结合 .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
订阅到 Publisher
。 subscribe
方法 而不是 return 和 AnyCancellable
。 Sink
对象本身是一个 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")
}
)
)
}
}
我是 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
订阅到 Publisher
。 subscribe
方法 而不是 return 和 AnyCancellable
。 Sink
对象本身是一个 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")
}
)
)
}
}