我正在尝试从用户模型中设置“当前”,以便以后可以使用current.username或current.uid等,但是我得到“无法转换'AuthDataResult类型的值?”到预期的参数类型“用户””错误。在过去的项目中,我能够按照最底部显示的教程进行操作。我现在拥有的代码显示在其上方。我在堆栈溢出时检查了与此有关的其他问题,但找不到对我有帮助的东西。
(用户模型)
import Foundation
import UIKit
import FirebaseDatabase.FIRDataSnapshot
class User: Codable {
let uid: String
let username: String
init(uid: String, username: String){
self.uid = uid
self.username = username
}
init?(snapshot: DataSnapshot) {
guard let dict = snapshot.value as? [String : Any],
let username = dict[Constants.Dict.username] as? String
else { return nil }
self.uid = snapshot.key
self.username = username
}
private static var _current: User?
static var current: User {
guard let currentUser = _current else {
fatalError("Error: current user doesn't exist")
}
return currentUser
}
class func setCurrent(_ user: User, writeToUserDefaults: Bool = false) {
if writeToUserDefaults {
if let data = try? JSONEncoder().encode(user) {
UserDefaults.standard.set(data, forKey: Constants.UserDefaults.currentUser)
}
}
_current = user
}
}
(当前项目-LoginVC)
@objc func handleSignIn() {
guard let email = emailField.text else { return }
guard let pass = passwordField.text else { return
Auth.auth().signIn(withEmail: email, password: pass) { user, error in
if error == nil && user != nil {
--> --> ERROR HERE "user" !!
User.setCurrent(user, writeToUserDefaults: true)
self.dismiss(animated: false, completion: nil)
} else {
print("Error logging in: \(error!.localizedDescription)")
}
}
}
(更新的解决方案)
Auth.auth().signIn(withEmail: email, password: pass) { user, error in
if user?.user != nil {
let user = user!.user
UserService.show(forUID: user.uid) { (user) in
User.setCurrent(user!, writeToUserDefaults: true)
self.dismiss(animated: false, completion: nil)
}
...
答案 0 :(得分:0)
看来,您只是弄乱了两种不同的方法。在您过去的项目中,它是 FirebaseUI-iOS 的方法:
func authUI(_ authUI: FUIAuth, didSignInWith user: FIRUser?, error: Error?)
来自协议“ FUIAuthDelegate”。
顺便说一下,此方法现在在firebase sources中声明为“不赞成使用”:
- (void)authUI:(FUIAuth *)authUI
didSignInWithUser:(nullable FIRUser *)user
error:(nullable NSError *)error
__attribute__((deprecated("Instead use authUI:didSignInWithAuthDataResult:error:")));
如您所见,它具有名为“ user”的“ FIRUser *”类型的参数。
但是在当前项目中,您使用 firebase-ios-sdk 的“ Auth”类的方法“ signIn”。让我们在sources of Firebase中查找“ signIn”的签名:
- (void)signInWithEmail:(NSString *)email
password:(NSString *)password
completion:(nullable FIRAuthDataResultCallback)completion {
where "FIRAuthDataResultCallback" is:
/** @typedef FIRAuthDataResultCallback
@brief The type of block invoked when sign-in related events complete.
@param authResult Optionally; Result of sign-in request containing both the user and
the additional user info associated with the user.
@param error Optionally; the error which occurred - or nil if the request was successful.
*/
typedef void (^FIRAuthDataResultCallback)(FIRAuthDataResult *_Nullable authResult,
NSError *_Nullable error)
NS_SWIFT_NAME(AuthDataResultCallback);
因此它具有类型为“ FIRAuthDataResult *”的FIRST参数,名为“ authResult”(闭包参数的命名在现代Swift中没有保留!)。您将此参数命名为“用户”,并对其类型做出了错误的假设-用户。
什么是“ FIRAuthDataResult *”? Let's look to sources once more:
NS_SWIFT_NAME(AuthDataResult)
@interface FIRAuthDataResult : NSObject
/**...*/
- (instancetype)init NS_UNAVAILABLE;
/** @property user
@brief The signed in user.
*/
@property(nonatomic, readonly) FIRUser *user;
/** @property additionalUserInfo
@brief If available contains the additional IdP specific information about signed in user.
*/
@property(nonatomic, readonly, nullable) FIRAdditionalUserInfo *additionalUserInfo;
@end
所以这只是用户和其他信息的容器。
我认为,这就是您当前代码可编译的方式:
@objc func handleSignIn() {
guard let email = emailField.text else { return }
guard let pass = passwordField.text else { return
Auth.auth().signIn(withEmail: email, password: pass) { authDataResult, error in
guard let authDataResult = authDataResult,
let user = authDataResult.user,
error == nil else {
print("Error logging in: \(error?.localizedDescription ?? "no description")")
return
}
User.setCurrent(user, writeToUserDefaults: true)
self.dismiss(animated: false, completion: nil)
}
}
免责声明:我并没有真正尝试编译它!