Using dispatch_group to execute code synchronously, this sample singletone class might help to implement it easily.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
@interface DispatchGroupManager : NSObject | |
{ | |
} | |
/** | |
* Singleton constructor | |
* @return Singleton instance of DispatchGroup. | |
*/ | |
+(instancetype)sharedManager; | |
/* | |
* Initiate a group of of tasks. Once all tasks are finished, a completion block will execute | |
*/ | |
-(void)initGroupTasksWithName:(NSString*)groupName; | |
/** | |
* Supply a completion block once all the async tasks are finished | |
* @param the completion block to execute once all the group tasks are done. | |
*/ | |
-(void)addGroupTasksCompletion:(void(^)())completion forGroup:(NSString*)groupName; | |
/** | |
* Should be called when a async task in about to be added in taskGroup | |
*/ | |
-(void)addFollowingTaskToGroup:(NSString*)groupName; | |
/** | |
* Should be called when a async task in done in taskGroup | |
*/ | |
-(void)doneThisTaskInGroup:(NSString*)groupName; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "DispatchGroupManager.h" | |
@interface DispatchGroupManager() | |
@property (strong, readwrite, nonatomic) NSMutableDictionary *asyncTasksGroupDic; | |
@end | |
@implementation DispatchGroupManager | |
#pragma mark - Shared Manager Initialization | |
+ (instancetype)sharedManager | |
{ | |
static dispatch_once_t pred; | |
static DispatchGroupManager *DispatchGroupManager = nil; | |
dispatch_once(&pred, ^{ | |
sharedInstance = [[DispatchGroupManager alloc] init]; | |
}); | |
return sharedInstance; | |
} | |
#pragma mark - Group task methods | |
-(void)initGroupTasksWithName:(NSString*)groupName | |
{ | |
if(!groupName) | |
return; | |
if(!self.asyncTasksGroupDic) | |
self.asyncTasksGroupDic = [[NSMutableDictionary alloc] init]; | |
dispatch_group_t oldDispatchGroup = [self.asyncTasksGroupDic objectForKey:groupName]; | |
if(oldDispatchGroup){ | |
[self.asyncTasksGroupDic removeObjectForKey:groupName]; | |
} | |
dispatch_group_t dispatchGroup = dispatch_group_create(); | |
[self.asyncTasksGroupDic setObject:dispatchGroup forKey:groupName]; | |
} | |
-(void)addGroupTasksCompletion:(void(^)())completion forGroup:(NSString*)groupName | |
{ | |
if(!groupName) | |
return; | |
dispatch_group_t dispatchGroup = [self.asyncTasksGroupDic objectForKey:groupName]; | |
if(dispatchGroup){ | |
dispatch_group_notify(dispatchGroup,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ { | |
if(completion){ | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
completion(); | |
}); | |
} | |
}); | |
} | |
} | |
-(void)addFollowingTaskToGroup:(NSString*)groupName | |
{ | |
if(!groupName) | |
return; | |
dispatch_group_t dispatchGroup = [self.asyncTasksGroupDic objectForKey:groupName]; | |
if(dispatchGroup){ | |
dispatch_group_enter(dispatchGroup); | |
} | |
} | |
-(void)doneThisTaskInGroup:(NSString*)groupName | |
{ | |
if(!groupName) | |
return; | |
dispatch_group_t dispatchGroup = [self.asyncTasksGroupDic objectForKey:groupName]; | |
if(dispatchGroup){ | |
dispatch_group_leave(dispatchGroup); | |
} | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "DispatchGroupManager.h" | |
#define TRAVEL_OVERVIEW_GROUP_TASK @"localTravelOverviewGroupTask" | |
@implementation MySampleViewController | |
//.... Other codes ..... | |
//This is a sample method where you need 2 API calls to finish to finally show the result in the tableView | |
-(void)loadAllTicketsAndHotels | |
{ | |
__weak typeof(self) weakSelf = self; | |
//Initiate the group task | |
[[DispatchGroupManager sharedManager] initGroupTasksWithName:TRAVEL_OVERVIEW_GROUP_TASK]; | |
[self.view addSubview:_loadingView]; // show a loading view while we load everything | |
//----------- Task 1. get all tickets------------------- | |
[[DispatchGroupManager sharedManager] addFollowingTaskToGroup:TRAVEL_OVERVIEW_GROUP_TASK]; | |
#warning We'r pulling only first page, but need to fetch all by adding the limit param, i.e "limit=1000" | |
[TicketsService getAllTicketsForIssueId:self.localTravel.issueIdentifier pageNo:1 completion:^(NSArray *tickets, Pagination *paginationInfo, NSError *error) { | |
if (!error && weakSelf) { | |
__strong typeof(weakSelf) strongSelf = weakSelf; | |
[strongSelf.allTicketsArray addObjectsFromArray:tickets]; | |
} | |
NSLog(@"Done loading all tickets"); | |
[[DispatchGroupManager sharedManager] doneThisTaskInGroup:TRAVEL_OVERVIEW_GROUP_TASK]; | |
}]; | |
//-------------- Task 2. get all hotels ---------------- | |
[[DispatchGroupManager sharedManager] addFollowingTaskToGroup:TRAVEL_OVERVIEW_GROUP_TASK]; | |
#warning We'r pulling only first page, but need to fetch all by adding the limit param, i.e "limit=1000" | |
[HotelService getAllHotelsForIssueId:self.localTravel.issueIdentifier pageNo:1 completion:^(NSArray *hotels, Pagination *paginationInfo, NSError *error) { | |
if (!error && weakSelf) { | |
__strong typeof(weakSelf) strongSelf = weakSelf; | |
[strongSelf.allHotelsArray addObjectsFromArray:hotels]; | |
} | |
NSLog(@"Done loading all Hotels"); | |
[[DispatchGroupManager sharedManager] doneThisTaskInGroup:TRAVEL_OVERVIEW_GROUP_TASK]; | |
}]; | |
//---- This method will add the action we want to take once the 2 API calls are finished | |
[[DispatchGroupManager sharedManager] addGroupTasksCompletion:^{ | |
if (weakSelf) { | |
__strong typeof(weakSelf) strongSelf = weakSelf; | |
[strongSelf.loadingView removeFromSuperview]; //remove the loading view | |
[strongSelf generateTravelOverview]; //combine the API call results and show it in the view | |
} | |
} forGroup:TRAVEL_OVERVIEW_GROUP_TASK]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment