Reputation: 693
I am trying to retrieve information from a MySQL database and process the data. The problem is that the retrieval is done via NSURLSessions asynchronously and updates/console output is printed before the data returns.
I've solved the above problem partially by using dispatch_group_enter/dispatach_group_leave with dispatch_group_notify. Using this setup solves console output, but I cannot pass the value (my understanding is that I cannot make a return statement inside the dispatch_group_notify closure)
MySQLCommunications.swift:
Class DBcom {
var dbGetQueue = dispatch_group_create()
func getMaxValue () -> Int {
var neverGetsFilled = getDBdata()
//process the self.DBTaskResults to extract Int (not neverGetsFilled)
dispatch_group_notify(self.dbGetQueue, dispatch_get_main_queue(), {
//1. Can print result here ok
//2. Cannot return result inside closure.
}
return result
}
func getDBData () ->NSData {
dispatch_group_enter(self.dbGetQueue)
let getDBTask = NSURLSession.sharedSession().dataTaskWithRequest(urlRequest,
completionHandler: {(reqData,reqResponse, reqError) -> Void in
self.DBTaskResults = reqData
dispatch_group_leave(self.dbGetQueue)
})
getDBTask.resume()
return self.DBTaskResults
}
}
TempTestController.swift:
class TempTestViewController: UIViewController {
@IBAction func TestButtonPressed(sender: AnyObject) {
let testDB = DBcom()
var maxfloor = testDB.getMaxValue()
println(maxfloor) //this is empty
}
}
I am trying to keep everything related to retrieving data from the database inside "MySQLCommunications.swift" with functions returning relevant data. However:
var myEmptyDBReturn = testDB.getMaxValue()
is empty. I can use a global variable declared above the @UIApplicationMain line in AppDelegate.swift and do:
globalVar = getMaxValue.processed_results //done inside dispatch notify in DBcom.getMaxValue
to get the value outside of MySQLCommunications.swift, but it doesn't solve the timing issue. Essentially, I would like to know how to assign a value derived from an asynchronous task to some variable such that when I use that variable it has the retrieved data.
Upvotes: 3
Views: 1610
Reputation: 7233
The method dispatch_group_notify() will return immediately without waiting for all the blocks in the group. The block passed to dispatch_group_notify() will get executed when all the blocks in that particular group has finished.
Either you may need to put a callback in getMaxValue() method which will get called when the notify block is executed.
OR
If you are not worried about calling thread be blocked then you could use dispatch_group_wait() like below example:
func getMaxValue () -> Int {
var neverGetsFilled = getDBdata()
//process the self.DBTaskResults to extract Int (not neverGetsFilled)
dispatch_group_wait(self.dbGetQueue, DISPATCH_TIME_FOREVER)
//You will reach here only when all the group blocks are executed.
return result
}
Upvotes: 2