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

Popular posts from this blog

angular - Is it possible to get native element for formControl? -

unity3d - Rotate an object to face an opposite direction -

javascript - Why jQuery Select box change event is now working? -