测试测试 | ✗ |
语言语言 | SwiftSwift |
许可证 | MIT |
发布最后发布 | 2017年7月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✗ |
由Daniel Li维护。
依赖项 | |
Alamofire | >= 0 |
SwiftyJSON | >= 0 |
PromiseKit/Alamofire | >= 0 |
使用承诺进行协程的 Swift 网络功能
中子是围绕 Alamofire 的包装,它推广了面向协议的 Swift 网络功能。
Swift 中的网络通常涉及在一个名为“网络管理器”的类中的冗长而长时间存在的静态函数列表,每个函数都重复调用其他函数。更糟糕的是,每个请求的信息经常散布在各个地方(路由可能在一个枚举中,参数键可能在另一个中等等)。有了中子,您可以在名为 Quarks 的结构中定义请求
定义一个 Quark
struct Login: Quark {
typealias ResponseType = User
let username: String, password: String
let route = "/login"
var parameters: Parameters = [
return [
"user": username,
"pass": password
]
]
func process(response: Data) throws -> User {
let user = ...
return user
}
}
形成和发送请求
Login(username: "user", password: "****").make()
.then { user in
print("Got user:", user)
}
.catch { error in
print(error)
}
就是这样。由于 Quark 是一个协议,结构体和承诺(请参阅 PromiseKit)使其能够轻松定义、形成和发送网络请求。除了默认请求数据之外,关于请求的所有信息都包含在结构体中。
最终,中子通过以下方式改进了传统的网络管理范式:
Quark 是一个符合 Quark
协议的结构体或从它继承的协议
import Neutron
struct MyQuark: Quark {
<response type>
<properties>
<process method>
}
这里有三个部分,其顺序并不重要
在结构体中,您应提供一个到 ResponseType
的 typealias,指定您最终期望返回什么类型的响应
typealias ResponseType = MyModelClass
这将是要返回的类型,如上所述,Promise 将返回该类型。
列出您的请求所需的属性,注意不要覆盖下面的协议属性。Swift 自动为这些未初始化的属性生成初始化器。例如,更新待办事项列表中的待办事项名称可能需要一个 id 和标题
let id: Int
let title: String
或
let id: Int, title: String
使用这些属性来生成以下协议属性之一以形成请求
主机: String
(默认为“https://”)
路由: String
(没有默认值 - 必须有)
apiVersion: APIVersion
(默认为 .none
)
parameters: Parameters
(默认为 [:]
)
encoding: ParameterEncoding
(默认为 URLEncoding.default
)
headers: HTTPHeaders
(默认为 [:]
)
如果属性有默认值,则在定义请求时应该省略该属性。要使用您自己的属性进行请求,您需要使用计算变量
var route: String {
return "/todo/\(id)" // id defined earlier
}
var parameters: Parameters = [
return [
"title": title // title defined earlier
]
]
将其他静态属性定义为 let
属性就足够了。请注意,如果您未初始化所需协议属性,它们将在生成的初始化器中显示。
最后,实现所需的 func process(response: Data) throws -> ResponseType
函数。当网络请求成功时,将调用此方法,以便将响应对象转换为之前定义的 ResponseType
。由于响应数据可能不符合客户端应用程序的期望,因此这是一个会抛出异常的方法。
在待办事项重命名示例中,如果服务器返回一个新的待办事项的 JSON,我们可以编写这样的 process
方法,使用 SwiftyJSON
func process(response: Data) throws -> Todo {
let json = JSON(data) // unnecessary, see 'Custom Quarks'
guard let id: Int = json["id"].int,
let title: String = json["title"].string else {
throw NeutronError.badResponseData // throw error if unexpected data
}
return Todo(id: id, title: title, ... )
}
发出请求就像调用 Swift 生成的“全体成员”初始化器一样简单
RenameTodo(id: id, title: title)
由于请求是结构体,因此它们是可存储的、可复制的和可修改的
let renameRequest = RenameTodo(id: id, title: title)
let copy = renameRequest
最后,您只需发起请求。在请求上调用 make
函数,该函数返回一个 PromiseKit 许诺,并相应地处理它
RenameTodo(id: id, title: title).make()
.then { todo in
// use updated todo
print(todo)
}
.catch { error in
// catch any error that occurred
print(error.localizedDescription)
}
可能让人担心的是,请求数的默认主机为 localhost
,以及 process
方法有一个 Data
类型的参数,而不是类似 JSON
的东西。这正是协议可组合性的地方!
您可以使用 JSONQuark
协议来进行肯定会返回 SwiftyJSON JSON 的请求。通过 JSONQuark
,process
方法中的 response
参数类型为 JSON
而不是 Data
。
当您创建继承自 Quark
或其子协议(如 JSONQuark
)的协议时,可以提供您自己的协议要求和不带参数的实现
protocol TodoQuark: Quark {
var authToken: String { get } // every request should provide one
}
extension TodoQuark { // custom default implementations
var host: String {
return "https://my.todo.list.server"
}
var headers: HTTPHeaders = [
"auth": authToken
]
}
漂亮,不是吗?
如果我们选择,请求可以作为 RESTful 资源请求嵌套在我们的模型中
class BlogPost { ... }
extension BlogPost {
struct Get: Quark { ... }
struct Post: Quark { ... }
struct Delete: Quark { ... }
}
// Later...
BlogPost.Get(...)
BlogPost.Post(...)
BlogPost.Delete(...)
要运行示例项目,请先从 GitHub 克隆存储库,然后在示例目录中运行 pod install
。
需要 Swift 3.0 或更高版本
Neutron 可以通过 CocoaPods 获取。为了安装它,只需将以下行添加到您的 Podfile 中
pod "Neutron"
这是一个非常年轻的项目,所以请原谅它的混乱和/或缺少功能。话说回来,任何贡献者都会是受欢迎的!
李丹尼尔,[email protected]
Neutron可在MIT许可证下使用。有关更多信息,请参阅LICENSE文件。