EZNetworking 是一个 Swift 包,旨在简化您的 iOS 和 macOS 应用程序中的网络请求和 API 交互。 它提供了一个干净且易于使用的 URLSession
抽象层,用于处理 HTTP 请求、响应解码和错误处理。
APIRequest
和 HTTPDownloader
等协议来创建可自定义的网络请求和响应。JSONDecoder
来处理各种解码策略。actor
模型来安全地管理并发网络请求。要使用 Swift Package Manager 将 EZNetworking 集成到您的项目中,请在您的 Package.swift
文件中添加以下依赖项
dependencies: [
.package(url: "https://github.com/yourusername/EZNetworking.git", from: "1.5.1")
]
Client actor(客户端 Actor)是发出网络请求的主要组件。 您可以使用您自己的 HTTPDownloader
和 JSONDecoder
自定义它,如果需要的话。
import EZNetworking
let client = Client()
或使用自定义配置
let customDecoder = JSONDecoder()
customDecoder.dateDecodingStrategy = .iso8601
let client = Client(decoder: customDecoder)
使用 GenericAPIRequest
创建请求
let url = "https://randomuser.me"
let path = "/api/"
let request = GenericAPIRequest<User>(baseURL: url, path: path)
使用 Client
从 API 获取数据
Task {
do {
let user = try await client.fetchData(from: request)
print(user.results.first?.name.first ?? "No name")
} catch {
print("Failed to fetch data: \(error.localizedDescription)")
}
}
如果您的 API 需要 API 密钥,您可以将其包含在请求的 headers(头部)中
let url = "https://api.example.com"
let path = "/data"
let headers = ["Authorization": "Bearer YOUR_API_KEY"]
let request = GenericAPIRequest<MyDataModel>(
baseURL: url,
path: path,
headers: headers
)
如果您需要在 API 请求中包含 query parameters(查询参数),您可以使用 queryItems 属性
let url = "https://api.example.com"
let path = "/search"
let queryItems = [
URLQueryItem(name: "query", value: "Swift"),
URLQueryItem(name: "limit", value: "10")
]
let request = GenericAPIRequest<MySearchResults>(
baseURL: url,
path: path,
queryItems: queryItems
)
EZNetworking 通过 APIError
枚举提供详细的错误处理
enum APIError: Error, LocalizedError {
case invalidURL
case httpStatusCodeFailed(statusCode: Int, description: String)
case decodingError(underlyingError: Error)
case networkError
case unknownError
var errorDescription: String? {
switch self {
case .invalidURL:
return "The URL provided was invalid."
case .httpStatusCodeFailed(let statusCode, let description):
return "HTTP request failed with status code \(statusCode): \(description)."
case .decodingError(let underlyingError):
return "Failed to decode the response: \(underlyingError)."
case .networkError:
return "There was a network error."
case .unknownError:
return "An unknown error has occurred."
}
}
}
EZNetworking 包含一个简单的测试设置来模拟网络响应
import Testing
@testable import EZNetworking
final class Downloader: HTTPDownloader {
func httpData(from url: URL) async throws -> Data {
try await Task.sleep(nanoseconds: UInt64.random(in: 100_000_000...500_000_000))
return testUser
}
@Test
func testClientDoesFetchUserData() async throws {
let downloader = Downloader()
let client = Client(downloader: downloader)
let request = GenericAPIRequest<User>(baseURL: "https://randomuser.me", path: "/api/")
let user = try await client.fetchData(from: request)
#expect(user.results.count == 1)
}
}
欢迎贡献! 请随时提交 pull request(拉取请求)或打开 issue(议题)以帮助改进 EZNetworking。