CI iOS macOS

Wheel

又一个轮子。重新发明。

一个现代、轻量级(实际上只有两个方法)的 Swift 网络层,使用 async-await。

特性

{
  "error": "Your Server Error Message",
  "domainCode": Your custom domain error code(Int)
}

安装

Swift Package Manager

您可以使用 Swift Package Manager 安装 Wheel,方法是将以下行添加到您的 Package.swift 文件中

dependencies: [
    .package(url: "https://github.com/swiftDevelopmentPackages/wheel.git", from: "1.0.0")
]

然后,将 wheel 添加到您的目标依赖项中

targets: [
    .target(name: "YourTarget", dependencies: ["wheel"]),
]

或者,只需使用 XCode 的包依赖项选项卡添加即可。

用法

使用 Wheel 非常简单,因为它具有内置接口。

public protocol HTTPServing {
  func request<T: Decodable>(authenticated: Bool, requestConfig: ConfigRequestConvertible) async throws -> T
  func request(authenticated: Bool, requestConfig: ConfigRequestConvertible) async throws
}

实际上只有两种方法可以执行请求 🚀

创建 HTTPService

首先,您需要创建 HTTPService 的实例。您可以通过将所需的依赖项传递给其初始化器来完成此操作

let tokenRefresher = YourTokenRefresher() // Your implementation of TokenRefreshing
let tokenStorage = YourTokenStorage() // Your implementation of TokenStoring
let commonHeaders = ["Custom-Header": "CustomValue"] // Your domain specific custom headers you want to append to every request. Content-Type, Authorization etc. is added automatically

let httpService = HTTPService(tokenRefresher: tokenRefresher,
                              tokenStorage: tokenStorage,
                              commonHeaders: commonHeaders)

创建 ConfigRequestConvertible

ConfigRequestConvertible 协议用于配置 HTTP 请求。您需要为您要发出的每种类型的请求创建一个符合此协议的类型。

这是一个 ConfigRequestConvertible 的示例,用于获取用户的 GET 请求

enum YourRequestConfig: ConfigRequestConvertible {
    case useCaseOne
    case useCaseTwo

    var baseURL: URL {
      URL(string: yourAPIBaseURL)!
    }

    var path: String {
      switch self {
      case .useCaseOne:
        return "useCaseOnePath"
      case .useCaseTwo:
        return "useCaseTwoPath"
      }
    }

    var method: HTTPMethod {
      switch self {
      case .useCaseOne:
        return .GET
      case .useCaseTwo:
        return .POST
      }
    }

    var parameters: [String: Any] {
      return [:] // your urlParams or request body
    }

    var headers: [String : String]? {
      return [:] // your endpoint specific headers
    }
  }

可解码请求,已认证/未认证

struct User: Decodable {
  let id: Int
  let name: String
  // other properties...
}

do {
  let user: User = try await httpService.request(authenticated: true, requestConfig: YourRequestConfig().useCaseOne)
  print("Received user: \(user)")
} catch {
  print("Failed to fetch user: \(error)")
}

在此示例中,User 是一个表示用户的 Decodable 结构体。YourRequestConfig 是一个 ConfigRequestConvertible,它配置一个 GET 请求以获取用户。authenticated: true 假设您的 TokenRefreshing 可注入对象持有一个有效的 accessToken & refreshToken 对,如果不是,则尝试刷新或使其失效。

Void 请求,已认证/未认证

do {
  try await httpService.request(authenticated: false, requestConfig: YourRequestConfig().useCasetTwo)
  print("User updated successfully.")
} catch {
  print("Failed to update user: \(error)")
}

在此示例中,YourRequestConfig 是一个 ConfigRequestConvertible,它配置一个 PUT 请求以更新用户。由于响应不需要解码为模型,因此请求方法的返回类型为 Voidauthenticated: Bool 的相同规则适用于上一个示例。