这个软件包包含一个微型的网络库。它提供了一个结构体 Endpoint
,它结合了 URL 请求和解析该请求响应的方法。因为 Endpoint
对解析结果是泛型的,所以它提供了一种类型安全的方式来使用 HTTP 端点。
这里有一些例子
这是一个代表用户数据的端点 (请注意,JSON 中还有更多字段,为了简洁起见已省略)
struct User: Codable {
var name: String
var location: String?
}
func userInfo(login: String) -> Endpoint<User> {
return Endpoint(json: .get, url: URL(string: "https://api.github.com/users/\(login)")!)
}
let sample = userInfo(login: "objcio")
上面的代码只是一个端点的描述,它不会加载任何东西。 sample
是一个简单的结构体,你可以检查它(例如,在单元测试中)。
这是如何加载一个端点的方法。 result
的类型是 Result<User, Error>
。
URLSession.shared.load(endpoint) { result in
print(result)
}
或者,你可以使用 async/await 选项。
let result = try await URLSession.shared.load(endpoint)
这是一个关于如何拥有身份验证端点的例子。你使用 API 密钥初始化 Mailchimp
结构体,并使用它来计算 authHeader
。然后,在创建端点时,你可以使用 authHeader
。
struct Mailchimp {
let base = URL(string: "https://us7.api.mailchimp.com/3.0/")!
var apiKey = env.mailchimpApiKey
var authHeader: [String: String] {
["Authorization": "Basic " + "anystring:\(apiKey)".base64Encoded]
}
func addContent(for episode: Episode, toCampaign campaignId: String) -> Endpoint<()> {
struct Edit: Codable {
var plain_text: String
var html: String
}
let body = Edit(plain_text: plainText(episode), html: html(episode))
let url = base.appendingPathComponent("campaigns/\(campaignId)/content")
return Endpoint<()>(json: .put, url: url, body: body, headers: authHeader)
}
}
JSON 编码和解码作为条件扩展添加到 Codable 基础设施之上。然而,Endpoint
本身与此完全无关。这是解析函数的类型
var parse: (Data?, URLResponse?) -> Result<A, Error>
将 Data
作为输入意味着你可以在其之上编写自己的功能。例如,这是一个解析图像的资源
struct ImageError: Error {}
extension Endpoint where A == UIImage {
init(imageURL: URL) {
self = Endpoint(.get, url: imageURL) { data in
Result {
guard let d = data, let i = UIImage(data: d) else { throw ImageError() }
return i
}
}
}
}
你还可以编写执行自定义 JSON 序列化、解析 XML 或其他格式的扩展。
因为 Endpoint
是一个简单的结构体,所以很容易在没有网络连接的情况下同步测试。例如,你可以像这样测试图像端点
XCTAssertThrows(try Endpoint(imageURL: someURL).parse(nil, nil).get())
XCTAssertThrows(try Endpoint(imageURL: someURL).parse(invalidData, nil).get())
XCTAssertNoThrow(try Endpoint(imageURL: someURL).parse(validData, nil).get())
Hsieh Min Che 创建了一个库,为这个库添加了 Combine 端点: https://github.com/Hsieh-1989/CombinedEndpoint
这个库的设计和实现已经在 Swift Talk 上进行了广泛的介绍。 还有一个包含所有相关节目的合集。