Yes of course if getAPI
calls parseAPI
, the code of parseAPI
will execute on the same thread than the one getAPI
was executed, so in your example on a background queue.
To return the callback to the main thread at the end, use the same techniques as Apple uses with their completionBlock
you can see on multiple Apple APIs : simply pass a block (e.g. dispatch_block_t
or void(^)(NSError*)
or whatever fits your needs) as a parameter to your getAPI:
method which will pass it to parseAPI:
which will in turn pass it to savetoDB:
and at the end savetoDB:
can simply use dipatch_async(dispatch_get_main_queue, completionBlock);
to call this block of code (passed from method to method) on the main thread.
Note: for your getAPI you can use Apple's sendAsynchronousRequest:queue:completionHandler:
method, that will automatically execute the request in the background then call the completion block on the indicated NSOperationQueue
(NSOperationQueue
uses GCD's dispatch_queue internally). See documentation on NSOperationQueue
, GCD and the Concurrency Programming Guide and all the great detailed guide in Apple doc for more info.
-(void)getAPI:( void(^)(NSError*) )completionBlock
{
NSURLRequest* req = ...
NSOperationQueue* queue = [[NSOperationQueue alloc] init]; // the completionHandler will execute on this background queue once the network request is done
[NSURLConnection sendAsynchronousRequest:req queue:queue completionHandler:^(NSURLResponse* resp, NSData* data, NSError* error)
{
if (error) {
// Error occurred, call completionBlock with error on main thread
dispatch_async(dispatch_get_main_queue(), ^{ completionBlock(error); });
} else {
[... parseAPI:data completion:completionBlock];
}
}];
}
-(void)parseAPI:(NSData*)dataToParse completion:( void(^)(NSError*) )completionBlock
{
... parse datatToParse ...
if (parsingError) {
dispatch_async(dispatch_get_main_queue(), ^{ completionBlock(error); });
} else {
[... savetoDB:dataToSave completion:completionBlock];
}
}
-(void)savetoDB:(id)dataToSave completion:( void(^)(NSError*) )completionBlock
{
... save to your DB ...
// Then call the completionBlock on main queue / main thread
dispatch_async(dispatch_get_main_queue(), ^{ completionBlock(dbError); }); // dbError may be nil if no error occurred of course, that will tell you everything worked fine
}
-(void)test
{
[... getAPI:^(NSError* err)
{
// this code will be called on the main queue (main thread)
// err will be nil if everythg went OK and vontain the error otherwise
}];
}