Netswift 0.3.0

Netswift 0.3.0

Dorian Grolaux 维护。



Netswift 0.3.0

  • 作者:
  • Dorian Grolaux

Netswift

Build Status Version License Platform Swift Package Manager

是什么

这个库负责处理在 Swift 应用中创建可重用和可维护的网络层所需的重型工作。目前,它允许您以非常结构化和类型安全的方式轻易编写网络调用。它通过广泛使用关联类型和泛型类和结构体来实现。

为什么

Swift 中的网络可能从一开始就是一件繁杂的事情。为了快速入门,常常会忽略类型安全和可重用性。这正是 Netswift 突显其优势的地方!

在过去几年中,我的团队和我在执行网络请求时遇到了 spaghetti 代码和难以维护的代码库。由于 API 调用的特性,很难找到一个同时满足大多数需求、同时又灵活和未来的解决方案。

因此,为了提高我的 Swift 技能并摆脱困境,我自主研发了一个解决方案,以期缓解这些痛苦点。

本框架深受 John Sundell 和 Ray Wenderlich 撰写的博客文章的启发。我强烈推荐他们,如果您需要学习和提高编程技能的话!。

使用 Netswift

先决条件

我假设你已经构建了一个带有此 cocoapod 的 iOS 项目并准备好使用。如果没有,请按照安装步骤进行操作。

编写我们的第一次请求

像所有值得一读的教程一样,以下步骤将帮助您设置第一个Hello World请求。

我们将做什么

  • 步骤 1:定义一个容器,该容器将作为我们的API实现的基类。
  • 步骤 2:实现 NetswiftRoute,定义端点的不同 URLComponents
  • 步骤 3:实现 NetswiftRequest,定义如何将容器转换为 URLRequest
  • 步骤 4:传递一切给通用的 Netswift 类并发出第一个请求🙌
  • 步骤 5: ????
  • 步骤 6: 利润👍

端点

为方便本教程,我已经为您设置了一个模拟API以供查询。它只有一个端点,返回一个包含标题的单个对象。 试试看

步骤 1

在这个特定的情况下,为了保持简单,我们可以定义一个新的 `enum`。我们将使用它来实施所需的最小协议功能,这样我们就可以执行我们的请求。

所以继续吧;为您的项目添加一个新文件,命名方式由你决定。我选择了 `MyAPI`。然后,别忘了导入 `Netswift`,并像这样创建您的 API 容器

import Netswift

enum MyAPI {
  case helloWorld
}

就这样了。现在,由于我们的 API 只有一个端点,实际上没有更多的事情要做。Swift 的 `enum` 的好处是它们还可以有关联值。这在您需要将额外的数据传递到端点时非常有用,同时保持类型安全和结构化。很棒👌

步骤 2

所以我们有我们的 `enum`。很好。但它并没有做什么。让我们来解决这个问题。

继续为它定义一个扩展,实现 `NetswiftRoute 协议

extension MyAPI: NetswiftRoute {
}

立即可见地,编译器开始抱怨。按'添加协议存根'会使其高兴起来。这将添加两个变量

  • host:这定义了我们的 API 域名,通常是像www.example.com这样的东西。
  • path:我们的 API 上的特定资源。除非你只是 GET 网站的话,你将需要定义一个路径。

让我们继续实现这两个。

var host: String {
  return "my-json-server.typicode.com"
}

var path: String {
  switch self {
    case .helloWorld: return "MrSkwiggs/Netswift-HelloWorld/Netswift"
  }
}

我们刚才做了什么?

我们的容器是一个 `enum`,这意味着我们可以很容易地为每个情况定义不同的返回值。对于 `host`,我们始终希望返回相同的值。

然而,对于 `path`,我们正在利用这一特性。我们以未来兼容的方式设置了它,这样我们就可以总是添加路径(作为新的 `enum` 案例)。当到了那个时刻,编译器将警告我们没有处理我们 `enum` 的所有情况。👍

现在我们需要的就这些了。默认情况下,后台已经完成了大量工作;我们总是可以定义更多信息,例如方案(http 或 https),并且在需要时查询它,但在这个教程的上下文中,我们可以直接跳过!

步骤 3

现在我们已经设置了路由,所有我们需要的只是实现 `NetswiftRequest` 协议。让我们在另一个扩展中这样做

extension MyAPI: NetswiftRequest {
}

这次,我们不想让编译器立即为我们添加协议存根。在我们这么做之前,让我先解释一下我们需要向 Netswift 提供哪些其他信息;

  • 一个 Response 类型。由于 Netswift 是泛型的,它不知道我们希望从我们的 API 端点获得什么类型的数据。如果我们的请求定义了一个名为 Response 的类型,那么我们就万事俱备了。最好的部分是,我们还可以使用一个 typealias,它仍然能够正常工作👍

所以现在,让我们在我们的扩展中添加一个名为 Response 的内部类型

struct Response: Decodable {
  let title: String
}

再次,我们刚才写了什么?

首先,我们定义了一个模拟端点响应结构的类型。也就是说,一个包含名为 title 的成员的对象,其类型为 String

接着,我们告诉编译器我们的 Response 类型实现了 Decodable 协议。 Netswift 使用 Swift 的泛型 JSONDecoder。这一切默认都由默认实现背后完成。

然而,编译器仍然不快乐。现在是时候让它 '添加协议存根' 了。现在,我们获得了一个名为 serialise 的新函数。这是我们在准备好之前需要定义的最后一部分。

那么,让我们来实现我们的 URLRequest 序列化,好吗?

func serialise(_ handler: @escaping NetswiftHandler<URLRequest>) {
  handler(.success(URLRequest(url: self.url)))
}

好吧,这一切都是什么意思?换句话说,serialise 函数让 Netswift 获取一个可用的、它可以发送的 URLRequest。由于我们的实现很简单,所以我们只需要使用给定的 URL 实例化一个 URLRequest。但等等。哪里来的 self.url

这个便利计算属性来自 NetswiftRoute 协议。它所做的只是将所有已定义的 URLComponents 格式化为一个 String,然后使用它来实例化和返回一个 URL 对象。

同样,这里有大量的默认实现,但你只需要知道的是,对于我们的 .helloWorld 当前案例,self.url 将使用 <scheme><host>/<path><query>

太好了,现在我们差不多做完了!

第 4 步

现在是我们等待已久的时刻:发送我们的请求!

我们所需要做的就是实际执行我们的请求。要这样做,我们可以使用 Netswift 的默认类的一个实例。我们只需要调用这个

Netswift().perform(MyAPI.helloWorld) { result in
  switch result {
  case .failure(let error):
    // Our request failed: we can use the error to debug it
    print(error)
    
  case .success(let value):
    // Our request succeeded: we now have an object of type MyAPI.Response available to use
    print(value.title)
  }
}

这就完成了我们的第一个 Netswift 请求!从这里,你可以进一步扩展并开始定义更复杂的要求。我还建议阅读文档,并覆盖默认实现,以便了解这个库真正可以达到什么效果👌

示例项目

要运行示例项目,请先克隆存储库,然后从 Example 目录运行 pod install。它包含了上述教程的全部实现以及一些其他示例。

安装

Netswift 可以通过以下方式获取

  • CocoaPods:要安装它,只需将以下行添加到您的 Podfile
pod 'Netswift'

作者

Dorian Grolauxhttps://skwiggs.dev

许可证

Netswift 在 MIT 许可证下提供。有关更多信息,请参阅 LICENSE 文件。