下面有三个函数。第一个是我需要重构的函数。基本上,我希望的是使用Promise Kit可以实现类似的功能,但在本例中使用Swifts组合框架。
第二函数CCD_ 1返回一个CCD_。该AuthCredential
需要传递给最后的函数,该函数返回与主函数(第一个函数(类似的返回类型Future<UserProfileCompact, Error>
。
我的问题是,是否有一种方法可以快速实现这一点,类似于Promise Kit执行此操作:return loginWithFacebook().then {loginWithFirebase(:_)}
// Call site is a View Model
// Main Function that needs to be refactored
func loginwithFacebook() -> Future<UserProfileCompact, Error> {
//This returs a Future Firebase Credential
loginWithFacebook()
//The above credential needs to be passed to this method and this returns a type Future<UserProfileCompact, Error>
loginWithFirebase(<#T##credentials: AuthCredential##AuthCredential#>)
}
private func loginWithFacebook() -> Future<AuthCredential,Error> {
return Future { [weak self] promise in
self?.loginManager.logIn(permissions: ["public_profile","email"], from: UIViewController()) { (loginResult, error) in
if let error = error {
promise(.failure(error))
} else if loginResult?.isCancelled ?? false {
//fatalError()
}
else if let authToken = loginResult?.token?.tokenString {
let credentials = FacebookAuthProvider.credential(withAccessToken: authToken)
promise(.success(credentials))
}
else{
fatalError()
}
}
}
}
private func loginWithFirebase(_ credentials: AuthCredential) -> Future<UserProfileCompact, Error> {
return Future { promise in
Auth.auth().signIn(with: credentials) { (result, error) in
if let error = error {
//Crashlytics.crashlytics().record(error: error)
promise(.failure(error))
}
else if let user = result?.user {
//Crashlytics.crashlytics().setUserID(user.uid)
let profile = UserProfileCompactMapper.map(firebaseUser: user)
promise(.success(profile))
}
else {
fatalError()
}
}
}
}
您可以使用.flatMap
运算符,它从上游获取值并生成发布者。这看起来像下面的样子。
注意,最好在函数边界返回一个类型已擦除的AnyPublisher
,而不是在函数中使用的特定发布者
func loginwithFacebook() -> AnyPublisher<UserProfileCompact, Error> {
loginWithFacebook().flatMap { authCredential in
loginWithFirebase(authCredential)
}
.eraseToAnyPublisher()
}