SwiftAPIClient

Group 3032 (3)

轻量级且简化的 API 客户端,使用 Swift 编写,并采用面向协议编程。您可以使用 async awaitCombine 发布器发送请求,而无需进行任何更改。SwiftAPIClient 可以帮助您仅用几行代码即可实现 HTTP 和服务器 API 调用。

HR Omni Solutions 开源

目录
使用 SPM 安装
使用枚举定义端点
使用结构体定义端点
解码 JSON 响应
使用 Combine 发送请求
使用 async 发送请求
响应验证
贡献

Swift Package Manager

Swift Package Manager 是一种用于自动化 Swift 代码分发的工具,并已集成到 swift 编译器中。

设置好 Swift 包后,将 SwiftAPIClient 添加为依赖项就像将其添加到 Package.swift 的 dependencies 值一样简单。

dependencies: [
    .package(url: "https://github.com/hromni/SwiftAPIClient.git", .upToNextMajor(from: "0.1"))
]

Cocoapods

pod 'HROmni.SwiftApiClient'

或者

pod 'HROmni.SwiftApiClient', :git => 'git@github.com:hromni/SwiftAPIClient.git'

使用枚举定义端点

import Foundation
import SwiftAPIClient

enum Endpoints: Endpoint {

    case getData, addData(_ name: String)

    var baseUrlString: String {  "https://example.com/" }

    var httpBody: RequestBody? {
        switch self {
        case .addData(let name):
            return .jsonDictionary(["name" : name])
        default: return nil
        }
    }

    var httpMethod: HTTPMethod {
        switch self {
        case .getData: return .get
        case .addData: return .post
        }
    }

    var path: String {
    // URL path should always start with forward slash
        switch self {
        case .getData:
            return "/getData"
        case .addData(let data):
            return "/addData"
        }
    }
    
}

使用 struct 的端点示例

struct GetDataEndpoint: Endpoint {
    var baseUrlString: String {  "https://example.com/" }
    // URL path should always start with forward slash
    var path: String { "/getData" }
}

解码 JSON 响应

如果您期望 JSON 响应,您可以使用 JsonResponse 协议,它是 Decodable 的包装器,并具有一些额外的内置功能。 您还可以通过遵循 Response 协议来创建自己的响应类型。

import Foundation
import SwiftAPIClient

struct ExampleDataResponse: JsonResponse {
   let name: String
}

使用 Combine 发送请求

使用端点创建带有 Combine 的客户端包装器

struct ApiClient {
    static func getData() -> AnyPublisher<ExampleDataResponse, SwiftApiClientError> {
        Endpoints.getData.send() 
        // GetDataEndpoint().send()
    }
}

使用 async 发送请求

正如前面提到的,该端点自动处理 Combineasync,因此您可以使用任何一种方法。例如,如果您想使用 async,您只需使用上述相同的 Endponts 定义将 send() 替换为 asyncSend() 即可

struct ApiClient {
    static func getData() async throws -> ExampleDataResponse {
        try await Endpoints.getData.asyncSend() 
        // try await GetDataEndpoint().asyncSend()
    }
}

验证响应

默认的验证器代码如下。

struct BasicResponseValidator: ResponseValidator {
    public func validate(_ response: (data: Data, response: URLResponse)) throws {
        if let statusCode = (response.response as? HTTPURLResponse)?.statusCode,
           statusCode >= 300 {
            throw SwiftApiClientError.serverError(statusCode: statusCode, payload: response.data)
        }
    }
}

您还可以通过遵循以下方式创建自己的验证器

public protocol ResponseValidator {
    func validate(_ response: (data: Data, response: URLResponse)) throws
}

然后将其作为验证器传递到您的端点,以替换默认的响应验证

贡献

欢迎贡献者。