hyperspace
hyperspace 在 URLSession 和 HTTP 之上提供了一个简单的抽象。有几个主要目标
- 保持简单。
- 将库的整体大小保持在最小。当然,可能会有些样板代码(如
HTTP
定义),但我们的主要目标是保持库高度功能化和可维护,而不过度设计。 - 针对我们遇到的最常见的网络使用案例定制库。我们将继续根据所有我们构建的应用程序中的共同需求添加功能。
内容
- HTTP - 包含标准 HTTP 定义和类型。如果您觉得这里缺少某些内容,请提交 pull request。
- Request - 一个定义网络请求细节的结构,包括期望的结果和错误类型。这基本上是
URLRequest
的一个薄 wrapper,利用了HTTP
中的定义。 - TransportService - 使用
TransportSession
(默认为URLSession
)执行URLRequests
。处理原始HTTP
和Data
。 - BackendService - 使用
TransportService
执行Requests
。将TransportService
返回的原始Data
转换为由Request
定义的反应模型类型。这是您的应用将直接处理的 main worker 对象。
使用说明
1. 创建请求
创建请求时,您有多种选择。这些包括创建静态函数,以减少创建 Request
对象时的冗余,或者简单地本地创建。此外,如果您的网络请求比较复杂,您还可以创建自己的自定义结构体,将其封装并处理 Request
对象。
Request
选项 1 - 扩展 以下示例说明了如何创建一个 Request
的扩展,这可以显著减少创建类似在社交网络动态中创建新帖子时的请求的冗余。它利用了 Request
中的许多默认值(所有这些都是可定制的),以保持定义简洁。
extension Request where Response == Post {
static func createPost(_ post: NewPost) -> Request<Post> {
return Request(method: .post, url: URL(string: "https://jsonplaceholder.typicode.com/posts")!, headers: [.contentType: .applicationJSON], body: try? HTTP.Body.json(post))
}
}
Request
选项 2 - 在本地定义每个 let createPostRequest: Request<Post> = Request(method: .post, url: URL(string: "https://jsonplaceholder.typicode.com/posts")!, headers: [.contentType: .applicationJSON], body: try? HTTP.Body.json(post))
Request
的 CREATEPOSTREQUEST
选项 3 - 创建一个包装 struct CreatePostRequest {
let newPost: NewPost
var request: Request<Post> {
return Request(method: .post, url: URL(string: "https://jsonplaceholder.typicode.com/posts")!, headers: [.contentType: .applicationJSON], body: try? HTTP.Body.json(post))
}
}
对于上面的示例,Post
响应类型和 NewPost
身体定义如下
struct Post: Decodable {
let id: Int
let userId: Int
let title: String
let body: String
}
struct NewPost: Encodable {
let userId: Int
let title: String
let body: String
}
2. 创建请求默认值(可选)
为了避免在您的应用程序中为每个请求定义默认的 Request
属性值,利用 Hyperspace 提供的 RequestDefaults
可能很有用。甚至可以自定义这些
RequestDefaults.defaultCachePolicy = .reloadIgnoringLocalCacheData // Default cache policy is '.useProtocolCachePolicy'
RequestDefaults.defaultDecoder = MyCustomDecoder() // Default decoder is JSONDecoder()
3. 创建一个 BackendService 来执行您的请求
我们建议通过为与您的 API 每个部分进行通信的每个部分创建单独的“控制器”对象来遵守接口隔离原则。每个控制器应公开一组相关的函数,并使用 BackendService
来执行请求数据,然而,在这个简单的例子中,我们将直接在视图控制器上作为 private
属性使用 BackendService
class ViewController: UIViewController {
private let backendService = BackendService()
// Rest of your view controller code...
}
4. 实例化您的请求
假设一个视图控制器应该在用户点击“发送”按钮时创建帖子。下面是一个可能的实现
@IBAction private func sendButtonTapped(_ sender: UIButton) {
let title = ... // Get the title from a text view in the UI...
let message = ... // Get the message from a text view/field in the UI...
let post = NewPost(userId: 1, title: title, body: message)
let createPostRequest = CreatePostRequest(newPost: post)
// Execute the network request...
}
5. 使用 BackendService 执行请求
对于上面的示例,以下是执行请求和解析响应的方法。尽管所有数据转换都发生在底层 URLSession 所使用的后台队列上,但是所有 BackendService
完成回调发生在主队列上,因此你无需担心在更新 UI 之前线程问题。注意,以下成功响应关联值的类型是与上面定义的 CreatePostRequest
中的 Post
结构。
do {
let post = NewPost(userId: 1, title: title, body: "")
let createPostRequest = Request<Post>.createPost(post)
let createdPost = try await backendService.execute(request: createPostRequest)
// Insert the new post into the UI...
} catch {
// Alert the user to the error...
}
示例
克隆仓库
git clone https://github.com/BottleRocketStudios/iOS-Hyperspace.git
从这里,您可以打开 Hyperspace.xcworkspace
并运行示例
共享代码
Models.swift
,Requests.swift
- 示例间共享的模型和网络上请求。
示例目标
- Hyperspace-iOSExample
ViewController.swift
- 查看如何在您的 iOS 应用中使用此示例。
- Hyperspace-tvOSExample
ViewController.swift
- 查看如何在您的 tvOS 应用中使用此示例(这实际上与 iOS 示例相同)。
- Hyperspace-watchOSExample 扩展
InterfaceController.swift
- 查看您如何在您的watchOS应用中使用此代码的一个简化示例。
Playgrounds
- Playground/Hyperspace.playground
- 查看并运行一个定义模型、网络请求并在执行请求时类似上述示例目标的单个文件。
- Playground/Hyperspace_DELETE.playground
- 如何处理不返回结果的请求的示例。这通常在DELETE请求中很常见。
系统要求
- iOS 13.0+
- tvOS 13.0+
- watchOS 6.0+
- macOS 11+
- Swift 5.6
安装
Cocoapods
Hyperspace通过CocoaPods提供。要安装它,只需在Podfile中添加以下行:
pod 'Hyperspace'
Carthage
将以下内容添加到您的Cartfile
github "BottleRocketStudios/iOS-Hyperspace"
运行carthage update
,并按照Carthage的README中描述的步骤进行。
Swift 包管理器
dependencies: [
.package(url: "https://github.com/BottleRocketStudios/iOS-Hyperspace.git", from: "5.0.0")
]
作者
许可证
Hyperspace是在Apache 2.0许可证下可用的。有关更多信息,请参阅LICENSE.txt文件。
贡献
请参阅CONTRIBUTING文档。感谢贡献者!