异步网络任务的循环(上一个完成后执行下一个)

Cycle of asynchronous network tasks (Next executed after completion of previous one)

我需要执行这些任务,以便在完成上一个任务后执行以下任务。

有我的代码:

[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];
    });
}];

我试过调试这个,但是信号量之后的动作永远不会执行。

谁能帮帮我?谢谢。

我能够解决我的问题。我 post 代码,也许对某人有用。

[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];
    });
}];