基于NSURLSession的networking模式

我一直在使用NSOperation子类创build和pipe理自己的NSURLConnection的模式。 NSOperation子类由视图控制器实例化,并且在完成之前不会打扰控制器。 当完成检索数据时,它将执行由视图控制器提供的完成块。

  1. ViewController实例化NSOperation子类(封装URL,参数等)
  2. NSOperation子类instanciates NSURLConnection(执行同步请求和检索数据)
  3. NSURLConnection将数据转储到NSOperation子类
  4. NSOperation子类执行由视图控制器提供的完成块。

我试图现在与NSURLSession实现相同的模式。 我希望能够封装在一个对象内进行networking请求所需的url和参数。 我是否使用NSURLSession子类或NSURLSessionTask子类实现此目的?

我喜欢根据angular色devise模式为每个networking操作创build单独的类。

您可以使用相同的模式,用NSURLSessionTask子类(例如NSURLSessionDataTask )replaceNSURLConnection

正如@CouchDeveloper在注释中所build议的,另一种方法是使用asynchronous语义(取消,恢复等)将NSURLSessionTask包装在一个非NSOperation对象中。 这个包装器对象只会对参数进行编码和解码,并将大部分操作委托给包装的任务。

在这两种情况下,要实例化NSURLSessionTask ,您将需要一个NSURLSession 。 ( NSURLSessionNSURLSessionTask工厂。)如果所有操作都使用相同的configuration (Cookie,代理,caching等),则可以简单地使用共享会话( +[NSURLSession sharedSession] )。 如果他们需要不同的configuration,你将不得不给他们一个NSURLSession或足够的信息来创build自己的。

NSURLSessionTask类(及其子类)看起来有点像操作,但它们不是。 因此,当你转换到NSURLSession ,你可以从你的代码中移除操作,但是如果你这样做,你将会失去某些NSOperationfunction(依赖,控制并发度等等)。 我不确定为什么当你转换到NSURLSession你想从代码中NSURLSession 。 就我个人而言,我曾经在一个操作中包装NSURLConnection ,我现在用一个操作来包装一个NSURLSessionTask

另外, NSURLSession一个重要问题是, 任务委托被设置在会话对象上。 我们可以猜测为什么苹果这样做,但是它有各种不幸的含义。 显然你可以通过使用基于块的工厂方法来创build你的任务来解决这个问题,但是如果你碰巧需要的话,那么你就失去了委托API的丰富性。

这意味着,如果使用基于块的任务工厂方法,将任务包装在一个并发的NSOperation子类中是相当明显的。 但是,如果使用基于委托的任务,但是如果您需要任务的自定义处理程序,则必须通过维护任务标识符和相应的完成块(我将其置于会话pipe理器对象我用来包装NSURLSession )。 (仅供参考,我相信在即将到来的AFNetworking更新中也会有这样的实现。关于AFNetworking github网站,请参阅关于第1504期的讨论的后半部分)。

无论如何,其他人已经回答了你如何用基于非操作的NSURLSession代码replace基于操作的NSURLConnection代码,但是我个人build议留在操作中。


顺便说一下,我已经上传了一个基于操作的NSURLSession在github上的实现: https : //github.com/robertmryan/NetworkManager

这不是一个完整的解决scheme,而是说明如何使用NSOperation子类实现基于委托的NSOperation

我希望能够封装在一个对象内进行networking请求所需的url和参数。 我是否使用NSURLSession子类或NSURLSessionTask子类实现此目的?

你所描述的是NSURLRequestNSURLSessionNSURLConnection使用NSURLRequest来执行networking连接( NSURLRequest就是它所执行的)。 你似乎想要的是一套工厂方法来生成不同的,专门的NSURLRequests 。 例如,描述“获取我的邮件”请求的一个。 你可以通过在NSURLRequest本身上创build一个类别来轻松完成。 例:

 @implementation NSURLRequest (Mail) + (instancetype) mailRequestForUser:(NSString *)user { NSURLRequest *result = nil; result = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"someServer""]]; // set user in a header, whatever // return immutable copy return [result copy]; } @end 

创build类似于以上的东西,满足您的需求。 然后可以使用生成的NSURLRequest来创build连接。 在cocoa这是一个非常典型的自定义对象模式,而不是子类化。 子类化是非常罕见的 – 相反,Cocoa有其他自定义类行为的机制,从工厂方法(如上所述的“方便方法”)到委托(对象被赋予另一个对象的行为责任)。