Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.1k views
in Technique[技术] by (71.8m points)

swift - Combine .sink print doesn't print

I am new to Combine and Sink, however the prints that I put in them do not seem to log however the result of the action completes as the user is created within 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
  }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

When you use the .sink operator, it returns a token of type AnyCancellable. When that token is destroyed, it calls cancel on itself, which tears down the subscription it represents. You're not saving the token, so Swift destroys it immediately, before the subscription has had a chance to deliver any outputs.

The usual solution is to find a place to store the token, like in a property of a controller object:

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")
                })
    }
}

An alternative, if you are sure you never want to cancel the subscription (e.g. the user cannot press a “Cancel”?button to back out), is to create a Subscribers.Sink directly, instead of using the sink operator, and use the subscribe method to subscribe the Sink to the Publisher. The subscribe method does not return an AnyCancellable. The Sink object is itself a Cancellable, but not an AnyCancellable, and you don't have to store it anywhere to keep the subscription alive.

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")
                    }
                )
            )
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...