1

Мне нужно выполнить задачи, чтобы после завершения предыдущего выполнить следующую задачу.Цикл асинхронных сетевых задач (следующий выполняется после завершения предыдущего)

Существует мой код:

[self startLoading]; 
NSMutableArray *failedContainerRequests = [NSMutableArray new]; 
MyContainersViewController __weak *weakSelf = self; 
[[RuzaServerAPI newAPIObject] serverGetListOfContainersWithSuccess:^(NSArray *containers) { 
    dispatch_group_t downloadGroup = dispatch_group_create(); 
    for (RZContainerModel *containerModel in containers) { 
     NSLog(@"Start container %@ with id %@", containerModel.containerName, containerModel.containerID); 
     dispatch_group_enter(downloadGroup); 
     dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      [[RuzaServerAPI newAPIObject] serverGetListOfProductsInContainer:containerModel.containerID withSuccess:^(NSArray *products) { 
       if (products.count > 0) { 
        containerModel.products = [NSMutableArray arrayWithArray:products]; 
        NSMutableArray *imagesURLs = [NSMutableArray new]; 
        for (RZProductModel *productModel in products) { 
         if (productModel.frontImageUrl) { 
          [imagesURLs addObject:productModel.frontImageUrl]; 
         } 

         if (productModel.backImageUrl) { 
          [imagesURLs addObject:productModel.backImageUrl]; 
         } 
        } 

        [self addImagesToDownloadQueue:imagesURLs.copy withComplection:^(BOOL status) { 
         [[RZCoreDataManager sharedInstance] saveContainer:containerModel withCompletion:^(BOOL success) { 
          NSLog(@"Container %@ succesfully saved!", containerModel.containerName); 
          dispatch_semaphore_signal(semaphore); 
          dispatch_group_leave(downloadGroup); 
         }]; 
        }]; 
       } else { 
        [[RZCoreDataManager sharedInstance] saveContainer:containerModel withCompletion:^(BOOL success) { 
         NSLog(@"Container %@ succesfully saved!", containerModel.containerName); 
         dispatch_semaphore_signal(semaphore); 
         dispatch_group_leave(downloadGroup); 
        }]; 
       } 
      } failure:^(NSError *error) { 
       NSLog(@"Container %@ failed!\n%@", containerModel.containerName, error.localizedDescription); 
       [failedContainerRequests addObject:containerModel]; 
       dispatch_semaphore_signal(semaphore); 
       dispatch_group_leave(downloadGroup); 
       //     dispatch_async(dispatch_get_main_queue(), ^{ 
       //      // Error message! 
       //     }); 
      }]; 
     }); 
     dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 
    } 

    dispatch_group_notify(downloadGroup, dispatch_get_main_queue(),^{ 
     [weakSelf stopLoading]; 

     for (RZContainerModel *containerModel in failedContainerRequests) { 
      NSLog(@"Container %@", containerModel.containerName); 
     } 

    }); 
} failure:^(NSError *error) { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [weakSelf stopLoading]; 
     NSString *messageStr = [NSString stringWithFormat:@"%@\nПопробовать еще раз?", error.localizedDescription]; 
     LGAlertView *allert = [[LGAlertView alloc] initWithTitle:@"Ошибка" 
                 message:messageStr 
                  style:LGAlertViewStyleAlert 
                buttonTitles:@[ @"ОК" ] 
               cancelButtonTitle:@"Отмена" 
              destructiveButtonTitle:nil 
                actionHandler:^(LGAlertView *alertView, NSString *title, NSUInteger index) { 
                 [weakSelf getListOfContainers]; 
                } 
                cancelHandler:nil 
               destructiveHandler:nil]; 
     [allert showAnimated:YES completionHandler:nil]; 
    }); 
}]; 

Я попытался отладки, но действия после семафора никогда не выполняется.

Может ли кто-нибудь мне помочь? Спасибо.

ответ

1

Я смог решить свою проблему. Я размещаю код, может быть, это будет полезно для кого-то.

[self startLoading]; 
NSMutableArray *failedContainerRequests = [NSMutableArray new]; 
MyContainersViewController __weak *weakSelf = self; 
[[RuzaServerAPI newAPIObject] serverGetListOfContainersWithSuccess:^(NSArray *containers) { 
    dispatch_group_t downloadGroup = dispatch_group_create(); 
    dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL); 
    dispatch_async(queue, ^{ 
     for (RZContainerModel *containerModel in containers) { 
      NSLog(@"Start container %@ with id %@", containerModel.containerName, containerModel.containerID); 
      dispatch_group_enter(downloadGroup); 
      dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 

      [[RuzaServerAPI newAPIObject] serverGetListOfProductsInContainer:containerModel.containerID withSuccess:^(NSArray *products) { 
       NSLog(@"Container %@ succesfully downloaded!", containerModel.containerName); 
       if (products.count > 0) { 
        containerModel.products = [NSMutableArray arrayWithArray:products]; 
        NSMutableArray *imagesURLs = [NSMutableArray new]; 
        for (RZProductModel *productModel in products) { 
         if (productModel.frontImageUrl) { 
          [imagesURLs addObject:productModel.frontImageUrl]; 
         } 

         if (productModel.backImageUrl) { 
          [imagesURLs addObject:productModel.backImageUrl]; 
         } 
        } 

        [self addImagesToDownloadQueue:imagesURLs.copy withComplection:^(BOOL status) { 
         [[RZCoreDataManager sharedInstance] saveContainer:containerModel withCompletion:^(BOOL success) { 
          NSLog(@"Container %@ succesfully saved!", containerModel.containerName); 
          dispatch_semaphore_signal(semaphore); 
          dispatch_group_leave(downloadGroup); 
         }]; 
        }]; 
       } else { 
        [[RZCoreDataManager sharedInstance] saveContainer:containerModel withCompletion:^(BOOL success) { 
         NSLog(@"Container %@ succesfully saved!", containerModel.containerName); 
         dispatch_semaphore_signal(semaphore); 
         dispatch_group_leave(downloadGroup); 
        }]; 
       } 
      } failure:^(NSError *error) { 
       NSLog(@"Container %@ failed!\n%@", containerModel.containerName, error.localizedDescription); 
       [failedContainerRequests addObject:containerModel]; 
       dispatch_semaphore_signal(semaphore); 
       dispatch_group_leave(downloadGroup); 
       //     dispatch_async(dispatch_get_main_queue(), ^{ 
       //      // Error message! 
       //     }); 
      }]; 
      dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 
     } 

     dispatch_group_notify(downloadGroup, dispatch_get_main_queue(),^{ 
      [weakSelf stopLoading]; 
     }); 
    }); 
} failure:^(NSError *error) { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [weakSelf stopLoading]; 
     NSString *messageStr = [NSString stringWithFormat:@"%@\nПопробовать еще раз?", error.localizedDescription]; 
     LGAlertView *allert = [[LGAlertView alloc] initWithTitle:@"Ошибка" 
                 message:messageStr 
                  style:LGAlertViewStyleAlert 
                buttonTitles:@[ @"ОК" ] 
               cancelButtonTitle:@"Отмена" 
              destructiveButtonTitle:nil 
                actionHandler:^(LGAlertView *alertView, NSString *title, NSUInteger index) { 
                 [weakSelf getListOfContainers]; 
                } 
                cancelHandler:nil 
               destructiveHandler:nil]; 
     [allert showAnimated:YES completionHandler:nil]; 
    }); 
}];