最佳实践,以取代NSURLSession

问题描述:

同步NSURLConnection的作为最佳实践,以取代NSURLSession

NSURLConnection sendSynchronousRequest:returningResponse:error:&connectionError 

是集弃用我将不得不更换一个进口商,我写了很久以前。

导入器执行以下操作:

  1. 它获取从API-A的数据。数据可以在多个页面上。
  2. 它使用从第一数据提取(也多页)来查询从API-B数据和合并
  3. 结果从API-B的查询将与数据从API-A

我被合并通过后台操作实现了这一点,其中我使用每个API的方法,如果请求有多个页面,则递归调用。

但是由于NSURLSession不支持同步请求,我目前只能看到有很多开销(例如iVars)控制完成块(例如下一页或开始查询API-B)的内容的选项。

那么,什么是一个优雅的解决方案,把这个NSURLSession。

注:只是为了确保,我以前的解决方案根本不会阻塞主线程。但当时,这是控制两个来源合并的最简单方法。

+0

这里是你的答案,http://stackoverflow.com/a/30952732/2713079 – itsji10dra

+1

我不明白这就是为什么你需要同步调用。由于按正常惯例,Webservicecalls始终应该是异步的。如果你想让用户等待,那么..把一个HUD/ActivityIndi​​cator显示设备正在获取结果..同步调用任何web api不是一个好主意。所以按照我的建议去通过异步调用 –

+1

正如我上面提到的,我在后台线程上进行导入,所以既没有阻塞UI也没有一些进度指示器可见。 而我之所以使用同步方法(同样,我用它的方式并没有阻止任何东西!)是我必须等待来自未知数量请求的未知数量的数据。而且,同步方法允许我处理这个问题比保留处理异步请求的大量开销要好得多。 – MatzeLoCal

这个答案不应该是最佳实践。这对我来说很实际。

时同步请求的一堆在后台执行和执行事项的顺序我已经结束了使用以下与形势:

SyncRequestSender.h

#import <Foundation/Foundation.h> 

@interface SyncRequestSender : NSObject 

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request 
       returningResponse:(NSURLResponse **)response 
          error:(NSError **)error; 

@end 

SyncRequestSender.m

#import "SyncRequestSender.h" 

@implementation SyncRequestSender 

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request 
       returningResponse:(NSURLResponse **)response 
          error:(NSError **)error 
{ 
    dispatch_group_t group = dispatch_group_create(); 
    dispatch_group_enter(group); 


    NSError __block *err = NULL; 
    NSData __block *data; 
    NSURLResponse __block *resp; 

    [[[NSURLSession sharedSession] dataTaskWithRequest:request 
            completionHandler:^(NSData* _data, NSURLResponse* _response, NSError* _error) { 
     resp = _response; 
     err = _error; 
     data = _data; 
     dispatch_group_leave(group); 

    }] resume]; 

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

    if (response) 
    { 
     *response = resp; 
    } 
    if (error) 
    { 
     *error = err; 
    } 

    return data; 
} 

@end 
+0

使用'dispatch_semaphore_wait'更好,我想。 –

+0

@KleinMioke考虑使用它,但由于某种原因决定与派遣组一起玩。 – Anton

这是AFNetworking中的一个示例,它显示了如何等待异步任务。

- (NSArray *)tasksForKeyPath:(NSString *)keyPath { 
    __block NSArray *tasks = nil; 
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 
    [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) { 
     if ([keyPath isEqualToString:NSStringFromSelector(@selector(dataTasks))]) { 
      tasks = dataTasks; 
     } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(uploadTasks))]) { 
      tasks = uploadTasks; 
     } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(downloadTasks))]) { 
      tasks = downloadTasks; 
     } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(tasks))]) { 
      tasks = [@[dataTasks, uploadTasks, downloadTasks] valueForKeyPath:@"@unionOfArrays.self"]; 
     } 

     dispatch_semaphore_signal(semaphore); 
    }]; 

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

    return tasks; 
}