Objective c 在前一次运行成功完成后,如何将多个AFNetworking调用链接到每次运行?

Objective c 在前一次运行成功完成后,如何将多个AFNetworking调用链接到每次运行?,objective-c,asynchronous,objective-c-blocks,afnetworking,Objective C,Asynchronous,Objective C Blocks,Afnetworking,以下方法使用AFNetworking向Web服务发送请求,并(成功时)对响应进行操作。AFNetworking异步执行请求,并使用块成功或失败。因此,发送请求的方法如下所示(简化): 在另一个类中,此方法用于多次调用webservice。上一次呼叫成功后,下一次呼叫完成。此方法如下所示(为简洁起见,省略了故障块): 这是可行的,但正如大家所看到的,每个webservice调用都会添加另一个嵌套的成功块处理程序。在我看来,一定有更好的方法来做到这一点,但我想不出一个 最好是在执行下一个调用之前等待

以下方法使用AFNetworking向Web服务发送请求,并(成功时)对响应进行操作。AFNetworking异步执行请求,并使用块成功或失败。因此,发送请求的方法如下所示(简化):

在另一个类中,此方法用于多次调用webservice。上一次呼叫成功后,下一次呼叫完成。此方法如下所示(为简洁起见,省略了故障块):

这是可行的,但正如大家所看到的,每个webservice调用都会添加另一个嵌套的成功块处理程序。在我看来,一定有更好的方法来做到这一点,但我想不出一个

最好是在执行下一个调用之前等待上一个调用完成,并使用GCD之类的东西异步调用整个导入方法。但是,AFNetworking并不是为进行同步调用而设计的


任何如何实现这一目标的想法都是非常受欢迎的。或者我当前的解决方案就是这样吗?

如果要进行同步调用,只需使用NSString的“stringWithContentsOfURL:”方法即可。因此,只需在循环中使用此代码循环NSURL的NSArray

NSError* error = nil;
NSString* htmlSource = [NSString stringWithContentsOfURL:theNSURL encoding:NSUTF8StringEncoding error:&error];
if (error) {
    // handle error
}
// parse htmlSource

我建议你看看这个答案


建议使用一些自定义解决方案来解决此问题。

您可以查看
octokit
。它们将AFN网络与Mantle和ReactiveCocoa结合在一起——与ReactiveCocoa的链接工作简单、干净


我也面临同样的问题,并且一直在考虑引入&有一段时间了。但我最终还是放弃了,并提出了一个简单而又有点混乱的解决方案

因此,我引入了一个名为“step”的属性,其主要目的是对其进行kvo。然后,对于完成的每个异步调用,都需要标记其步骤。然后,kvo方法将整个过程移动到下一步,即kvo方法进行流量控制。

例如,您的sendRequestForConnector:@“城市”将是步骤1,@“类别”将是步骤2,@“类别转换”将是步骤3,@“产品”将是步骤4。。。在每个成功块的末尾,将步骤设置为自己的值。所以kvo将知道这一步已经完成,它需要调用下一个异步方法

kvo方法监督和控制整个过程

switch (step.intValue) {
    case 1: //call step2; break;
    case 2: //call step3; break;
    case 3: //call step4; break;
    case 4: //call step5; break;
    ...
    case x: // finish, remove kvo on step
}

到目前为止,它符合我的目的,我的代码看起来更干净。

我的情况与上次上传完成后需要等待响应并调用ws进行上传的情况相同

有几种方法可以做到这一点

1) 您可以使用
dispatch\u group
并在完成所有任务后通知

2) 使用create信号量逐个调用ws

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(queue, ^{
    dispatch_semaphore_t test = dispatch_semaphore_create(0);
    for (NSUInteger i = 0; i < self.uploadDocument.count; ++i) {
       // My custom method with block which call ws 
      [self uploadMultipleImagesUsingAFNetworkingMultipartFormatWithDocumentId:[[self.uploadDocument objectAtIndex:i] valueForKey:kDocument_DocumentId] andIndex:i withCompletionBlock:^(id responseObj, NSError *error) {

            // Your Logic 

            dispatch_semaphore_signal(test);
        }];
        dispatch_semaphore_wait(test, DISPATCH_TIME_FOREVER);

    // Here comes when your all ws finish 
      dispatch_async(dispatch_get_main_queue(), ^{
              [self.tblUpload reloadData];
              [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

        });
    }
dispatch\u queue\u t queue=dispatch\u get\u global\u queue(dispatch\u queue\u PRIORITY\u DEFAULT,0);
调度异步(队列^{
调度信号量测试=调度信号量创建(0);
对于(i=0;i
也有同样的问题,你找到了什么好的解决方案吗?谢谢我也在寻找解决方案。我的后续请求取决于前一个请求的结果。这并不能回答问题。有时,你不回答问题,而是建议一种更好地帮助海报acco的替代方法mplish他的目标。他想要同步调用,因此没有理由使用块和修改用于异步调用的自定义类。简单的NSString方法可以做到。如果他不想在主线程运行时阻止主线程,那么只需在后台线程上运行NSString方法(同样,一段简单的一行代码)。他甚至可以在完成后发布通知,主线程可以接收通知,并在必要时执行一些post操作。如果您需要链接多个调用,而当前调用取决于前一个调用的成功与否,则此解决方案可能无法工作,我认为它应该工作,因为它将等待其他响应发出信号信号量,我正在使用它和工作,但你可以给我建议,以改善这一点,thnx为您的评论,所以你可以尝试我的解决方案,以及:D
switch (step.intValue) {
    case 1: //call step2; break;
    case 2: //call step3; break;
    case 3: //call step4; break;
    case 4: //call step5; break;
    ...
    case x: // finish, remove kvo on step
}
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(queue, ^{
    dispatch_semaphore_t test = dispatch_semaphore_create(0);
    for (NSUInteger i = 0; i < self.uploadDocument.count; ++i) {
       // My custom method with block which call ws 
      [self uploadMultipleImagesUsingAFNetworkingMultipartFormatWithDocumentId:[[self.uploadDocument objectAtIndex:i] valueForKey:kDocument_DocumentId] andIndex:i withCompletionBlock:^(id responseObj, NSError *error) {

            // Your Logic 

            dispatch_semaphore_signal(test);
        }];
        dispatch_semaphore_wait(test, DISPATCH_TIME_FOREVER);

    // Here comes when your all ws finish 
      dispatch_async(dispatch_get_main_queue(), ^{
              [self.tblUpload reloadData];
              [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

        });
    }