在Swift中隔离任务,或如何创建可测试的网络层。

在过去的几年中,有许多闪亮的iOS体系结构越来越受到人们的炒作。 因为它们都是有效的,并且有好有坏,所以它们都解决了同一件事: 将业务逻辑与表示分离。 今天,我将写一个简单的概念,该概念适用于您下一个项目的架构,无论您打算使用哪种架构。

相当普通的网络层

为了解释我的观点,我将首先谈谈通常如何实现网络层。

我见过很多不同的网络层。 在大多数情况下,都有NetworkManager,ConnectionManager或类似的东西。 有一个类包含应用程序中的每个API调用。 尽管这是有效的并且可以正常工作,但它并没有遵循软件设计的核心概念: 单一职责。

ConnectionManager包含太多职责,因此不被认为是好的做法。 而且,它通常实现为单例。 我并不是说单例不一定很坏,但是不能将它们作为依赖项注入,并且在测试时不能轻易模拟。

这是非常常见的做法。 我也在MVVM或MVP架构中看到了这一点。

不同的方法

数据访问层可以以不同的方式实现。 让我们描述网络获取的过程:

这样,网络调用至少包含三个步骤:

  1. 创建一个请求 :这意味着设置URL,方法,参数(在URL路径或http正文中)和HTTP标头。
  2. 发货请求 :这是非常非常重要的一步。 必须使用URLSession或其上的一层(例如Alamofire)调度在上一步中创建和配置的请求。
  3. 获取和解析响应 :重要的是,此步骤应与前两个步骤分开实施。 在这里,您应该验证JSON或XML响应,然后将其解析为有效的Entity(如果愿意,也可以解析为Model)。

如果您确实希望您的体系结构干净且可测试,则应在不同的对象中实现这三个步骤。

这些对象如下:

  1. RequestRequest对象具有配置网络请求所需的一切。 它是负责配置单个网络请求的结构或类。 这非常重要: 一个网络请求,一个 Request 对象。
  2. NetworkDispatcherNetworkDispatcher是一个对象,负责获取Request并返回Response 。 它应该作为协议来实现。 您应该针对该协议而不是针对具体的类(或结构)进行编码,并且永远不应将其实现为单例。 如果执行此操作,则可以将该NetworkDispatcher替换为实际上不发出任何网络请求的MockNetworkDispatcher ,而是从JSON文件获取响应,从而形成自然可测试的体系结构。
  3. NetworkTaskNetworkTask是通用类Task的子类。 正如我将在稍后更好地解释的,任务是一个通用类,它负责以同步或异步方式获取Input类型并返回Output类型。 您可以使用RxSwift,ReactiveCocoa,Hydra,Microfutures,FOTask或仅使用闭包来实现Task 。 由你决定。 这里的重要部分是概念,而不是实现细节。

实施请求

Request是一个对象,负责配置创建URLRequest所需的一切。

网络请求的示例可能像这样:

结论

在分离的对象中隔离业务逻辑操作是一个好习惯,因为它允许创建更可测试的体系结构。 它降低了复杂性,并且完全独立于所使用的体系结构。 可以在ViewModelPresenterInteractorStore或用于将业务逻辑与表示逻辑分离的任何东西之后使用。

我希望这会对您有所帮助。 如果您有疑问或知道更好的方法,请在下面留下您的评论。