Files
e-party-iOS/yana/APIs/Integration-Guide.md
edwinQQQ 007c10daaf feat: 添加Swift Package管理和API功能模块
新增Package.swift和Package.resolved文件以支持Swift Package管理,创建API相关文件(API.swift、APICaller.swift、APIConstants.swift、APIEndpoints.swift、APIService.swift、APILogger.swift、APIModels.swift、Integration-Guide.md)以实现API请求管理和网络交互功能,增强项目的功能性和可扩展性。同时更新.gitignore以排除构建文件和临时文件。
2025-06-04 17:25:21 +08:00

4.9 KiB
Raw Permalink Blame History

APIClient 集成指南

🔧 在其他文件中使用 APIClient

方法一:直接实例化 (推荐用于测试)

import SwiftUI

struct ContentView: View {
    @State private var isLoading = false
    @State private var result = ""
    
    var body: some View {
        VStack {
            Button("测试 API") {
                testAPI()
            }
            .disabled(isLoading)
            
            if isLoading {
                ProgressView("请求中...")
            }
            
            Text(result)
        }
    }
    
    private func testAPI() {
        isLoading = true
        
        Task {
            do {
                // 创建 API 客户端实例
                let apiClient = LiveAPIClient(
                    baseURL: URL(string: "https://your-api.com")!
                )
                
                // 发起请求
                let response: YourResponseModel = try await apiClient.get(
                    path: "/your/endpoint",
                    queryParameters: ["key": "value"]
                )
                
                await MainActor.run {
                    result = "成功: \(response)"
                    isLoading = false
                }
                
            } catch {
                await MainActor.run {
                    result = "错误: \(error.localizedDescription)"
                    isLoading = false
                }
            }
        }
    }
}

方法二:使用单例模式

// 在需要使用的文件中
private func makeAPIRequest() async {
    do {
        let response: SomeModel = try await APIClientManager.shared.get(
            path: "/endpoint"
        )
        // 处理响应
    } catch {
        // 处理错误
    }
}

方法三TCA 集成 (当 TCA 可用时)

import ComposableArchitecture

@Reducer
struct MyFeature {
    @ObservableState
    struct State: Equatable {
        var data: [Item] = []
        var isLoading = false
    }
    
    enum Action: Equatable {
        case loadData
        case dataLoaded([Item])
        case loadingFailed(String)
    }
    
    @Dependency(\.apiClient) var apiClient
    
    var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .loadData:
                state.isLoading = true
                
                return .run { send in
                    do {
                        let items: [Item] = try await apiClient.get(path: "/items")
                        await send(.dataLoaded(items))
                    } catch {
                        await send(.loadingFailed(error.localizedDescription))
                    }
                }
                
            case let .dataLoaded(items):
                state.isLoading = false
                state.data = items
                return .none
                
            case let .loadingFailed(error):
                state.isLoading = false
                // 处理错误
                return .none
            }
        }
    }
}

🚨 常见问题解决

1. "Cannot find 'APIClientManager' in scope"

原因: Swift 模块系统问题,需要确保正确导入

解决方案:

// 方案 A: 直接实例化
let apiClient = LiveAPIClient(baseURL: URL(string: "https://api.com")!)

// 方案 B: 确保文件在同一个 target 中
// 检查 Xcode 项目设置,确保 APICaller.swift 和使用文件在同一个 target

// 方案 C: 使用原生 URLSession (临时方案)
let (data, _) = try await URLSession.shared.data(for: request)

2. TCA 导入问题

原因: ComposableArchitecture 模块配置问题

解决方案:

  1. 检查 Package Dependencies 是否正确添加
  2. 确保 target 正确链接了 TCA
  3. Clean Build Folder (⌘+Shift+K)
  4. 重新构建项目

3. 网络请求失败

常见错误处理:

do {
    let response = try await apiClient.get(path: "/endpoint")
    // 成功处理
} catch let urlError as URLError {
    switch urlError.code {
    case .notConnectedToInternet:
        print("网络不可用")
    case .timedOut:
        print("请求超时")
    case .cannotFindHost:
        print("无法找到服务器")
    default:
        print("网络错误: \(urlError.localizedDescription)")
    }
} catch {
    print("其他错误: \(error)")
}

📝 最佳实践

  1. 错误处理: 始终使用 do-catch 处理异步请求
  2. 主线程更新: 使用 await MainActor.run 更新 UI
  3. 取消请求: 在适当时候取消不需要的请求
  4. 重试机制: 对于网络错误实现重试逻辑
  5. 缓存策略: 考虑实现适当的缓存机制

🔄 迁移步骤

从原生 URLSession 迁移到 APIClient:

  1. 保留现有代码 - 确保功能正常
  2. 逐步替换 - 一个接口一个接口地迁移
  3. 测试验证 - 每次迁移后进行测试
  4. 清理代码 - 移除不需要的原生实现

这样可以确保平滑的迁移过程,避免破坏现有功能。