使 UI 等待方法响应
Make UI Wait for Method Response
我是一名新 swift 开发人员。我正在使用 Swift 4.2 和 Xcode 10.2.
我需要 UI 等待方法完成,以便我可以使用结果显示余额。我试图为此使用 dispatchGroup
,但它似乎没有等待,因为下面 user?.userId
的值是 nil
。这是我的代码:
// Load the local user data. Must wait until this is done to continue.
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
let user = LocalStorageService.loadCurrentUser()
dispatchGroup.leave()
// Display the current balance.
// Get a reference to the Firestore database.
let db = Firestore.firestore()
// Make sure we have a userId and then update the balance with a listener that keeps it updated.
// Only run this part when the dispatchGroup has completed (in this case, the user is loaded).
dispatchGroup.notify(queue: .main) {
if let userId = user?.userId {
db.collection("subs").whereField("ID", isEqualTo: userId)
.addSnapshotListener { querySnapshot, error in
// Make sure we have a document
guard let document = querySnapshot?.documents.first else {
print("Error fetching document: \(error!)")
return
}
// We have a document and it has data. Use it.
self.balance = document.get("balance") as! Double
// Format the balance
let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currency
let balanceString = currencyFormatter.string(from: self.balance as NSNumber)
self.balanceLabel.setTitle(balanceString, for: .normal)
}
}
}
如何让 UI 等待 dispatchGroup.enter()
中调用的方法完成?
这是 LoadCurrentUser 中的内容....
static func loadCurrentUser() -> User? {
// Loads the current user in the UserDefaults if there is one
let defaults = UserDefaults.standard
let userId = defaults.value(forKey: Constants.LocalStorage.storedUserId) as? String
let phoneNumber = defaults.value(forKey: Constants.LocalStorage.storedPhoneNumber) as? String
let subscriberId = defaults.value(forKey: Constants.LocalStorage.storedDocumentId) as? String
guard userId != nil && phoneNumber != nil && subscriberId != nil else {
return nil
}
// Return the user
let u = User(userId:userId!, phoneNumber:phoneNumber!, subscriberId: subscriberId)
return u
}
目前,您通过在回调中设置 vars 来正确执行此操作,因此不需要 DispatchGroup
,但要正确使用它然后执行(请注意每行应按 1 到 4 之间的数字排列的正确位置)
let dispatchGroup = DispatchGroup() /// 1
let user = LocalStorageService.loadCurrentUser()
// Display the current balance.
// Get a reference to the Firestore database.
let db = Firestore.firestore()
var balance = ""
// Make sure we have a userId and then update the balance with a listener that keeps it updated.
// Only run this part when the dispatchGroup has completed (in this case, the user is loaded).
if let userId = user?.userId {
dispatchGroup.enter() /// 2
db.collection("subs").whereField("ID", isEqualTo: userId)
.addSnapshotListener { querySnapshot, error in
// Make sure we have a document
guard let document = querySnapshot?.documents.first else {
print("Error fetching document: \(error!)")
return
}
// We have a document and it has data. Use it.
self.balance = document.get("balance") as! Double
dispatchGroup.leave() /// 3
}
}
dispatchGroup.notify(queue: .main) { /// 4
//update here
// Format the balance
let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currency
let balanceString = currencyFormatter.string(from: self.balance as NSNumber)
self.balanceLabel.setTitle(balanceString, for: .normal)
}
我是一名新 swift 开发人员。我正在使用 Swift 4.2 和 Xcode 10.2.
我需要 UI 等待方法完成,以便我可以使用结果显示余额。我试图为此使用 dispatchGroup
,但它似乎没有等待,因为下面 user?.userId
的值是 nil
。这是我的代码:
// Load the local user data. Must wait until this is done to continue.
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
let user = LocalStorageService.loadCurrentUser()
dispatchGroup.leave()
// Display the current balance.
// Get a reference to the Firestore database.
let db = Firestore.firestore()
// Make sure we have a userId and then update the balance with a listener that keeps it updated.
// Only run this part when the dispatchGroup has completed (in this case, the user is loaded).
dispatchGroup.notify(queue: .main) {
if let userId = user?.userId {
db.collection("subs").whereField("ID", isEqualTo: userId)
.addSnapshotListener { querySnapshot, error in
// Make sure we have a document
guard let document = querySnapshot?.documents.first else {
print("Error fetching document: \(error!)")
return
}
// We have a document and it has data. Use it.
self.balance = document.get("balance") as! Double
// Format the balance
let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currency
let balanceString = currencyFormatter.string(from: self.balance as NSNumber)
self.balanceLabel.setTitle(balanceString, for: .normal)
}
}
}
如何让 UI 等待 dispatchGroup.enter()
中调用的方法完成?
这是 LoadCurrentUser 中的内容....
static func loadCurrentUser() -> User? {
// Loads the current user in the UserDefaults if there is one
let defaults = UserDefaults.standard
let userId = defaults.value(forKey: Constants.LocalStorage.storedUserId) as? String
let phoneNumber = defaults.value(forKey: Constants.LocalStorage.storedPhoneNumber) as? String
let subscriberId = defaults.value(forKey: Constants.LocalStorage.storedDocumentId) as? String
guard userId != nil && phoneNumber != nil && subscriberId != nil else {
return nil
}
// Return the user
let u = User(userId:userId!, phoneNumber:phoneNumber!, subscriberId: subscriberId)
return u
}
目前,您通过在回调中设置 vars 来正确执行此操作,因此不需要 DispatchGroup
,但要正确使用它然后执行(请注意每行应按 1 到 4 之间的数字排列的正确位置)
let dispatchGroup = DispatchGroup() /// 1
let user = LocalStorageService.loadCurrentUser()
// Display the current balance.
// Get a reference to the Firestore database.
let db = Firestore.firestore()
var balance = ""
// Make sure we have a userId and then update the balance with a listener that keeps it updated.
// Only run this part when the dispatchGroup has completed (in this case, the user is loaded).
if let userId = user?.userId {
dispatchGroup.enter() /// 2
db.collection("subs").whereField("ID", isEqualTo: userId)
.addSnapshotListener { querySnapshot, error in
// Make sure we have a document
guard let document = querySnapshot?.documents.first else {
print("Error fetching document: \(error!)")
return
}
// We have a document and it has data. Use it.
self.balance = document.get("balance") as! Double
dispatchGroup.leave() /// 3
}
}
dispatchGroup.notify(queue: .main) { /// 4
//update here
// Format the balance
let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currency
let balanceString = currencyFormatter.string(from: self.balance as NSNumber)
self.balanceLabel.setTitle(balanceString, for: .normal)
}