我是Swift编码的新手,我一直在寻找解决该问题的方法,但至今仍找不到解决我问题的方法。
我正在使用一个函数从Firebase返回一些数据。经过许多错误和大量研究之后,我设法在不引发错误的情况下使函数“正常运行”,但是返回的数据为空。本质上,我在调用函数时试图返回多个值并将它们保存在数组中。
数据从Firebase正常返回,当我在设置变量后立即打印出变量时,它将正确打印,但是当我在返回函数之前执行相同操作时,它将返回空白。如果我尝试在设置数据后立即返回该函数,则会收到错误“ void函数中的非预期非空返回值”。
这是完整的代码:
func loadClientData(client_id: String) -> (address_1: String, address_2: String, city: String, company_name: String, contact_name: String, county: String, email: String, phone: String, postcode: String, country: String) {
let db = Firestore.firestore()
let userID : String = (Auth.auth().currentUser!.uid)
print("\(userID)/clients/existing/\(client_id)")
let docRef = db.collection("\(userID)/clients/existing/").document(client_id)
var address_1 = ""
var address_2 = ""
var city = ""
var company_name = ""
var contact_name = ""
var county = ""
var email = ""
var phone = ""
var postcode = ""
var country = ""
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let data = document.data()
address_1 = data?["address_1"] as? String ?? ""
address_2 = data?["address_2"] as? String ?? ""
city = data?["city"] as? String ?? ""
company_name = data?["company_name"] as? String ?? ""
contact_name = data?["contact_name"] as? String ?? ""
county = data?["county"] as? String ?? ""
email = data?["email"] as? String ?? ""
phone = data?["phone"] as? String ?? ""
postcode = data?["postcode"] as? String ?? ""
country = data?["country"] as? String ?? ""
print("Company name is \(company_name)") // <---- THIS prints out the company name
} else {
print("client does not exist")
return
}
}
print("Company name is \(company_name)") // <---- THIS prints the company name as blank
return (address_1: address_1, address_2: address_2, city: city, company_name: company_name, contact_name: contact_name, county: county, email: email, phone: phone, postcode: postcode, country: country)
}
被这样称呼:
let companyInfo = loadClientData(client_id: self.items[indexPath.item].company)
print(companyInfo)
并打印出以下内容:
(地址_1:“”,地址_2:“”,城市:“”,公司名称:“”, contact_name:“”,县:“”,电子邮件:“”,电话:“”,邮政编码:“”, 国家:“”)
谢谢您的输入。
答案 0 :(得分:5)
此网站上有many个问题,它们与您的问题基本相同,因此您应该查看一下。为避免重复,我将简单说明一下,但敦促您阅读类似的问题。
简而言之,发生的事情是loadClientData
异步获取数据,这意味着它发生在后台,而其他内容发生在前台。前台内容包括调用loadClientData
并将其打印出来的代码。 前景材料不会等待背景材料完成。
您什么也没得到,因为到print(companyInfo)
时,背景材料还没有完成处理。
真实世界示例:
你妈妈要你去买柠檬做晚餐。
她开始做饭,但没有柠檬!
为什么?因为您还没有从超市回来,而您的妈妈没有等。
如果要让前台等待,则有很多选择,可以通过查看other similar questions来考虑。
答案 1 :(得分:1)
您需要重构函数以不返回任何内容,并使用完成处理程序。完成处理程序是调用者传递给您的函数的代码块。结果可用后,您的函数将调用完成处理程序。这是Swift中常见的编码模式,您的firebase getDocument()
调用被编写为使用完成处理程序。
搜索Swift completion handler design pattern
以了解更多信息。
**注意:
使用完成处理程序只是执行此操作的一种方法。您也可以使用委托设计模式,但是完成处理程序是处理异步事件的更现代的方式,也是我建议处理问题的方式。