I understand that these completion blocks will each be called twice, once for local data, second time with API data. And you want the notify block called when the two local calls finish, and again when the two API calls finish.
To do this, you need two dispatch groups, and you could do something like:
dispatch_group_t requestGroupLocal = dispatch_group_create();
dispatch_group_t requestGroupAPI = dispatch_group_create();
dispatch_group_enter(requestGroupLocal);
dispatch_group_enter(requestGroupAPI);
__block NSInteger count1 = 0;
[self method1WithCompletion:^(NSArray *items) {
if (count1 == 0) {
dispatch_group_leave(requestGroupLocal);
count1++;
} else {
dispatch_group_leave(requestGroupAPI);
}
}];
dispatch_group_enter(requestGroupLocal);
dispatch_group_enter(requestGroupAPI);
__block NSInteger count2 = 0;
[self method2WithCompletion:^(NSArray *items) {
if (count2 == 0) {
dispatch_group_leave(requestGroupLocal);
count2++;
} else {
dispatch_group_leave(requestGroupAPI);
}
}];
dispatch_block_t completion = ^{
// do whatever you want when each group finishes
};
dispatch_group_notify(requestGroupLocal, dispatch_get_main_queue(), completion);
dispatch_group_notify(requestGroupAPI, dispatch_get_main_queue(), completion);
Or, better, rather than relying on those cryptic counters, you could add a parameter to the block to indicate whether it's a local call or not:
dispatch_group_t requestGroupLocal = dispatch_group_create();
dispatch_group_t requestGroupAPI = dispatch_group_create();
dispatch_group_enter(requestGroupLocal);
dispatch_group_enter(requestGroupAPI);
[self method1WithCompletion:^(NSArray *items, BOOL isLocal) {
if (isLocal) {
dispatch_group_leave(requestGroupLocal);
} else {
dispatch_group_leave(requestGroupAPI);
}
}];
dispatch_group_enter(requestGroupLocal);
dispatch_group_enter(requestGroupAPI);
[self method2WithCompletion:^(NSArray *items, BOOL isLocal) {
if (isLocal) {
dispatch_group_leave(requestGroupLocal);
} else {
dispatch_group_leave(requestGroupAPI);
}
}];
dispatch_block_t completion = ^{
// do whatever you want when each group finishes
};
dispatch_group_notify(requestGroupLocal, dispatch_get_main_queue(), completion);
dispatch_group_notify(requestGroupAPI, dispatch_get_main_queue(), completion);
Frankly, this pattern of calling the completion handler twice is quite atypical and is somewhat suspect. I can imagine the intent behind the current design, but I would be inclined to retire it. Instead, I'd rather see separate methods for the local and API renditions which call their completion handlers only once:
dispatch_group_t requestGroupLocal = dispatch_group_create();
dispatch_group_enter(requestGroupLocal);
[self methodLocal1WithCompletion:^(NSArray *items) {
dispatch_group_leave(requestGroupLocal);
}];
dispatch_group_enter(requestGroupLocal);
[self methodLocal2WithCompletion:^(NSArray *items) {
dispatch_group_leave(requestGroupLocal);
}];
dispatch_group_t requestGroupAPI = dispatch_group_create();
dispatch_group_enter(requestGroupAPI);
[self methodAPI1WithCompletion:^(NSArray *items) {
dispatch_group_leave(requestGroupAPI);
}];
dispatch_group_enter(requestGroupAPI);
[self methodAPI2WithCompletion:^(NSArray *items) {
dispatch_group_leave(requestGroupAPI);
}];
dispatch_block_t completion = ^{
// do whatever you want when each group finishes
};
dispatch_group_notify(requestGroupLocal, dispatch_get_main_queue(), completion);
dispatch_group_notify(requestGroupAPI, dispatch_get_main_queue(), completion);
Or, if you really wanted just one method for methods 1 and 2, then make local
a parameter, but again, write methods that call their completion handler only once:
dispatch_group_t requestGroupLocal = dispatch_group_create();
dispatch_group_enter(requestGroupLocal);
[self method1Local:true completion:^(NSArray *items) {
dispatch_group_leave(requestGroupLocal);
}];
dispatch_group_enter(requestGroupLocal);
[self method2Local:true completion:^(NSArray *items) {
dispatch_group_leave(requestGroupLocal);
}];
dispatch_group_t requestGroupAPI = dispatch_group_create();
dispatch_group_enter(requestGroupAPI);
[self method1Local:false completion:^(NSArray *items) {
dispatch_group_leave(requestGroupAPI);
}];
dispatch_group_enter(requestGroupAPI);
[self method2Local:false completion:^(NSArray *items) {
dispatch_group_leave(requestGroupAPI);
}];
dispatch_block_t completion = ^{
// do whatever you want when each group finishes
};
dispatch_group_notify(requestGroupLocal, dispatch_get_main_queue(), completion);
dispatch_group_notify(requestGroupAPI, dispatch_get_main_queue(), completion);