feat: 更新依赖和项目配置,优化代码结构

- 在Package.swift中注释掉旧的swift-composable-architecture依赖,并添加swift-case-paths依赖。
- 在Podfile中将iOS平台版本更新至16.0,并移除QCloudCOSXML/Transfer依赖,改为使用QCloudCOSXML。
- 更新Podfile.lock以反映依赖变更,确保项目依赖的准确性。
- 新增架构分析需求文档,明确项目架构评估和改进建议。
- 在多个文件中实现async/await语法,提升异步操作的可读性和性能。
- 更新日志输出方法,确保在调试模式下提供一致的调试信息。
- 优化多个视图组件,提升用户体验和代码可维护性。
This commit is contained in:
edwinQQQ
2025-07-17 18:47:09 +08:00
parent 4bbb4f8434
commit 128bf36c88
46 changed files with 1250 additions and 1203 deletions

View File

@@ -111,9 +111,10 @@ struct BaseRequest: Codable {
case pubSign = "pub_sign"
}
@MainActor
init() {
//
let preferredLanguage = Locale.current.languageCode ?? "en"
let preferredLanguage = Locale.current.language.languageCode?.identifier ?? "en"
self.acceptLanguage = preferredLanguage
self.lang = preferredLanguage
@@ -237,6 +238,7 @@ struct CarrierInfoManager {
// MARK: - User Info Manager (for Headers)
struct UserInfoManager {
@MainActor
private static let keychain = KeychainManager.shared
// MARK: - Storage Keys
@@ -246,72 +248,66 @@ struct UserInfoManager {
}
// MARK: -
private static var accountModelCache: AccountModel?
private static var userInfoCache: UserInfo?
// UserInfoCacheActor
private static let cacheQueue = DispatchQueue(label: "com.yana.userinfo.cache", attributes: .concurrent)
// MARK: - User ID Management ( AccountModel)
static func getCurrentUserId() -> String? {
return getAccountModel()?.uid
static func getCurrentUserId() async -> String? {
return await getAccountModel()?.uid
}
// MARK: - Access Token Management ( AccountModel)
static func getAccessToken() -> String? {
return getAccountModel()?.accessToken
static func getAccessToken() async -> String? {
return await getAccountModel()?.accessToken
}
// MARK: - Ticket Management ( AccountModel )
private static var currentTicket: String?
// UserInfoCacheActor
static func getCurrentUserTicket() -> String? {
static func getCurrentUserTicket() async -> String? {
// AccountModel ticket
if let accountTicket = getAccountModel()?.ticket, !accountTicket.isEmpty {
if let accountTicket = await getAccountModel()?.ticket, !accountTicket.isEmpty {
return accountTicket
}
//
return currentTicket
// actor
return await cacheActor.getCurrentTicket()
}
static func saveTicket(_ ticket: String) {
currentTicket = ticket
debugInfo("💾 保存 Ticket 到内存")
static func saveTicket(_ ticket: String) async {
await cacheActor.setCurrentTicket(ticket)
debugInfoSync("💾 保存 Ticket 到内存")
}
static func clearTicket() {
currentTicket = nil
debugInfo("🗑️ 清除 Ticket")
static func clearTicket() async {
await cacheActor.clearCurrentTicket()
debugInfoSync("🗑️ 清除 Ticket")
}
// MARK: - User Info Management
static func saveUserInfo(_ userInfo: UserInfo) {
cacheQueue.async(flags: .barrier) {
do {
try keychain.store(userInfo, forKey: StorageKeys.userInfo)
userInfoCache = userInfo
debugInfo("💾 保存用户信息成功")
} catch {
debugError("❌ 保存用户信息失败: \(error)")
}
static func saveUserInfo(_ userInfo: UserInfo) async {
do {
try await keychain.store(userInfo, forKey: StorageKeys.userInfo)
await cacheActor.setUserInfo(userInfo)
debugInfoSync("💾 保存用户信息成功")
} catch {
debugErrorSync("❌ 保存用户信息失败: \(error)")
}
}
static func getUserInfo() -> UserInfo? {
return cacheQueue.sync {
//
if let cached = userInfoCache {
return cached
}
// Keychain
do {
let userInfo = try keychain.retrieve(UserInfo.self, forKey: StorageKeys.userInfo)
userInfoCache = userInfo
return userInfo
} catch {
debugError("❌ 读取用户信息失败: \(error)")
return nil
}
static func getUserInfo() async -> UserInfo? {
//
if let cached = await cacheActor.getUserInfo() {
return cached
}
// Keychain
do {
let userInfo = try await keychain.retrieve(UserInfo.self, forKey: StorageKeys.userInfo)
await cacheActor.setUserInfo(userInfo)
return userInfo
} catch {
debugErrorSync("❌ 读取用户信息失败: \(error)")
return nil
}
}
@@ -322,7 +318,7 @@ struct UserInfoManager {
ticket: String,
uid: Int?,
userInfo: UserInfo?
) {
) async {
// AccountModel
let accountModel = AccountModel(
uid: uid != nil ? "\(uid!)" : nil,
@@ -336,38 +332,40 @@ struct UserInfoManager {
ticket: ticket
)
saveAccountModel(accountModel)
saveTicket(ticket)
await saveAccountModel(accountModel)
await saveTicket(ticket)
if let userInfo = userInfo {
saveUserInfo(userInfo)
await saveUserInfo(userInfo)
}
debugInfo("✅ 完整认证信息保存成功")
debugInfoSync("✅ 完整认证信息保存成功")
}
///
static func hasValidAuthentication() -> Bool {
return getAccessToken() != nil && getCurrentUserTicket() != nil
static func hasValidAuthentication() async -> Bool {
let token = await getAccessToken()
let ticket = await getCurrentUserTicket()
return token != nil && ticket != nil
}
///
static func clearAllAuthenticationData() {
clearAccountModel()
clearUserInfo()
clearTicket()
static func clearAllAuthenticationData() async {
await clearAccountModel()
await clearUserInfo()
await clearTicket()
debugInfo("🗑️ 清除所有认证信息")
debugInfoSync("🗑️ 清除所有认证信息")
}
/// Ticket
static func restoreTicketIfNeeded() async -> Bool {
guard let accessToken = getAccessToken(),
getCurrentUserTicket() == nil else {
guard let _ = await getAccessToken(),
await getCurrentUserTicket() == nil else {
return false
}
debugInfo("🔄 尝试使用 Access Token 恢复 Ticket...")
debugInfoSync("🔄 尝试使用 Access Token 恢复 Ticket...")
// APIService false
// TicketHelper.createTicketRequest
@@ -377,50 +375,48 @@ struct UserInfoManager {
// MARK: - Account Model Management
/// AccountModel
/// - Parameter accountModel:
static func saveAccountModel(_ accountModel: AccountModel) {
cacheQueue.async(flags: .barrier) {
do {
try keychain.store(accountModel, forKey: StorageKeys.accountModel)
accountModelCache = accountModel
// ticket
if let ticket = accountModel.ticket {
saveTicket(ticket)
}
debugInfo("💾 AccountModel 保存成功")
} catch {
debugError("❌ AccountModel 保存失败: \(error)")
static func saveAccountModel(_ accountModel: AccountModel) async {
do {
try await keychain.store(accountModel, forKey: StorageKeys.accountModel)
await cacheActor.setAccountModel(accountModel)
// ticket
if let ticket = accountModel.ticket {
await saveTicket(ticket)
}
debugInfoSync("💾 AccountModel 保存成功")
} catch {
debugErrorSync("❌ AccountModel 保存失败: \(error)")
}
}
/// AccountModel
/// - Returns: nil
static func getAccountModel() -> AccountModel? {
return cacheQueue.sync {
//
if let cached = accountModelCache {
return cached
}
// Keychain
do {
let accountModel = try keychain.retrieve(AccountModel.self, forKey: StorageKeys.accountModel)
accountModelCache = accountModel
return accountModel
} catch {
debugError("❌ 读取 AccountModel 失败: \(error)")
return nil
}
static func getAccountModel() async -> AccountModel? {
//
if let cached = await cacheActor.getAccountModel() {
return cached
}
// Keychain
do {
let accountModel = try await keychain.retrieve(
AccountModel.self,
forKey: StorageKeys.accountModel
)
await cacheActor.setAccountModel(accountModel)
return accountModel
} catch {
debugErrorSync("❌ 读取 AccountModel 失败: \(error)")
return nil
}
}
/// AccountModel ticket
/// - Parameter ticket:
static func updateAccountModelTicket(_ ticket: String) {
guard var accountModel = getAccountModel() else {
debugError("❌ 无法更新 ticketAccountModel 不存在")
static func updateAccountModelTicket(_ ticket: String) async {
guard var accountModel = await getAccountModel() else {
debugErrorSync("❌ 无法更新 ticketAccountModel 不存在")
return
}
@@ -436,97 +432,78 @@ struct UserInfoManager {
ticket: ticket
)
saveAccountModel(accountModel)
saveTicket(ticket) // ticket
await saveAccountModel(accountModel)
await saveTicket(ticket) // ticket
}
/// AccountModel
/// - Returns:
static func hasValidAccountModel() -> Bool {
guard let accountModel = getAccountModel() else {
static func hasValidAccountModel() async -> Bool {
guard let accountModel = await getAccountModel() else {
return false
}
return accountModel.hasValidAuthentication
}
/// AccountModel
static func clearAccountModel() {
cacheQueue.async(flags: .barrier) {
do {
try keychain.delete(forKey: StorageKeys.accountModel)
accountModelCache = nil
debugInfo("🗑️ AccountModel 已清除")
} catch {
debugError("❌ 清除 AccountModel 失败: \(error)")
}
static func clearAccountModel() async {
do {
try await keychain.delete(forKey: StorageKeys.accountModel)
await cacheActor.clearAccountModel()
debugInfoSync("🗑️ AccountModel 已清除")
} catch {
debugErrorSync("❌ 清除 AccountModel 失败: \(error)")
}
}
///
static func clearUserInfo() {
cacheQueue.async(flags: .barrier) {
do {
try keychain.delete(forKey: StorageKeys.userInfo)
userInfoCache = nil
debugInfo("🗑️ UserInfo 已清除")
} catch {
debugError("❌ 清除 UserInfo 失败: \(error)")
}
static func clearUserInfo() async {
do {
try await keychain.delete(forKey: StorageKeys.userInfo)
await cacheActor.clearUserInfo()
debugInfoSync("🗑️ UserInfo 已清除")
} catch {
debugErrorSync("❌ 清除 UserInfo 失败: \(error)")
}
}
///
static func clearAllCache() {
cacheQueue.async(flags: .barrier) {
accountModelCache = nil
userInfoCache = nil
debugInfo("🗑️ 清除所有内存缓存")
}
static func clearAllCache() async {
await cacheActor.clearAccountModel()
await cacheActor.clearUserInfo()
debugInfoSync("🗑️ 清除所有内存缓存")
}
/// 访
static func preloadCache() {
cacheQueue.async {
// AccountModel
_ = getAccountModel()
// UserInfo
_ = getUserInfo()
debugInfo("🚀 缓存预加载完成")
}
static func preloadCache() async {
await cacheActor.setAccountModel(await getAccountModel())
await cacheActor.setUserInfo(await getUserInfo())
debugInfoSync("🚀 缓存预加载完成")
}
// MARK: - Authentication Validation
///
/// - Returns:
static func checkAuthenticationStatus() -> AuthenticationStatus {
return cacheQueue.sync {
guard let accountModel = getAccountModel() else {
debugInfo("🔍 认证检查:未找到 AccountModel")
return .notFound
}
// uid
guard let uid = accountModel.uid, !uid.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
debugInfo("🔍 认证检查uid 无效")
return .invalid
}
// ticket
guard let ticket = accountModel.ticket, !ticket.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
debugInfo("🔍 认证检查ticket 无效")
return .invalid
}
// access token
guard let accessToken = accountModel.accessToken, !accessToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
debugInfo("🔍 认证检查access token 无效")
return .invalid
}
debugInfo("🔍 认证检查:认证有效 - uid: \(uid), ticket: \(ticket.prefix(10))...")
return .valid
static func checkAuthenticationStatus() async -> AuthenticationStatus {
guard let accountModel = await getAccountModel() else {
debugInfoSync("🔍 认证检查:未找到 AccountModel")
return .notFound
}
guard let uid = accountModel.uid, !uid.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
debugInfoSync("🔍 认证检查uid 无效")
return .invalid
}
guard let ticket = accountModel.ticket, !ticket.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
debugInfoSync("🔍 认证检查ticket 无效")
return .invalid
}
guard let accessToken = accountModel.accessToken, !accessToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
debugInfoSync("🔍 认证检查access token 无效")
return .invalid
}
debugInfoSync("🔍 认证检查:认证有效 - uid: \(uid), ticket: \(ticket.prefix(10))...")
return .valid
}
///
@@ -556,19 +533,19 @@ struct UserInfoManager {
/// header
/// header
static func testAuthenticationHeaders() {
static func testAuthenticationHeaders() async {
#if DEBUG
debugInfo("\n🧪 开始测试认证 header 功能")
debugInfoSync("\n🧪 开始测试认证 header 功能")
// 1
debugInfo("📝 测试1未登录状态")
clearAllAuthenticationData()
let headers1 = APIConfiguration.defaultHeaders
debugInfoSync("📝 测试1未登录状态")
await clearAllAuthenticationData()
let headers1 = await APIConfiguration.defaultHeaders()
let hasAuthHeaders1 = headers1.keys.contains("pub_uid") || headers1.keys.contains("pub_ticket")
debugInfo(" 认证 headers 存在: \(hasAuthHeaders1) (应该为 false)")
debugInfoSync(" 认证 headers 存在: \(hasAuthHeaders1) (应该为 false)")
// 2
debugInfo("📝 测试2模拟登录状态")
debugInfoSync("📝 测试2模拟登录状态")
let testAccount = AccountModel(
uid: "12345",
jti: "test-jti",
@@ -580,22 +557,48 @@ struct UserInfoManager {
scope: "read write",
ticket: "test-ticket-12345678901234567890"
)
saveAccountModel(testAccount)
await saveAccountModel(testAccount)
let headers2 = APIConfiguration.defaultHeaders
let headers2 = await APIConfiguration.defaultHeaders()
let hasUid = headers2["pub_uid"] == "12345"
let hasTicket = headers2["pub_ticket"] == "test-ticket-12345678901234567890"
debugInfo(" pub_uid 正确: \(hasUid) (应该为 true)")
debugInfo(" pub_ticket 正确: \(hasTicket) (应该为 true)")
debugInfoSync(" pub_uid 正确: \(hasUid) (应该为 true)")
debugInfoSync(" pub_ticket 正确: \(hasTicket) (应该为 true)")
// 3
debugInfo("📝 测试3清理测试数据")
clearAllAuthenticationData()
debugInfo("✅ 认证 header 测试完成\n")
debugInfoSync("📝 测试3清理测试数据")
await clearAllAuthenticationData()
debugInfoSync("✅ 认证 header 测试完成\n")
#endif
}
}
// MARK: - User Info Cache Actor
actor UserInfoCacheActor {
private var accountModelCache: AccountModel?
private var userInfoCache: UserInfo?
private var currentTicket: String?
// AccountModel
func getAccountModel() -> AccountModel? { accountModelCache }
func setAccountModel(_ model: AccountModel?) { accountModelCache = model }
func clearAccountModel() { accountModelCache = nil }
// UserInfo
func getUserInfo() -> UserInfo? { userInfoCache }
func setUserInfo(_ info: UserInfo?) { userInfoCache = info }
func clearUserInfo() { userInfoCache = nil }
// Ticket
func getCurrentTicket() -> String? { currentTicket }
func setCurrentTicket(_ ticket: String?) { currentTicket = ticket }
func clearCurrentTicket() { currentTicket = nil }
}
extension UserInfoManager {
static let cacheActor = UserInfoCacheActor()
}
// MARK: - API Request Protocol
/// API
@@ -604,7 +607,7 @@ struct UserInfoManager {
/// API
///
///
/// - Response:
/// - Response: Sendable
/// - endpoint: API
/// - method: HTTP
/// -
@@ -618,8 +621,8 @@ struct UserInfoManager {
/// // ...
/// }
/// ```
protocol APIRequestProtocol {
associatedtype Response: Codable
protocol APIRequestProtocol: Sendable {
associatedtype Response: Codable & Sendable
var endpoint: String { get }
var method: HTTPMethod { get }