Не удается преобразовать значение типа 'AuthDataResult?'к ожидаемому типу аргумента «Пользователь» - PullRequest
0 голосов
/ 03 июня 2019

Я пытаюсь установить «текущий» из моей пользовательской модели, чтобы позже я мог использовать 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)
            }
            ...

1 Ответ

0 голосов
/ 03 июня 2019

Кажется, вы только что испортили два разных метода.В вашем прошлом проекте это был метод FirebaseUI-iOS :

func authUI(_ authUI: FUIAuth, didSignInWith user: FIRUser?, error: Error?)

из протокола "FUIAuthDelegate".

Кстати, этот метод объявлен как "устаревший"теперь в источниках firebase :

- (void)authUI:(FUIAuth *)authUI
    didSignInWithUser:(nullable FIRUser *)user
                error:(nullable NSError *)error
__attribute__((deprecated("Instead use authUI:didSignInWithAuthDataResult:error:")));

Как видите, он имеет аргумент типа "FIRUser *" с именем "user".

Но в текущем проекте выиспользуйте метод "signIn" класса "Auth" firebase-ios-sdk .Давайте посмотрим на сигнатуру "signIn" в источниках Firebase :

    - (void)signInWithEmail:(NSString *)email
                   password:(NSString *)password
                 completion:(nullable FIRAuthDataResultCallback)completion {

, где "FIRAuthDataResultCallback" равно :

/** @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 *» с именем «authResult» (именование аргументов закрытия не сохраняется в современном Swift!).Вы назвали этот аргумент "пользователь" и сделали неверное предположение о его типе - Пользователь.

Что такое "FIRAuthDataResult *"? Давайте еще раз посмотрим на источники :

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

Отказ от ответственности: Я действительно не пытался его скомпилировать!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...