SimpleApiClient 0.1.0

SimpleApiClient 0.1.0

测试已测试
Lang语言 SwiftSwift
许可 MIT
发布最后发布2017年10月
SwiftSwift 版本4.0
SPM支持 SPM

Jay Chang 维护。



 
依赖
Alamofire~> 4.5
RxSwift~> 4.0
 

  • 作者
  • Jay Chang




基于 Alamofire4 和 RxSwift4 的 iOS 可配置 API 客户端

目录

安装

SimpleApiClient 可通过 CocoaPods 获取。要安装
它,只需在您的 Podfile 中添加以下行

pod 'SimpleApiClient'

基本使用

步骤 1

配置 API 客户端

let config = SimpleApiClient.Config(
baseUrl: "https://api.github.com",
defaultParameters: ["foo": "bar"],
defaultHeaders: ["foo": "bar"],
timeout: 120, // default is 60s
certificatePins: [
CertificatePin(hostname: "https://api.github.com", certificateUrl: Bundle.main.url(forResource: "serverCert", withExtension: "cer")!)
],
errorMessageKeyPath: "message",
jsonDecoder: JSONDecoder(),  // default is JSONDecoder()
isMockResponseEnabled: true, // default is false
logHandler: { request, response in
...
},
errorHandler: { error in
// you can centralize the handling of general error here
switch error {
case .authenticationError(let code, let message):
...
case .clientError(let code, let message):
...
case .serverError(let code, let message):
...
case .networkError(let source):
...
case .sslError(let source):
...
case .uncategorizedError(let source):
...
}
}
)

let githubClient = SimpleApiClient(config: config)

步骤 2

创建 API

import SimpleApiClient

struct GetRepoApi: SimpleApi {
let user: String
let repo: String

var path: String {
return "/repos/\(user)/\(repo)"
}

var method: HTTPMethod {
return .get
}

// optional
var parameters: Parameters {
return [:]
}

// optional
var headers: HTTPHeaders {
return [:]
}
}

extension SimpleApiClient {
func getRepo(user: String, repo: String) -> Observable<Repo> {
return request(api: GetRepoApi(user: user, repo: repo))
}
}

步骤 3

使用 observe() 来入队调用,在相应的参数块中执行您的事情。默认情况下,所有块都在主线程上运行,并且是可选的。

githubClient.getRepo(user: "foo", repo: "bar")
.observe(
onStart: { print("show loading") },
onEnd: { print("hide loading") },
onSuccess: { print("sucess: \($0)") },
onError: { print("error: \($0)" }
)

通过 KeyPath 解包响应

有时 API 响应包括我们不需要的元数据,但为了映射响应,我们创建一个包装类,并使函数返回该包装类。
这种做法将服务的实现泄漏给调用代码。

假设响应 JSON 看起来像以下这样

{
total_count: 33909,
incomplete_results: false,
foo: {
bar: {
items: [
{
login: "foo",
...
}
...
]
}
}
}

并且您只需要 items 部分,实现 Unwrappable 以指明您想要响应的哪个部分。

struct GetUsersApi: SimpleApi, Unwrappable {
...

var responseKeyPath: String {
return "foo.bar.items"
}
}

// then your response will be a list of User
extension SimpleApiClient {
func getUsers(query: String) -> Observable<[User]> {
return request(api: GetUsersApi(query: query))
}
}

上传文件

要上传文件,使 API 实现 Uploadable 以提供 Multipart

struct UploadImageApi: SimpleApi, Uploadable {
...

var multiParts: [MultiPart] {
let multiPart = MultiPart(data: UIImageJPEGRepresentation(image, 1)!, name: "imagefile", filename: "image.jpg", mimeType: "image/jpeg")
return [multiPart]
}
}

extension SimpleApiClient {
func uploadImage(image: UIImage) -> Observable<Image> {
return request(api: UploadImageApi(image))
}
}

串行/并行调用

串行

githubClient.foo()
.then { foo in githubClient.bar(foo.name) }
.observe(...)

串行然后并行

githubClient.foo()
.then { foo in githubClient.bar(foo.name) }
.thenAll { bar in
(githubClient.baz(bar.name), githubClient.qux(bar.name)) // return a tuple
}
.observe(...)

并行

SimpleApiClient.all(
githubApi.foo(),
githubApi.bar()
)
.observe(...)

并行然后串行

SimpleApiClient.all(
githubApi.foo(),
githubApi.bar()
).then { array -> // the return type is Array<Any>, you should cast them, e.g. let foo = array[0] as! Foo
githubApi.baz()
}.observe(...)

重试间隔/指数退避

githubClient.getUsers("foo")
.retry(delay: 5, maxRetryCount: 3) // retry up to 3 times, each time delays 5 seconds
.retry(exponentialDelay: 5, maxRetryCount: 3) // retry up to 3 times, each time delays 5^n seconds, where n = {1,2,3}
.observe(...)

调用取消

自动调用取消

当对象被注销时,将取消调用。

githubClient.getUsers("foo")
.cancel(when: self.rx.deallocated)
.observe(...)

手动取消调用

let call = githubClient.getUsers("foo").observe(...)

call.cancel()

模拟响应

要启用响应模拟,将 SimpleApiClient.Config.isMockResponseEnabled 设置为 true,并使 API 实现 Mockable 以提供 MockResponse.

模拟示例 JSON 数据

要使 API 返回一个包含提供 JSON 的成功响应

struct GetUsersApi: SimpleApi, Mockable {
...

var mockResponse: MockResponse {
let file = Bundle.main.url(forResource: "get_users", withExtension: "json")!
return MockResponse(jsonFile: file)
}
}

模拟状态

要使 API 返回一个包含提供 JSON 的客户端错误

struct GetUsersApi: SimpleApi, Mockable {
...

var mockResponse: MockResponse {
let file = Bundle.main.url(forResource: "get_users_error", withExtension: "json")!
return MockResponse(jsonFile: file, status: .clientError)
}
}

MockResponsejsonFile 参数是可选的,您可以仅设置状态,然后您会收到空字符串。

可能的 Status

public enum Status {
case success
case authenticationError
case clientError
case serverError
case networkError
case sslError
}

要只模拟成功状态响应,应返回 Observable.

struct DeleteRepoApi: SimpleApi, Mockable {
...

var mockResponse: MockResponse {
return MockResponse(status: .success)
}
}

extension SimpleApiClient {
func deleteRepo(id: String) -> Observable<Nothing> {
return request(api: DeleteRepoApi(id: id))
}
}

作者

jaychang0917, [email protected]

许可

SimpleApiClient 在 MIT 许可下可用。有关更多信息,请参阅 LICENSE 文件。