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

196 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# APIClient 集成指南
## 🔧 在其他文件中使用 APIClient
### 方法一:直接实例化 (推荐用于测试)
```swift
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
}
}
}
}
}
```
### 方法二:使用单例模式
```swift
// 在需要使用的文件中
private func makeAPIRequest() async {
do {
let response: SomeModel = try await APIClientManager.shared.get(
path: "/endpoint"
)
// 处理响应
} catch {
// 处理错误
}
}
```
### 方法三TCA 集成 (当 TCA 可用时)
```swift
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 模块系统问题,需要确保正确导入
**解决方案**:
```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. 网络请求失败
**常见错误处理**:
```swift
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. **清理代码** - 移除不需要的原生实现
这样可以确保平滑的迁移过程,避免破坏现有功能。