构建Foursquare克隆iOS应用-第5部分:网络层

  • 第1部分:简介和设置
  • 第2部分:位置数据和管理依赖项
  • 第三部分:持续集成
  • 第4部分:流媒体位置
  • 第5部分:网络层
  • 第六部分:国家管理

在详细说明此应用程序的范围时,我不希望主数据源是一个简单的API调用,而是要更复杂一些,这取决于两个数据源的集成。 这样,测试将更加复杂,并且需要更多的计划和研究。

在这种情况下,显示给用户的最终数据取决于iOS SDK提供的用户位置,该位置将用于请求附近地点的Foursquare API。

现在,我们有了获取用户位置的可靠方法,我们可以在Foursquare Places API请求中使用此信息来获取附近的位置。 Moya依赖关系将帮助我们完成此任务,特别是通过将HTTP响应自动包装到Observable

我们感兴趣的端点是“获取场地建议”。 通过阅读文档,我们需要发送的请求参数为:

  • v :我们要使用的API版本。 我使用的是本文撰写的当前日期。
  • venuePhotos照片:布尔值,以在响应中包括照片
  • limit :结果数
  • ll :经度和纬度
  • client_idclient_secrent :您通过在Foursquare开发人员平台中注册获得的凭证

为了将所有这些翻译成Moya可以理解的语言,我们需要创建一个enum ,每种case都将代表给定URL的终结点。 然后,该enum需要符合MoyaTargetType协议。

然后将此文件添加到XCode项目。 我决定将其添加到名为“ Stubbed Responses”的文件夹中,您可以在其中检查Github存储库。

现在,您可以指示PlacesApi使用此文件的内容来创建sampleData方法的返回:

您可以通过在构造函数中传递以下行为来指示MoyaProvider使用存根响应,而不是执行实际的网络请求:

let provider = MoyaProvider(stubClosure: MoyaProvider.immediatelyStub)

存根响应使我们能够实现上述第一个测试用例,从而确保应用程序将为预期的JSON响应创建有效的模型实例。

现在我们需要一个数据结构,该结构允许我们在存根响应(用于测试)和实际实现之间进行切换。 Moya官方文档中描述的包装适配器模式将非常适合此操作。 我们的包装器结构将称为PlacesService

现在,第一个测试用例的实现非常简单。

Moya还提供了终结点关闭支持,我们可以使用它来模拟网络故障。 首先,我们在PlacesApi文件中声明此关闭:

然后,我们只需要将此方法传递给MoyaProvider构造函数即可:

现在,我们可以将所有内容粘合在一个测试用例中:

预期会传递相同的错误

经过一些工作,我们现在有了一个使用Foursquare API提取附近地点的类,以及另一个可以获取用户位置的类。 下一步是从后者获取数据并获取用户位置附近的地点。

我决定使用一种新结构来接收两个数据源类,然后返回需要在UI上显示的最终结果。

这也使我们可以监视PlacesService以确保正确完成了实现。

为了正确监视,我们需要这种结构依赖于接口,而不是网络请求类的实际实现。

该协议将称为PlacesDatasource和实现PlacesService

使用新协议更新了PlacesService

现在,我们可以实现一个结构,该结构将PlacesDatasourceUserLocationDatasource接收为依赖项并执行它们之间的通信:

请注意flatMap运算符的用法,该运算符用于将Observable转换为Observable

现在我们需要做的测试是确保将UserLocationDatasource返回的位置正确地提供给PlacesDatasource 。 为此,我们将使用一种称为spy的测试技术,该技术包括使用public变量创建PlacesDatasource协议的实现,该协议可用于检查方法是否被正确调用。

纬度和经度是间谍值

注意,我们也对该方法的返回值不感兴趣,因此我们只返回编译器接受的任何内容。

我还为UserLocationDatasource创建了一个模拟,然后我们可以轻松获取位置:

现在,我们拥有可以编写测试用例的所有内容:

按照计划,在此测试中,我们实例化了NearbyPlacesServices及其两个依赖关系,一个UserLocationService模拟始终返回相同的位置,一个PlacesDatasource模拟允许我们窥探先前发送的接收到的纬度和经度。 然后,断言仅确保纬度/经度具有相同的值。

我们可以学习如何收集数据来显示在我们的应用程序上,这些数据来自两个不同的来源,webservice和本地api也是依赖的。 选择的面向对象的体系结构使编写测试并使代码更健壮的可能性成为可能。