ios - Nested multiple request with dispatch_group -
i make multiple requests server fetch posts , comments 1 after another. so, created example dispatch_group fetches posts serially 1 after , after finished posts, fetches comments 1 after another.
here rough schema how works.
- fetch post 1
- fetch post 2
- fetch post 3
- ....
- fetch post 50
- fetch comment 1
- fetch comment 2
- ...
- fetch comment 50
so, these should work serially shown, fetches post 1, finishes , fetches post 2 finish , on.
the following example works fine purpose. but, want have call know when syncing of 50 posts finished , when 50 comments finished. tried adding dispatch_group_notify after loop in requestone , requesttwo. but, notify method seems called when tasks have been completed. how can achieved ? not native english speaker so, please write down if need improve post, can still try :)
@interface grouptest () @property (nonatomic, readonly) dispatch_group_t group; @property (nonatomic, readonly) dispatch_queue_t serialqueue; @end @implementation grouptest - (instancetype)init { if (self = [super init]) { _group = dispatch_group_create(); _serialqueue = dispatch_queue_create("com.test.serial.queue", dispatch_queue_serial); } return self; } - (void)start { dispatch_async(self.serialqueue, ^{ [self requestonecompletion:^{ nslog(@"request 1 completed"); }]; [self requesttwocompletion:^{ nslog(@"request 2 completed"); }]; }); } - (void)requesttwocompletion:(void(^)(void))completion { (nsuinteger = 1; <= 50; i++) { dispatch_group_enter(self.group); [self requestcomment:i completion:^(id response){ nslog(@"%@", response); dispatch_group_leave(self.group); }]; dispatch_group_wait(self.group, dispatch_time_forever); } } - (void)requestonecompletion:(void(^)(void))completion { (nsuinteger = 1; <= 50; i++) { dispatch_group_enter(self.group); [self requestpost:i completion:^(id response){ nslog(@"%@", response); dispatch_group_leave(self.group); }]; dispatch_group_wait(self.group, dispatch_time_forever); } } - (void)requestcomment:(nsuinteger)comment completion:(void(^)(id))completion { nsstring *urlstring = [nsstring stringwithformat:@"https://jsonplaceholder.typicode.com/comments/%lu", (unsigned long)comment]; nsurlsession *session = [nsurlsession sharedsession]; nsurlsessiondatatask *datatask = [session datataskwithurl:[nsurl urlwithstring:urlstring] completionhandler:^(nsdata * _nullable data, nsurlresponse * _nullable response, nserror * _nullable error) { id object = [nsjsonserialization jsonobjectwithdata:data options:0 error:nil]; completion(object); }]; [datatask resume]; } - (void)requestpost:(nsuinteger)post completion:(void(^)(id))completion { nsstring *urlstring = [nsstring stringwithformat:@"https://jsonplaceholder.typicode.com/posts/%lu", (unsigned long)post]; nsurlsession *session = [nsurlsession sharedsession]; nsurlsessiondatatask *datatask = [session datataskwithurl:[nsurl urlwithstring:urlstring] completionhandler:^(nsdata * _nullable data, nsurlresponse * _nullable response, nserror * _nullable error) { id object = [nsjsonserialization jsonobjectwithdata:data options:0 error:nil]; completion(object); }]; [datatask resume]; } @end
i think want following. note made each completion block requesttwocompletion
, requestonecompletion
called after 50 calls done. order of 50 calls not guaranteed.
the main changes made dispatch_group_t
local each method , moved dispatch_group_wait
outside of for
loop. in case takes away benefit of completion
since wait block unit done. if highly insistent on completion being used , not blocking, can wrap in dispatch_async
.
- (void)requesttwocompletion:(void(^)(void))completion { dispatch_group_t group = dispatch_group_create(); (nsuinteger = 1; <= 50; i++) { dispatch_group_enter(group); [self requestcomment:i completion:^(id response){ nslog(@"%@", response); dispatch_group_leave(group); }]; } dispatch_group_wait(group, dispatch_time_forever); completion(); } - (void)requestonecompletion:(void(^)(void))completion { dispatch_group_t group = dispatch_group_create(); (nsuinteger = 1; <= 50; i++) { dispatch_group_enter(group); [self requestpost:i completion:^(id response){ nslog(@"%@", response); dispatch_group_leave(group); }]; } dispatch_group_wait(group, dispatch_time_forever); }
as in serial queue, way work requestonecompletion
finish 50, , requesttwocompletion
run 50 next.
Comments
Post a Comment