【问题标题】:Replacing NSURLConnection with NSURLSession用 NSURLSession 替换 NSURLConnection
【发布时间】:2014-06-09 05:20:21
【问题描述】:

我已经开始为NetworkCommunication 设计。我有一个设计,其中NSOperation 子类创建和管理自己的NSURLConnectionNSOperation 子类由 NetworkManger 类实例化,该类将其添加到 NSOperationQueue。一旦请求完成,委托(例如:ViewController 将被调用)。这是流程:

网络管理器实例化 NSOperation 子类(封装 URL、参数等)并将其添加到它维护的 NSOperationQueue 中。 NSOperation 子类实例化NSURLConnection(执行asynchronous 请求并检索数据) NSURLConnection 将数据转储到 NSOperation-subclass NSOperation 子类执行委托(视图控制器)提供的完成块。 我现在正在尝试使用NSURLSession 实现相同的模式。我希望能够将发出网络请求所需的 url 和参数封装在单个对象中。

如果我使用NSURLSession,是否可以使用相同的模式。我检查了AFNetworking 课程。但是,他们没有将 NSOperation 子类化为NSURLSession。而且,会话对象应该去哪里。它会成为 NSOperation 类的一部分吗?

有人可以就此提供一些专家建议吗?我应该能够取消请求、上传(POST/PUT)、下载数据。 Network Manager 类将是任何网络请求的单一联系点。

【问题讨论】:

  • @Bhavesh Nai,请不要在编辑的末尾添加“提前感谢”或其他称呼,它们被视为“噪音”meta.stackexchange.com/questions/2950/…
  • 有人可以回答这个问题,而不仅仅是编辑。这里没有 iOS 专家吗?PL 帮助

标签: ios nsurlsession


【解决方案1】:

更新:

NSURLConnection 已弃用,适用于 Mac OS 10.11 和 iOS 9。因此,此时应使用 NSURLSession 代替 NSURLConnection。正如NSURLConnection.h 标头所说:

已弃用:不应再使用 NSURLConnection 类。 NSURLSessionNSURLConnection 的替代品。

我的原始答案如下。


答案取决于您是否需要丰富的各种NSURLSession 委托方法。如果您可以使用完成块再现(即没有进度回调、没有流式传输等),从NSURLConnectionNSURLSession 的转换非常简单。只需将您的 NSURLSession 实例放入您的 NetworkManager 类中,然后将基于委托的 NSURLSessionTask 实例包装在并发的 NSOperation 子类中即可。只需采用标准的异步/并发NSOperation 子类模式即可。

如果您使用NSURLSession 的基于委托的演绎版,那就完全不同了。主要的麻烦是各种NSURLSessionTask 委托方法是在会话delegate 而不是任务委托对象上调用的。乍一看,这听起来像是一个微不足道的问题,但是如果您的操作实例具有唯一的完成/进度块,例如,您会遇到如何让会话对象将这些委托方法回调映射到个人的麻烦原始请求操作实例。

要解决这个问题,您必须维护任务标识符到 NSOperation 子类对象的映射。然后,您可以在各自的NSOperation 子类中实现这些NSURLSessionTask(包括任务、下载任务和上传任务)委托方法。然后,NSURLSession 网络管理器类可以在收到 NSURLSessionTask 委托调用时,使用任务标识符来识别适当的 NSOperation 实例,然后在那里调用适当的委托方法。

最后,如果您打算处理后台 NSURLSession 实例,生活会变得更加困难(因为即使在您的应用程序终止并且其所有对象都已被丢弃后,后台任务仍将继续)。后台会话根本不适合基于 NSOperation 的方法。

底线,如果您只需要完成块 NSURLSession 方法,这很简单,但如果您需要基于委托的再现,这有点麻烦。

【讨论】:

  • 谢谢罗伯。这是我现在的理解:如果我们要采用基于块的方法,则 NSOperation 很好。但是,如果我们要采用基于委托的方法,那么我们必须管理任务。我的疑问是:如果我让 NSOperation 子类实现任务级委托方法,那么问题是什么。请解释一下。我不明白。
  • @user694688 我并不是说您不能对基于委托的NSURLSession 使用基于操作的方法,而是说它需要更多的工作。
  • 例如,假设您有两个网络请求,分别封装在各自的操作中,一个是下载图像,另一个是请求 JSON。当NSURLSession 为其委托调用任务委托方法时,它如何知道该调用是针对哪个操作(图像或 JSON)?有两种合乎逻辑的方法:一种是为每个操作设置一个单独的会话(这在架构上似乎不优雅)。另一种是让公共会话实例维护哪个任务标识符属于哪个操作的映射。
  • Rob - 谢谢我明白这一点。解决此问题的最佳方法是什么,因此实现是可扩展的。而且,为什么要在会话级别实施任务级别委托。现在,我有两个类,Network Manager 和 NetworkOperation(NSOperation 的子类)。NetworkManager 类有一个 NSOperationQueue,我为每个请求创建 NetworkOperation 类并添加它。我应该如何为 NSURLSession 更改它。
  • @user694688 为什么要在会话级别实现任务委托?我不知道 Apple 的精确思考过程,但如果我猜的话,它可能会想出一个与添加到后台会话的任务兼容的设计,在下载完成时可以终止应用程序然后重新启动。您可以轻松地重新实例化会话管理器委托,但重新实例化单个任务委托将非常困难。话虽如此,恕我直言,这是一个愚蠢的设计(加上未能给我们userInfo 对象)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-04
相关资源
最近更新 更多