After 10 years of coding abstinence, I am actually trying a "come back" by developing a little app in swift using parse as backend. So far it ran quite smooth but since a few days, I have got stuck! I hope some one here can help me.
I wrote two methods in my TableViewController that loads the data from parse backend and the local datastore:
//get data from local Datastore
func fetchAllObjectsFromLocalDatastore() {
let query: PFQuery = PFQuery(className: "Task")
query.fromLocalDatastore()
query.whereKey("delete", equalTo: false)
query.findObjectsInBackground().continueWithBlock {
(task: BFTask!) -> AnyObject in
if let error = task.error {
print("Error: \(error)")
return task
}
//LOG
print("Retrieved \(task.result.count)")
let objects = task.result as? NSArray
self.taskObjects = objects?.mutableCopy() as! NSMutableArray
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
return task
}
}
//get data from parse and cach it locally
func fetchAllObjects() {
let query: PFQuery = PFQuery(className: "Task")
print(PFUser.currentUser()?.username) //log
query.whereKey("done", equalTo: false)
// Query for new results from the network
query.findObjectsInBackground().continueWithSuccessBlock({
(task: BFTask!) -> AnyObject! in
print("Retrieved \(task.result.count)")
return PFObject.unpinAllObjectsInBackground().continueWithSuccessBlock({
(ignored: BFTask!) -> AnyObject! in
// Cache new results in local data store
let objects = task.result as? NSArray
let temp : BFTask = PFObject.pinAllInBackground(objects as? [AnyObject], withName: "Task")
self.fetchAllObjectsFromLocalDatastore()
return temp
})
})
}
These two methods run fine, but now I want to improve the app to a bit a more like MVC architecture and add some new features. Therefore, I have tried to put them into a separate class. Here comes now my problem: when I last developed in C threading got quite populär so it was Also my first intention to do the asynchron tasks. Nur when I have researed the Topos I always ended up Reading of blocks and closures. In my understanding (no idea if it's right), I would have to write asynchronous-callbaks that I can do that – right?
I tried different things like shown here Swift: Asynchronous callback but nothing really worked. Here my last approach:
func fetchAllObjects(completion: (update:Bool?)->()) {
print("CallParse")
var update = false
let query: PFQuery = PFQuery(className: "Task")
print(PFUser.currentUser()?.username) //log
query.whereKey("done", equalTo: false)
// Query for new results from the network
query.findObjectsInBackground().continueWithSuccessBlock({
(task: BFTask!) -> AnyObject! in
print("Retrieved \(task.result.count)")
return PFObject.unpinAllObjectsInBackground().continueWithSuccessBlock({
(ignored: BFTask!) -> AnyObject! in
// Cache new results
let objects = task.result as? NSArray
let temp : BFTask = PFObject.pinAllInBackground(objects as? [AnyObject], withName: "Task")
//self.fetchAllObjectsFromLocalDatastore()
update = true
return temp
})
//TODO: correct update
})
}
and the call:
tasklist.fetchAllObjects({(update) -> () in
print("lalalalal")
if (update==true) {
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
}
})
.. but it never prints lalala or updates the tableView