结合 .sink 打印不打印

Combine .sink print doesn't print

我是 Combine and Sink 的新手,但是我放入其中的打印件似乎没有记录,但是操作的结果在 AWS Amplify 中创建用户时完成。

@objc private func createAccountButtonAction(sender: UIButton) {
    print("Create Account Button Action")
    signUp(password: self.password, email: self.email)
  }
  
  func signUp(password: String, email: String) -> AnyCancellable {
      let userAttributes = [AuthUserAttribute(.email, value: email)]
      let options = AuthSignUpRequest.Options(userAttributes: userAttributes)
      let sink = Amplify.Auth.signUp(username: email, password: password, options: options)
        .resultPublisher.sink(receiveCompletion: { (authError) in
          print("Failed with error: \(authError)")
        }, receiveValue: { (signUpResult) in
          print("Signed Up")
        })
    return sink
  }

当您使用 .sink 运算符时,它 return 是 AnyCancellable 类型的标记。当该令牌被销毁时,它会调用 cancel 自身,这会破坏它所代表的订阅。您没有保存令牌,因此 Swift 在订阅有机会交付任何输出之前立即销毁它。

通常的解决方案是找到一个地方来存储令牌,比如在控制器对象的 属性 中:

class AccountCreationController: UIViewController {
    private var token: AnyCancellable? = nil
// NEW          ^^^^^ storage for the AnyCancellable

    @objc private func createAccountButtonAction(sender: UIButton) {
        print("Create Account Button Action")
        signUp(password: self.password, email: self.email)
    }

    func signUp(password: String, email: String) {
        let userAttributes = [AuthUserAttribute(.email, value: email)]
        let options = AuthSignUpRequest.Options(userAttributes: userAttributes)
        token = Amplify.Auth.signUp(username: email, password: password, options: options)
// NEW  ^^^^^ store the AnyCancellable to keep the subscription alive
            .resultPublisher.sink(
                receiveCompletion: { (authError) in
                    print("Failed with error: \(authError)")
                },
                receiveValue: { (signUpResult) in
                    print("Signed Up")
                })
    }
}

如果您确定永远不想取消订阅(例如,用户无法按“取消”按钮退出),另一种方法是直接创建 Subscribers.Sink,而不是使用sink 运算符,并使用 subscribe 方法将 Sink 订阅到 Publishersubscribe 方法 而不是 return 和 AnyCancellableSink 对象本身是一个 Cancellable,但不是 AnyCancellable,您不必将其存储在任何地方以保持订阅有效。

class AccountCreationController: UIViewController {
    @objc private func createAccountButtonAction(sender: UIButton) {
        print("Create Account Button Action")
        signUp(password: self.password, email: self.email)
    }

    func signUp(password: String, email: String) {
        let userAttributes = [AuthUserAttribute(.email, value: email)]
        let options = AuthSignUpRequest.Options(userAttributes: userAttributes)
        Amplify.Auth.signUp(username: email, password: password, options: options)
// NEW  ^ There is no AnyCancellable to store.
            .resultPublisher
            .subscribe(
// NEW      ^^^^^^^^^^ use the subscribe method instead of sink.
                Subscribers.Sink(
// NEW          ^^^^^^^^^^^^^^^^ Create a Sink object.
                    receiveCompletion: { (authError) in
                        print("Failed with error: \(authError)")
                    },
                    receiveValue: { (signUpResult) in
                        print("Signed Up")
                    }
                )
            )
    }
}