
新增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以排除构建文件和临时文件。
83 lines
2.5 KiB
Swift
83 lines
2.5 KiB
Swift
import Foundation
|
||
import ComposableArchitecture
|
||
|
||
struct LoginResponse: Codable, Equatable {
|
||
let status: String
|
||
let message: String?
|
||
let token: String?
|
||
}
|
||
|
||
@Reducer
|
||
struct LoginFeature {
|
||
@ObservableState
|
||
struct State: Equatable {
|
||
var account: String = ""
|
||
var password: String = ""
|
||
var isLoading = false
|
||
var error: String?
|
||
|
||
#if DEBUG
|
||
init() {
|
||
self.account = "3184"
|
||
self.password = "a0d5da073d14731cc7a01ecaa17b9174"
|
||
}
|
||
#endif
|
||
}
|
||
|
||
enum Action: Equatable {
|
||
case updateAccount(String)
|
||
case updatePassword(String)
|
||
case login
|
||
case loginResponse(TaskResult<LoginResponse>)
|
||
}
|
||
|
||
var body: some ReducerOf<Self> {
|
||
Reduce { state, action in
|
||
switch action {
|
||
case let .updateAccount(account):
|
||
state.account = account
|
||
return .none
|
||
|
||
case let .updatePassword(password):
|
||
state.password = password
|
||
return .none
|
||
|
||
case .login:
|
||
state.isLoading = true
|
||
state.error = nil
|
||
|
||
let loginBody = [
|
||
"account": state.account,
|
||
"password": state.password
|
||
]
|
||
|
||
return .run { send in
|
||
do {
|
||
let response: LoginResponse = try await APIClientManager.shared.post(
|
||
path: APIConstants.Endpoints.login,
|
||
body: loginBody,
|
||
headers: APIConstants.defaultHeaders
|
||
)
|
||
await send(.loginResponse(.success(response)))
|
||
} catch {
|
||
await send(.loginResponse(.failure(error)))
|
||
}
|
||
}
|
||
|
||
case let .loginResponse(.success(response)):
|
||
state.isLoading = false
|
||
if response.status == "success" {
|
||
// TODO: 处理登录成功,保存 token 等
|
||
} else {
|
||
state.error = response.message ?? "登录失败"
|
||
}
|
||
return .none
|
||
|
||
case let .loginResponse(.failure(error)):
|
||
state.isLoading = false
|
||
state.error = error.localizedDescription
|
||
return .none
|
||
}
|
||
}
|
||
}
|
||
} |