I am following the docs for implementing the login by API,
class AWSUserPool {
var userAuthenticationError: Error?
AWSMobileClient.default().signIn(username: <param username>, password: <param password>) { (signInResult, error) in
if let error = error {
print("\(error.localizedDescription)")
self.userAuthenticationError = error
} else if let signInResult = signInResult {
switch (signInResult.signInState) {
case .signedIn:
print("User is signed in.")
case .smsMFA:
print("SMS message sent to \(signInResult.codeDetails!.destination!)")
default:
print("Sign In needs info which is not yet supported.")
}
}
}
}
I have instantiated the class and the login works when the correct credentials are supplied, I want to show the error message to an alert but I can print the error which is an optional (user not found....) but I am unable to assign it to a class variable.
import RxSwift
let observable: Observable<Error?> = Observable<Error?>.just(self.awsUserPool?.userAuthenticationError)
let disposeBag = DisposeBag()
observable.subscribe { event in
print(event)
}
.disposed(by: disposeBag)
I would first write a reactive wrapper around AWSMobileClient
like so:
extension Reactive where Base: AWSMobileClient {
func signIn(username: String, password: String) -> Observable<SignInResult> {
return Observable.create { observer in
self.base.signIn(username: username, password: password) { (signinResult, error) in
if let signinResult = signinResult {
observer.onNext(signinResult)
observer.onCompleted()
}
else {
observer.onError(error ?? RxError.unknown)
}
}
return Disposables.create()
}
}
}
Then to put the error in an Observable do something like this:
class AWSUserPool {
let userAuthenticationError: Observable<Error>
private let disposeBag = DisposeBag()
init(username: String, password: String) {
let result = AWSMobileClient.default().rx.signIn(username: username, password: password)
.materialize()
result
.compactMap { $0.element }
.subscribe(onNext: { signinResult in
switch signinResult.signInState {
case .signedIn:
print("User is signed in.")
case .smsMFA:
print("SMS message sent to \(signinResult.codeDetails!.destination!)")
default:
print("Sign In needs info which is not yet supported.")
}
})
.disposed(by: disposeBag)
userAuthenticationError = result.compactMap { $0.error }
}
}
I probably wouldn't bother with the AWSUserPool though... That's up to you.