适用于iOS的同步网络方法

这篇文章提出了一种同步处理网络的方法。 它开始回顾当今如何异步处理网络,继续检测异步性的源头,并以展示如何删除它如何改善可伸缩性,可测试性,表达性,模块化和线程控制为结尾。

如今联网

当作为移动开发人员,我们需要从服务器获取数据并将其显示在设备中时,我们遵循的方法不会冻结UI:

  1. 我们在主线程中显示了一个动画微调器;
  2. 我们在另一个线程中请求数据;
  3. 当请求完成时,我们返回主线程;
  4. 我们删除了微调器;
  5. 我们使用接收到的数据刷新UI。
我们获取和呈现数据而不冻结UI的方法。

数据来自以下服务:

  1. 使用NSURLSession,Alamofire或其他机制发送HTTP请求;
  2. 使用本机工具,SwiftyJSON或其他库解析HTTP响应;
  3. 将结果(事物数组或错误)统一为两个可选参数或结果monad;
  4. 使用回调机制,作为参数接收的函数或先前分配的委托返回结果。
一种可能的服务实现,它使用回调来返回获取的数据(或错误)。

异步的根源

从网络获取数据的任何组件都必须异步处理,以避免冻结应用程序; 但是,应该在API级别包括异步性吗? 我们以后不能处理吗? API级别的异步性迫使我们立即对其进行处理; 我们无法决定何时处理。

如果我们注意前面的代码段,则在发送HTTP请求时会出现异步性。 我们丢失了流控制,并在调用作为参数传递的函数时将其恢复。 然后,如果我们在另一个线程上,则返回主线程以更新UI。

吻:保持同步,s **** d!

让我们删除异步源,以异步方式转换异步服务API:

自iOS 9以来,没有很多库向我们提供同步请求,并且不赞成使用本机执行同步请求的方法,但是我们可以使用本机SDK解决该问题。

首先,它看起来非常简单:您想要的东西,可以调用getThings() ,您将收到您想要的东西(或错误)作为返回值。 但是,如果您在主线程中调用它,则该应用程序将冻结,直到我们收到对HTTP请求的响应。 因此,现在该处理它了:

我们使用此辅助函数来提高可读性和模块化性,但是我们可以直接使用SDK,使用任何async-await库,任何Futures库或继续期待Swift 5。

这样,我们选择在后台线程中执行服务以避免冻结应用程序。

一些优点是:

  • 该代码更简单,语义上也更好。 我们索要一些东西,然后得到它作为……一个返回值☺,而不是作为回调函数或委托方法中的参数(参数用于发送事物,而不是返回它们)。
  • 我们在控制线程。 我们决定在后台线程中以有效意图执行某些代码(不阻塞UI),我们决定以另一个明确定义的目的返回主线程(更新UI)。 如果不需要,我们不在乎切换线程。
  • 我们可以通过一种更简单的方式伪造服务,无需在延迟后调用回调,只需将所需的值作为返回值返回即可。
  • 我们可以以更舒适的方式测试服务,无需期望,因为在运行测试时没有UI线程会阻塞,因此您可以在当前线程中同步使用服务。 重要的是要注意,这些测试是集成测试,而不是单元测试。 使用服务时,我们是在测试环境(在最佳情况下为此类测试专用的环境)中创建/修改/删除实体。
  • 我们可以以可扩展的方式编写服务呼叫。

一些缺点是:

  • 以非标准方式处理网络。
  • 没有同步发送网络请求的直接方法。

结论

软件组件的API定义了其使用方式。 如果我们在组件内部处理异步性,并添加回调函数作为参数,那么我们将迫使使用API​​的任何人立即处理异步性。

通过定义同步API,我们使我们的API更简单,使用它的任何人都可以决定是否以及何时使其异步。 我们的组件只是做它所做的事情,它并不关心线程,使用它的任何人只有在他认为必要时才关心线程。


注意1:在Codika,这种同步联网方法已成为我们iOS应用程序的开发标准,我们对结果感到非常满意。

注意2:我没有发现很多文章讨论这种方法,而只是 一篇


Codika 是一家创新的软件开发公司,旨在激励其成员进行研究并分享他们的改进。 我们希望鼓励所有公司创新并提高社会生活质量。