我是新的iOS环境,我陷入了这样的境地:
在Google搜索之后,我找到了一种在防火墙中进行查询的方法:
db.collection("cities").whereField("capital", isEqualTo: true)
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}
这很好,但是现在我想将它“包装”成一个函数,比如
func getPlayerFromFirebase(email: String) -> Player {
//Do the query in the collection Players where field "email" == email
//Save the query result in a variable (which is a dictionary)
//decode the dictionary into another variable of type Player
//return the Player variable
}
我不知道如何做到这一点,因为如果我将返回放在打印查询结果的行下面,就会得到以下错误```Unexpected non-void return value in void function
我还看到了另一个示例,它将查询结果存储在自己的类属性中,但我不希望这样,我希望在另一个快速文件中实现该函数。
谢谢。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在Swift中,您提到的错误Unexpected non-void return value in void function
表明您尝试从一个预期返回Void
(即无返回值)的函数中返回了一个实际的值。这是因为Firebase的异步查询不会立即返回结果,而是在闭包内完成时才提供结果。因此,您需要调整方法以适应异步操作,通常通过使用completion handler或者将功能设计为异步并使用Swift的async/await
(如果您的环境支持Swift 5.5及以上版本)。
您可以修改您的函数,使其接受一个completion handler作为参数,该handler会在查询完成后被调用,并传递查询结果或错误。
func getPlayerFromFirebase(email: String, completion: @escaping (Player?, Error?) -> Void) {
db.collection("players").whereField("email", isEqualTo: email)
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
completion(nil, err) // 在这里处理错误
} else if let documents = querySnapshot?.documents.first {
do {
let playerData = try documents.data(as: Player.self) // 假设Player遵循Codable
completion(playerData, nil) // 返回Player对象
} catch {
print("Error decoding document: \(error)")
completion(nil, error) // 解码失败时处理错误
}
} else {
print("No document found for email: \(email)")
completion(nil, nil) // 没有找到文档时的处理
}
}
}
在这个例子中,getPlayerFromFirebase
现在接受一个带有两个泛型参数(Player?
, Error?
)的closure作为其完成处理程序。当查询成功且找到匹配项时,它会尝试解码第一个查询到的文档为Player
类型,并通过completion handler返回。如果发生错误或找不到匹配项,也会通过completion handler通知调用者。
如果您使用的是Swift 5.5或更高版本,可以利用Swift的并发特性来简化异步代码:
import Foundation
func getPlayerFromFirebase(email: String) async throws -> Player {
let querySnapshot = try await db.collection("players").whereField("email", isEqualTo: email).getDocuments()
guard let document = querySnapshot.documents.first else {
throw NSError(domain: "", code: 1, userInfo: [NSLocalizedDescriptionKey: "Player not found"])
}
return try document.data(as: Player.self)
}
请注意,为了使用async/await
,您的调用环境也需要是异步的,比如在标记为async
的函数内部调用此函数。此外,您的数据库查询方法(如Firebase的.getDocuments()
)需要支持异步/等待,这可能需要第三方库的支持或Firebase SDK的更新来直接兼容Swift concurrency。
请根据您的项目环境和Swift版本选择合适的方法实现。