Trying to understand how I can schedule one task behind the other, looked at GCD and NSOperations, but both seem to be at an abstraction to far removed from the core code; part of which executes on its very own thread!
I tried this code which was the most obvious I could find...
let date = NSDate()
print("getting Links \(date)")
let operationQueue: NSOperationQueue = NSOperationQueue.mainQueue()
let completionBlockOperation: NSBlockOperation = NSBlockOperation.init(
block: {
self.reportFini()
}
)
let workerBlockOperation:NSBlockOperation = NSBlockOperation.init(
block: {
self.getLinks()
}
)
completionBlockOperation.addDependency(workerBlockOperation)
operationQueue.addOperation(workerBlockOperation)
operationQueue.addOperation(completionBlockOperation)
Now reportFini does next to nothing ...
func reportFini() {
let date = NSDate()
print("got Links \(date)")
}
But getLinks is more complex, using sessions... in nutshell it runs
let request = NSMutableURLRequest(URL: NSURL(string: "https://blah")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.addValue("application/json",forHTTPHeaderField: "Content-Type")
request.addValue("path", forHTTPHeaderField: lePath)
request.addValue("settings", forHTTPHeaderField: "requested_visibility\": \"public\"}")
var nodeA:NSMutableDictionary? = ["path":lePath]
let nodeB:NSMutableDictionary? = ["requested_visibility":"public"]
nodeA!.setValue(nodeB, forKey: "settings")
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(nodeA!, options: [])
request.HTTPBody = jsonData
} catch {
completion(string: nil, error: error)
}
var string2Return = ""
var stringPath = ""
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if let error = error {
completion(string: nil, error: error)
return
}
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Body: \(strData)\n\n")
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers);
self.jsonParser(jsonResult,field2file: "ignore")
if let stringPath = (self.parsedJson["url"] as? String) {
string2Return = stringPath
} else {
string2Return = (self.parsedJson["error_summary"] as? String)!
}
completion(string: string2Return, error: error)
} catch {
completion(string: nil, error: error)
}
})
task.resume()
}
Now, getLinks and reportFini both execute @ the same time; basically get links goes off on its own thread! and immediately returns... BUT I need/want to be notified when it is finished, cause I got something else to do.
It get more complicated, since I need to run 10 sessions (fetching 10 links) concurrently, so in parallel; and want to be notified when they're all finished.
--- UPDATE ---
Tried GCD enclosing my sessions code in
let workerQueue = dispatch_queue_create("getLinks", DISPATCH_QUEUE_CONCURRENT)
let getLinksGroup = dispatch_group_create()
dispatch_group_notify(getLinksGroup, dispatch_get_main_queue()) {
print("All Links Downloaded")
}
dispatch_group_enter(getLinksGroup)
dispatch_group_async(getLinksGroup, workerQueue) {
exiting with ...
dispatch_group_leave(getLinksGroup)
Unfortunately it doesn't work; as I had already seen the sessions launch their own thread and I get notified almost immediately that the code has completed, clearly before it actually finishes the URL data download tasks.
Going to try with KVO ...