How can I return an object that I create in my data service class through Firebase?

谁说胖子不能爱 提交于 2019-11-26 14:55:10

问题


I am trying to adhere to MVC practices and keep all the network code inside the data service class that I am using in my app. On one screen I have the user's name and username that needs to be displayed. When updating this, I am calling this function:

func grabUserData() -> User {
    REF_USERS.child(getCurrentUID()).observeSingleEvent(of: .value) { 
        (snapshot) in
        if let userDict = snapshot.value as? Dictionary<String, String> {
            let user = User(
                first:    userDict["firstName"]!, 
                last:     userDict["lastName"]!, 
                username: userDict["username"]!
            )
            return user
        } 
    }
}

But I am getting an error trying to return the user! It says:

Unexpected non-void return value in void function.

But the function clearly isn't void. So what do I do?


回答1:


You are confusing your grabUserData function return value with the Firebase closure return value — the former is User but the latter is Void ;)

You are actually returning from this closure — I'm now using a explicit return type to be clear:

{ 
    (snapshot) -> Void in
    if let userDict = snapshot.value as? Dictionary<String,String> {
        let user = User(
            first:    userDict["firstName"]!, 
            last:     userDict["lastName"]!, 
            username: userDict["username"]!
        )
        return user
    }
}

which is passed as the last argument to the observeSingleEvent Firebase function. This is a very common mistake ;)

Completion handler. A standard pattern here is to return the desired User via a completion handler instead. This solution nicely models the asynchronous nature of network requests such as Firebase database calls. For instance:

func grabUserData(completion: @escaping (User?) -> Void) {
    REF_USERS.child(getCurrentUID()).observeSingleEvent(of: .value) { 
        (snapshot) in
        if let userDict = snapshot.value as? Dictionary<String, String> {
            let user = User(
                first:    userDict["firstName"]!, 
                last:     userDict["lastName"]!, 
                username: userDict["username"]!
            )
            completion(user) // Returns user!
        } else {
            completion(nil) // User not found!
        }
    }
}

Finally, in your data service client code, call it like this:

grabUserData() { 
    (user) in
    if let user = user {
        print("Grabbed user: \(user)")
    } else {
        print("User not found!")
    }        
}


来源:https://stackoverflow.com/questions/44251463/how-can-i-return-an-object-that-i-create-in-my-data-service-class-through-fireba

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!