如何通过Firebase返回我在数据服务类中创建的对象?

时间:2017-05-29 23:38:01

标签: swift firebase model-view-controller firebase-realtime-database completionhandler

我正在尝试遵循MVC实践并将所有网络代码保存在我在我的应用程序中使用的数据服务类中。在一个屏幕上,我有需要显示的用户名和用户名。更新时,我正在调用此函数:

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

但是我在尝试返回用户时遇到错误!它说:

  

void函数中出现意外的非void返回值。

但这个功能显然不是无效的。那我该怎么办?

1 个答案:

答案 0 :(得分:3)

您的grabUserData 功能返回值与Firebase 闭包返回值相混淆 - 前者为User但后者为{{ 1}};)

你实际上是从这个闭包中返回的 - 我现在正在使用显式返回类型:

Void

作为{ (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 } } Firebase函数的最后一个参数传递。这是非常常见的错误;)

完成处理程序。这里的标准模式是通过完成处理程序 返回所需的observeSingleEvent。此解决方案很好地模拟了Firebase数据库调用等网络请求的异步特性。例如:

User

最后,在您的数据服务客户端代码中,将其命名为:

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