Reputation: 1449
I have a function which has multiple queries set up in it. The function is long and involves alot, but works perfectly, save for one issue. There is a query which depends on some information with the query before and it occasionally crashes the app when the query before it is not totally done and caused the second one to unwrap a nil value. Here is the general setup:
func QueryandAppend(completion: (() -> Void)?){
let userLinkQuery = PFUser.query()//query1
userLinkQuery?.findObjectsInBackground(block: { (objects, error) in
if let users = objects{
for object in users{
if let user = object as? PFUser{
userLinkArray[user.objectId!] = user.username
}
}
}
})
let appendingQuery = PFQuery(classname: "Stuff")//query2
appendingQuery.findObjectsInBackground { (objects, error) in
for object in objects{
creatorArray.append(userLinkArray[object["User"] as! String]!)
}
...
completion!()
}
The completion handler is used to make sure the entire function (and all of the queries) have been completed before running something in the viewDidLoad()
. How do I ensure, though, that within the function query1 is done before query2 can run?
Upvotes: 1
Views: 118
Reputation: 41236
The prototypical way to do this with network and other asynchronous operations is to chain the operations, perhaps even break the individual network operations up each into a specific routine. The individual operations have completion callbacks, so just invoke your second routine from the completion of the first.
func QueryandAppend(completion: ((Bool) -> Void)?) {
PFUser.query().findObjectsInBackground { (objects, error) in
guard error == nil, let users = objects else {
completion?(false)
return
}
for object in users {
if let user = object as? PFUser,
let objectId = user.objectId {
userLinkArray[objectId] = user.username
}
}
PFQuery(classname: "Stuff").findObjectsInBackground { (objects, error) in
if error != nil {
// Handle error case
completion?(false)
return
}
for object in objects {
creatorArray.append(userLinkArray[object["User"] as! String]!)
}
completion?(true)
}
}
}
Alternatively, for a more modern stylistic approach, you could take a look at a good Promise framework, such as PromiseKit
Upvotes: 2