Files
e-party-iOS/yana/APIs/APIModels.swift
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

138 lines
4.0 KiB
Swift
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.

import Foundation
import ComposableArchitecture
// MARK: - HTTP Method
enum HTTPMethod: String, CaseIterable {
case GET = "GET"
case POST = "POST"
case PUT = "PUT"
case DELETE = "DELETE"
case PATCH = "PATCH"
}
// MARK: - API Error Types
enum APIError: Error, Equatable {
case invalidURL
case noData
case decodingError(String)
case networkError(String)
case httpError(statusCode: Int, message: String?)
case timeout
case resourceTooLarge
case unknown(String)
var localizedDescription: String {
switch self {
case .invalidURL:
return "无效的 URL"
case .noData:
return "没有收到数据"
case .decodingError(let message):
return "数据解析失败: \(message)"
case .networkError(let message):
return "网络错误: \(message)"
case .httpError(let statusCode, let message):
return "HTTP 错误 \(statusCode): \(message ?? "未知错误")"
case .timeout:
return "请求超时"
case .resourceTooLarge:
return "响应数据过大"
case .unknown(let message):
return "未知错误: \(message)"
}
}
}
// MARK: - Base Request Parameters
struct BaseRequest: Codable {
let acceptLanguage: String
let os: String = "iOS"
let osVersion: String
let ispType: String
let channel: String = "molistar_enterprise"
let model: String
let deviceId: String
let appVersion: String
let app: String = "youmi"
let mcc: String?
let spType: String?
let pubSign: String
enum CodingKeys: String, CodingKey {
case acceptLanguage = "Accept-Language"
case appVersion = "appVersion"
case os, osVersion, ispType, channel, model, deviceId
case app, mcc, spType
case pubSign = "pub_sign"
}
init() {
//
self.acceptLanguage = Locale.current.languageCode ?? "en"
//
self.osVersion = UIDevice.current.systemVersion
//
self.model = UIDevice.current.model
// ID (使 identifierForVendor)
self.deviceId = UIDevice.current.identifierForVendor?.uuidString ?? UUID().uuidString
//
self.appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0.0"
//
self.ispType = "65535"
self.mcc = nil
self.spType = nil
// 使 MD5
let timestamp = String(Int(Date().timeIntervalSince1970))
self.pubSign = timestamp.md5()
}
}
// MARK: - API Request Protocol
protocol APIRequestProtocol {
associatedtype Response: Codable
var endpoint: String { get }
var method: HTTPMethod { get }
var queryParameters: [String: String]? { get }
var bodyParameters: [String: Any]? { get }
var headers: [String: String]? { get }
var timeout: TimeInterval { get }
var includeBaseParameters: Bool { get }
}
extension APIRequestProtocol {
var timeout: TimeInterval { 30.0 }
var includeBaseParameters: Bool { true }
var headers: [String: String]? { nil }
}
// MARK: - Generic API Response
struct APIResponse<T: Codable>: Codable {
let data: T?
let status: String?
let message: String?
let code: Int?
}
// MARK: - String MD5 Extension
extension String {
func md5() -> String {
let data = Data(self.utf8)
let hash = data.withUnsafeBytes { bytes -> [UInt8] in
var hash = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
CC_MD5(bytes.baseAddress, CC_LONG(data.count), &hash)
return hash
}
return hash.map { String(format: "%02x", $0) }.joined()
}
}
// CommonCrypto
import CommonCrypto