first commit for e-party
This commit is contained in:
@@ -2,15 +2,49 @@ import Foundation
|
||||
import ComposableArchitecture
|
||||
|
||||
// MARK: - API Service Protocol
|
||||
|
||||
/// API 服务协议,定义了网络请求的核心接口
|
||||
///
|
||||
/// 该协议支持泛型请求,可以处理任何符合 `APIRequestProtocol` 的请求类型
|
||||
/// 并返回对应的响应类型。这种设计提供了类型安全和灵活性。
|
||||
///
|
||||
/// 使用示例:
|
||||
/// ```swift
|
||||
/// let apiService: APIServiceProtocol = LiveAPIService()
|
||||
/// let request = ConfigRequest()
|
||||
/// let response = try await apiService.request(request)
|
||||
/// ```
|
||||
protocol APIServiceProtocol {
|
||||
/// 发起网络请求
|
||||
/// - Parameter request: 符合 APIRequestProtocol 的请求对象
|
||||
/// - Returns: 请求对应的响应对象
|
||||
/// - Throws: APIError 或其他网络相关错误
|
||||
func request<T: APIRequestProtocol>(_ request: T) async throws -> T.Response
|
||||
}
|
||||
|
||||
// MARK: - Live API Service Implementation
|
||||
|
||||
/// 实际的 API 服务实现类
|
||||
///
|
||||
/// 该类负责处理真实的网络请求,包括:
|
||||
/// - URL 构建和参数处理
|
||||
/// - 请求头设置和认证
|
||||
/// - 请求体编码和签名生成
|
||||
/// - 响应解析和错误处理
|
||||
/// - 日志记录和性能监控
|
||||
///
|
||||
/// 特性:
|
||||
/// - 支持 GET/POST/PUT/DELETE 等 HTTP 方法
|
||||
/// - 自动添加基础参数和安全签名
|
||||
/// - 完整的错误处理和重试机制
|
||||
/// - 详细的请求/响应日志记录
|
||||
/// - 防止资源超限的保护机制
|
||||
struct LiveAPIService: APIServiceProtocol {
|
||||
private let session: URLSession
|
||||
private let baseURL: String
|
||||
|
||||
/// 初始化 API 服务
|
||||
/// - Parameter baseURL: API 服务器基础 URL,默认使用配置中的地址
|
||||
init(baseURL: String = APIConfiguration.baseURL) {
|
||||
self.baseURL = baseURL
|
||||
|
||||
@@ -27,6 +61,19 @@ struct LiveAPIService: APIServiceProtocol {
|
||||
self.session = URLSession(configuration: config)
|
||||
}
|
||||
|
||||
/// 发起网络请求的核心方法
|
||||
///
|
||||
/// 该方法处理完整的请求生命周期:
|
||||
/// 1. 构建请求 URL 和参数
|
||||
/// 2. 设置请求头和认证信息
|
||||
/// 3. 处理请求体和签名生成
|
||||
/// 4. 发起网络请求
|
||||
/// 5. 解析响应数据
|
||||
/// 6. 记录日志和性能指标
|
||||
///
|
||||
/// - Parameter request: 符合 APIRequestProtocol 的请求对象
|
||||
/// - Returns: 解析后的响应对象
|
||||
/// - Throws: APIError 包含详细的错误信息
|
||||
func request<T: APIRequestProtocol>(_ request: T) async throws -> T.Response {
|
||||
let startTime = Date()
|
||||
|
||||
@@ -57,7 +104,9 @@ struct LiveAPIService: APIServiceProtocol {
|
||||
// 如果需要包含基础参数,则合并
|
||||
var finalBody = bodyParams
|
||||
if request.includeBaseParameters {
|
||||
let baseParams = BaseRequest()
|
||||
var baseParams = BaseRequest()
|
||||
// 生成符合 API rule 的签名
|
||||
baseParams.generateSignature(with: bodyParams)
|
||||
let baseDict = try baseParams.toDictionary()
|
||||
finalBody.merge(baseDict) { existing, _ in existing }
|
||||
}
|
||||
@@ -129,6 +178,15 @@ struct LiveAPIService: APIServiceProtocol {
|
||||
|
||||
// MARK: - Private Helper Methods
|
||||
|
||||
/// 构建完整的请求 URL
|
||||
///
|
||||
/// 该方法负责:
|
||||
/// - 拼接基础 URL 和端点路径
|
||||
/// - 处理查询参数
|
||||
/// - 为 GET 请求添加基础参数和签名
|
||||
///
|
||||
/// - Parameter request: API 请求对象
|
||||
/// - Returns: 构建完成的 URL,如果构建失败则返回 nil
|
||||
private func buildURL<T: APIRequestProtocol>(for request: T) -> URL? {
|
||||
guard var urlComponents = URLComponents(string: baseURL + request.endpoint) else {
|
||||
return nil
|
||||
@@ -140,7 +198,10 @@ struct LiveAPIService: APIServiceProtocol {
|
||||
// 对于 GET 请求,将基础参数添加到查询参数中
|
||||
if request.method == .GET && request.includeBaseParameters {
|
||||
do {
|
||||
let baseParams = BaseRequest()
|
||||
var baseParams = BaseRequest()
|
||||
// 为 GET 请求生成签名(合并查询参数)
|
||||
let queryParamsDict = request.queryParameters ?? [:]
|
||||
baseParams.generateSignature(with: queryParamsDict)
|
||||
let baseDict = try baseParams.toDictionary()
|
||||
for (key, value) in baseDict {
|
||||
queryItems.append(URLQueryItem(name: key, value: "\(value)"))
|
||||
@@ -164,6 +225,12 @@ struct LiveAPIService: APIServiceProtocol {
|
||||
return urlComponents.url
|
||||
}
|
||||
|
||||
/// 从响应数据中提取错误消息
|
||||
///
|
||||
/// 尝试从 JSON 响应中提取错误信息,支持多种常见的错误字段格式
|
||||
///
|
||||
/// - Parameter data: 响应数据
|
||||
/// - Returns: 提取到的错误消息,如果没有找到则返回 nil
|
||||
private func extractErrorMessage(from data: Data) -> String? {
|
||||
guard let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
|
||||
return nil
|
||||
@@ -181,6 +248,13 @@ struct LiveAPIService: APIServiceProtocol {
|
||||
return nil
|
||||
}
|
||||
|
||||
/// 将系统错误映射为 API 错误
|
||||
///
|
||||
/// 将 URLError 等系统级错误转换为统一的 APIError 类型,
|
||||
/// 便于上层代码进行统一的错误处理
|
||||
///
|
||||
/// - Parameter error: 系统错误
|
||||
/// - Returns: 映射后的 APIError
|
||||
private func mapSystemError(_ error: Error) -> APIError {
|
||||
if let urlError = error as? URLError {
|
||||
switch urlError.code {
|
||||
@@ -200,6 +274,20 @@ struct LiveAPIService: APIServiceProtocol {
|
||||
}
|
||||
|
||||
// MARK: - Mock API Service (for testing)
|
||||
|
||||
/// 模拟 API 服务,用于测试和开发
|
||||
///
|
||||
/// 该类提供了一个可配置的模拟 API 服务,可以:
|
||||
/// - 设置预定义的响应数据
|
||||
/// - 模拟网络延迟
|
||||
/// - 用于单元测试和 UI 预览
|
||||
///
|
||||
/// 使用示例:
|
||||
/// ```swift
|
||||
/// var mockService = MockAPIService()
|
||||
/// mockService.setMockResponse(for: "/client/config", response: mockConfigResponse)
|
||||
/// let response = try await mockService.request(ConfigRequest())
|
||||
/// ```
|
||||
struct MockAPIService: APIServiceProtocol {
|
||||
private var mockResponses: [String: Any] = [:]
|
||||
|
||||
|
Reference in New Issue
Block a user