测试已测试 | ✓ |
语言语言 | SwiftSwift |
许可 | MIT |
发布上次发布 | 2017年10月 |
SwiftSwift版本 | 3.0 |
SPM支持SPM | ✓ |
由Aryan Ghassemi维护。
Quick rest是一个简单的网络/映射库,允许您快速构建和连接到API。
让我们构建一个简单的网络层来从GitHub获取仓库。
我们首先创建模型。模型应该实现Deserializable
public struct Repository {
public let id: Int
public let nuame: String
public let description: String?
public let owner: Owner
public let language: Language?
}
extension Repository: Deserializable {
public init(json: [String : Any]) throws {
id = try json.readValue(key: "id")
nuame = try json.readValue(key: "name")
description = try? json.readValue(key: "description")
owner = try json.readDeserializable(key: "owner")
language = try? json.readEnum(key: "language")
}
}
public struct Owner {
public let id: Int
public let username: String
public let avatarUrl: String?
}
extension Owner: Deserializable {
public init(json: [String : Any]) throws {
id = try json.readValue(key: "id")
username = try json.readValue(key: "login")
avatarUrl = try? json.readValue(key: "avatar_url")
}
}
public enum Language: String {
case java = "Java"
case swift = "Swift"
case objectiveC = "Objective-C"
case Ruby = "Ruby"
}
接下来我们创建一个网络管理器类
public class NetworkManager {
private let networkService : NetworkService
public init() {
networkService = NetworkHttpService(
baseUrlString: "https://api.github.com/",
urlSession: URLSession.shared,
networkRequestInterceptor: nil,
timeout: 60)
}
@discardableResult public func fetchRepositories(username: String, completion: @escaping (NetworkResponse<[Repository]>)->Void) -> URLSessionTask {
return networkService.fetchObjects(
type: Repository.self,
path: "users/\(username)/repos",
completion: completion)
}
}
就这样。我们已经完成。现在我们使用网络管理器从GitHub获取对象
let networkManger = NetworkManager()
networkManger.fetchRepositories(username: "aryaxt") {
switch $0.result {
case .success(let repos):
print(repos)
case .failure(let error):
print(error)
}
}
有4种类型安全的方法可用于映射(在字典上扩展)
所有这些方法都可以用于可选值。为了映射可选值,只需使用try?
而不是try
映射方法 | 用法 |
---|---|
readValue | 用于映射可以直接从字典中设置值的任何字段(例如:String,Int,Double,字典,字符串数组,等) |
readDeserializable | 用于映射实现了Deserializable协议的模型 |
readDeserializableList | 用于映射实现了Deserializable协议的模型的数组 |
readEnum | 用于读取枚举。如果字典中的值与枚举的原始可表示值相同,它将被转换为枚举可表示的形式 |
NetworkHttpService
有两个方法用于触发API调用,fetchObject
和 fetchObjects
fetchObject
当根级别响应是一个字典且该字典直接映射到一个模型时使用。例如
networkService.fetchObject(type: User.self, path: "users/5", completion: completion)
{
"firstName" : "Aryan"
"lastName" : "Ghassemi"
}
fetchObjects
当API调用返回对象列表时使用。通常响应将是一个数组
networkService.fetchObjects(type: User.self, path: "users/search", completion: completion)
[{
"firstName" : "Aryan"
"lastName" : "Ghassemi"
}]
在某些情况下,响应被嵌套在字典中的另一个键中;可以使用unwrapKey直接将结果映射到数组,而不必创建一个模型来包装数组
networkService.fetchObjects(type: User.self, path: "users/search", unwrapKey: "results", completion: completion)
{"results" : [{
"firstName" : "Aryan"
"lastName" : "Ghassemi"
}]
}
#######获取原始数据
在某些情况下,您可能需要从API调用中获取原始json数据。
字典符合Deserializable,这意味着您可以将[String: Any]传递到fetchObject
和 fetchObjects
,完成回调将以类型Dictionary调用
在某些情况下,您可能需要修改请求。例如,传递一个自定义标题。您可以将实现了NetworkRequestInterceptor
的类/结构体传递到NetworkHttpService
。
public struct MyNetworkRequestInterceptor: NetworkRequestInterceptor {
public func inttercept(request: inout URLRequest) {
request.addValue("MyApp", forHTTPHeaderField: "User-Agent")
request.addValue("123123", forHTTPHeaderField: "Access-Token")
}
}
允许通过使它符合Deserializable来获取[String: Any]类型。
此功能将在下一个版本的Swift中提供
https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md