测试已测试 | ✓ |
语言语言 | SwiftSwift |
许可证 | MIT |
发布最后发布 | 2017年4月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✓ |
由 Evan Liu 维护。
依赖项 | |
Alamofire | ~> 4.4 |
Result | ~> 3.2 |
WebAPIKit 是一个用于构建网络 API 客户端的网络抽象层。
final class GitHubAPI: WebAPIProvider {
let baseURL = URL(string: "https://api.github.com")!
func getUser(login: String, handler: @escaping ResultHandler) {
makeRequest(path: "/users/\(login)").send(handler: handler)
}
}
GitHubAPI().getUser(login: "WebAPIKit") {
if case .success(let response) = $0, response.status.isSuccess {
// Read from response.data and/or response.headers
}
}
(此处使用 Marshal 进行 json 解析,但您可以选择任何库)
struct User: ResponseJSONData {
var login: String
var name: String?
init(json: [String: Any]) throws {
login = try json.value(for: "login")
name = try json.value(for: "name")
}
}
extension GitHubAPI {
func getUser(login: String, handler: @escaping (Result<User, WebAPIError>) -> Void) {
makeRequest(path: "/users/\(login)").sendAndDecode(handler: handler)
}
}
GitHubAPI().getUser(login: "WebAPIKit") {
if case .success(let user) = $0 {
// user is of type User
}
}
final class GitHubAPI: WebAPIProvider {
let baseURL = URL(string: "https://api.github.com")!
let plugins = PluginHub()
.addRequestProcessor(RequestHeaderSetter(key: .accept, value: "application/vnd.github.v3+json"))
.addResponseProcessor(ResponseStatusValidator())
}
请求也可以有自己的插件
extension GitHubAPI {
func getUser(login: String, handler: @escaping ResultHandler) {
makeRequest(path: "/users/\(login)").addPlugin(MyRequestHook()).send(handler: handler)
}
}
final class MyServerAPI: WebAPIProvider {
let baseURL = URL(string: "https://my-server.com/api/v1")!
let requireAuthentication = true
var authentication: WebAPIAuthentication = NoneAuthentication()
}
class MyLoginController {
func login(user: String, password: String) {
myServer.authentication = BasicAuthentication(user: user, password: password)
}
}
如果 requireAuthentication
为 true 但没有有效的认证,请求将不会发送。但有些端点可能不需要认证。
extension MyServerAPI {
func sayHi(message: String, handler: @escaping ResultHandler) {
makeRequest(path: "/hi", method: .post)
.addParameter(key: "message", value: message)
.setRequireAuthentication(false)
.send(handler: handler)
}
}
final class GitHubAPI: StubbableProvider {
let baseURL = URL(string: "https://api.github.com")!
var httpClient: HTTPClient? // Use Alamofire.SessionManager.default if not defined
}
// Stub for development
class SomeBusyClass {
fucn someMethod() {
let client = gitHub.stubClient()
client.stub(path: "/users", method: .post).withStatus(.code201)
client.stub(template: "/users/{login}").withTemplatedJSON { ["login": $0["login"]!, "name": "User"] }
client.stub().withStatus(.code404) // All other requests will fail with 404
}
}
// Stub for testing
class SomeTestCase {
func testSomeMethod() {
// ... After stub setup
client.stub(path: "/users").withJSON([["login": "test", "name": "Tester"]])
client.stub(path: "/users", method: .post).withStatus(.code201).withMode(.manual)
// ... After some method calls
XCTAssertTrue(client.hasConnection)
client.lastConnection!.respond() // For POST /users. GET /users will respond with json data automatically
// ... Verify success behaviour
XCTAssertFalse(client.hasActiveConnection) // No connection that is not yet responded to or canceled
}
}
extension GitHubAPI {
func getUser(login: String, handler: @escaping ResultHandler) -> Cancelable {
return makeRequest(path: "/users/\(login)").send(handler: handler)
}
}
class SomeClass {
func someMethod() {
let connection = gitHub.getUser(login: "WebAPIKit") { ... }
// No longer needed now
connection.cancel()
}
}
WebAPIKit 仍在开发中。
发布前
未来版本(或扩展库)