如何通过 Firebase return 我在数据服务 class 中创建的对象?

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

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

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

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

Unexpected non-void return value in void function.

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

您将 grabUserData function return 值与 Firebase closure return 混淆了值 — 前者是 User 但后者是 Void ;)

你实际上是 return从这个关闭 — 我现在使用 explicit return 类型来明确:

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

作为最后一个参数传递给 observeSingleEvent Firebase 函数。这是一个非常的常见错误 ;)

完成处理程序。这里的标准模式是 return 通过 完成处理程序 所需的 User。该解决方案很好地模拟了网络请求(例如 Firebase 数据库调用)的 异步 性质。例如:

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

最后,在你的数据服务客户端代码中,这样调用:

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