feat: 更新Podfile和Podfile.lock,移除Alamofire依赖并添加API认证机制文档
- 注释掉Podfile中的Alamofire依赖,更新Podfile.lock以反映更改。 - 在yana/APIs/API-README.md中新增自动认证Header机制的详细文档,描述其工作原理、实现细节及最佳实践。 - 在yana/yanaApp.swift中将print语句替换为debugInfo以增强调试信息的输出。 - 在API相关文件中实现用户认证状态检查和相关header的自动添加逻辑,提升API请求的安全性和用户体验。 - 更新多个文件中的日志输出,确保在DEBUG模式下提供详细的调试信息。
This commit is contained in:
@@ -18,24 +18,24 @@ struct APILoadingEffectView: View {
|
||||
if let firstItem = getFirstDisplayItem() {
|
||||
SingleLoadingView(item: firstItem)
|
||||
.onAppear {
|
||||
print("🔍 Loading item appeared: \(firstItem.id)")
|
||||
debugInfo("🔍 Loading item appeared: \(firstItem.id)")
|
||||
}
|
||||
.onDisappear {
|
||||
print("🔍 Loading item disappeared: \(firstItem.id)")
|
||||
debugInfo("🔍 Loading item disappeared: \(firstItem.id)")
|
||||
}
|
||||
}
|
||||
}
|
||||
.allowsHitTesting(false) // 不阻挡用户点击
|
||||
.ignoresSafeArea(.all) // 覆盖整个屏幕
|
||||
.onReceive(loadingManager.$loadingItems) { items in
|
||||
print("🔍 Loading items updated: \(items.count) items")
|
||||
debugInfo("🔍 Loading items updated: \(items.count) items")
|
||||
}
|
||||
}
|
||||
|
||||
/// 安全地获取第一个需要显示的项目
|
||||
private func getFirstDisplayItem() -> APILoadingItem? {
|
||||
guard Thread.isMainThread else {
|
||||
print("⚠️ getFirstDisplayItem called from background thread")
|
||||
debugWarn("⚠️ getFirstDisplayItem called from background thread")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ struct APILoadingEffectView_Previews: PreviewProvider {
|
||||
.font(.title)
|
||||
|
||||
Button("测试按钮") {
|
||||
print("按钮被点击了!")
|
||||
debugInfo("按钮被点击了!")
|
||||
}
|
||||
.padding()
|
||||
.background(Color.blue)
|
||||
|
@@ -6,7 +6,7 @@ struct StringHashTest {
|
||||
|
||||
/// 测试哈希方法
|
||||
static func runTests() {
|
||||
print("🧪 开始测试字符串哈希方法...")
|
||||
debugInfo("🧪 开始测试字符串哈希方法...")
|
||||
|
||||
let testStrings = [
|
||||
"hello world",
|
||||
@@ -16,27 +16,27 @@ struct StringHashTest {
|
||||
]
|
||||
|
||||
for testString in testStrings {
|
||||
print("\n📝 测试字符串: \"\(testString)\"")
|
||||
debugInfo("\n📝 测试字符串: \"\(testString)\"")
|
||||
|
||||
// 测试 MD5
|
||||
let md5Result = testString.md5()
|
||||
print(" MD5: \(md5Result)")
|
||||
debugInfo(" MD5: \(md5Result)")
|
||||
|
||||
// 测试 SHA256 (iOS 13+)
|
||||
if #available(iOS 13.0, *) {
|
||||
let sha256Result = testString.sha256()
|
||||
print(" SHA256: \(sha256Result)")
|
||||
debugInfo(" SHA256: \(sha256Result)")
|
||||
} else {
|
||||
print(" SHA256: 不支持 (需要 iOS 13+)")
|
||||
debugInfo(" SHA256: 不支持 (需要 iOS 13+)")
|
||||
}
|
||||
}
|
||||
|
||||
print("\n✅ 哈希方法测试完成")
|
||||
debugInfo("\n✅ 哈希方法测试完成")
|
||||
}
|
||||
|
||||
/// 验证已知的哈希值
|
||||
static func verifyKnownHashes() {
|
||||
print("\n🔍 验证已知哈希值...")
|
||||
debugInfo("\n🔍 验证已知哈希值...")
|
||||
|
||||
// 验证 "hello world" 的 MD5 应该是 "5d41402abc4b2a76b9719d911017c592"
|
||||
let testString = "hello world"
|
||||
@@ -44,11 +44,11 @@ struct StringHashTest {
|
||||
let actualMD5 = testString.md5()
|
||||
|
||||
if actualMD5 == expectedMD5 {
|
||||
print("✅ MD5 验证通过: \(actualMD5)")
|
||||
debugInfo("✅ MD5 验证通过: \(actualMD5)")
|
||||
} else {
|
||||
print("❌ MD5 验证失败:")
|
||||
print(" 期望: \(expectedMD5)")
|
||||
print(" 实际: \(actualMD5)")
|
||||
debugError("❌ MD5 验证失败:")
|
||||
debugError(" 期望: \(expectedMD5)")
|
||||
debugError(" 实际: \(actualMD5)")
|
||||
}
|
||||
|
||||
// 验证 SHA256
|
||||
@@ -57,11 +57,11 @@ struct StringHashTest {
|
||||
let actualSHA256 = testString.sha256()
|
||||
|
||||
if actualSHA256 == expectedSHA256 {
|
||||
print("✅ SHA256 验证通过: \(actualSHA256)")
|
||||
debugInfo("✅ SHA256 验证通过: \(actualSHA256)")
|
||||
} else {
|
||||
print("❌ SHA256 验证失败:")
|
||||
print(" 期望: \(expectedSHA256)")
|
||||
print(" 实际: \(actualSHA256)")
|
||||
debugError("❌ SHA256 验证失败:")
|
||||
debugError(" 期望: \(expectedSHA256)")
|
||||
debugError(" 实际: \(actualSHA256)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,9 +75,9 @@ struct StringHashTest {
|
||||
StringHashTest.verifyKnownHashes()
|
||||
|
||||
// 或者在开发时快速测试
|
||||
print("Test MD5:", "hello".md5())
|
||||
debugInfo("Test MD5:", "hello".md5())
|
||||
if #available(iOS 13.0, *) {
|
||||
print("Test SHA256:", "hello".sha256())
|
||||
debugInfo("Test SHA256:", "hello".sha256())
|
||||
}
|
||||
|
||||
*/
|
@@ -67,11 +67,11 @@ struct FontManager {
|
||||
|
||||
/// 打印所有可用字体(调试用)
|
||||
static func printAllAvailableFonts() {
|
||||
print("=== 所有可用字体 ===")
|
||||
debugInfo("=== 所有可用字体 ===")
|
||||
for font in getAllAvailableFonts() {
|
||||
print(font)
|
||||
debugInfo(font)
|
||||
}
|
||||
print("==================")
|
||||
debugInfo("==================")
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -42,9 +42,9 @@ class LocalizationManager: ObservableObject {
|
||||
didSet {
|
||||
do {
|
||||
try KeychainManager.shared.storeString(currentLanguage.rawValue, forKey: "AppLanguage")
|
||||
} catch {
|
||||
print("❌ 保存语言设置失败: \(error)")
|
||||
}
|
||||
} catch {
|
||||
debugError("❌ 保存语言设置失败: \(error)")
|
||||
}
|
||||
// 通知视图更新
|
||||
objectWillChange.send()
|
||||
}
|
||||
@@ -56,7 +56,7 @@ class LocalizationManager: ObservableObject {
|
||||
do {
|
||||
savedLanguage = try KeychainManager.shared.retrieveString(forKey: "AppLanguage")
|
||||
} catch {
|
||||
print("❌ 读取语言设置失败: \(error)")
|
||||
debugError("❌ 读取语言设置失败: \(error)")
|
||||
savedLanguage = nil
|
||||
}
|
||||
|
||||
|
@@ -5,8 +5,8 @@ struct DESEncryptOCTest {
|
||||
|
||||
/// 测试 OC 版本的 DES 加密功能
|
||||
static func testOCDESEncryption() {
|
||||
print("🧪 开始测试 OC 版本的 DES 加密...")
|
||||
print(String(repeating: "=", count: 50))
|
||||
debugInfo("🧪 开始测试 OC 版本的 DES 加密...")
|
||||
debugInfo(String(repeating: "=", count: 50))
|
||||
|
||||
let key = "1ea53d260ecf11e7b56e00163e046a26"
|
||||
let testCases = [
|
||||
@@ -19,25 +19,25 @@ struct DESEncryptOCTest {
|
||||
|
||||
for testCase in testCases {
|
||||
if let encrypted = DESEncrypt.encryptUseDES(testCase, key: key) {
|
||||
print("✅ 加密成功:")
|
||||
print(" 原文: \"\(testCase)\"")
|
||||
print(" 密文: \(encrypted)")
|
||||
debugInfo("✅ 加密成功:")
|
||||
debugInfo(" 原文: \"\(testCase)\"")
|
||||
debugInfo(" 密文: \(encrypted)")
|
||||
|
||||
// 测试解密
|
||||
if let decrypted = DESEncrypt.decryptUseDES(encrypted, key: key) {
|
||||
let isMatch = decrypted == testCase
|
||||
print(" 解密: \"\(decrypted)\" \(isMatch ? "✅" : "❌")")
|
||||
debugInfo(" 解密: \"\(decrypted)\" \(isMatch ? "✅" : "❌")")
|
||||
} else {
|
||||
print(" 解密: 失败 ❌")
|
||||
debugError(" 解密: 失败 ❌")
|
||||
}
|
||||
} else {
|
||||
print("❌ 加密失败: \"\(testCase)\"")
|
||||
debugError("❌ 加密失败: \"\(testCase)\"")
|
||||
}
|
||||
print()
|
||||
debugInfo("")
|
||||
}
|
||||
|
||||
print(String(repeating: "=", count: 50))
|
||||
print("🏁 OC版本DES加密测试完成")
|
||||
debugInfo(String(repeating: "=", count: 50))
|
||||
debugInfo("🏁 OC版本DES加密测试完成")
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -54,23 +54,23 @@ final class DataMigrationManager {
|
||||
/// 执行数据迁移
|
||||
/// - Returns: 迁移结果
|
||||
func performMigration() -> MigrationResult {
|
||||
print("🔄 开始检查数据迁移...")
|
||||
debugInfo("🔄 开始检查数据迁移...")
|
||||
|
||||
// 检查是否已经迁移过
|
||||
if isMigrationCompleted() {
|
||||
print("✅ 数据已经迁移过,跳过迁移")
|
||||
debugInfo("✅ 数据已经迁移过,跳过迁移")
|
||||
return .alreadyMigrated
|
||||
}
|
||||
|
||||
// 检查是否有需要迁移的数据
|
||||
let legacyData = collectLegacyData()
|
||||
if legacyData.isEmpty {
|
||||
print("ℹ️ 没有发现需要迁移的数据")
|
||||
debugInfo("ℹ️ 没有发现需要迁移的数据")
|
||||
markMigrationCompleted()
|
||||
return .noDataToMigrate
|
||||
}
|
||||
|
||||
print("📦 发现需要迁移的数据: \(legacyData.keys.joined(separator: ", "))")
|
||||
debugInfo("📦 发现需要迁移的数据: \(legacyData.keys.joined(separator: ", "))")
|
||||
|
||||
do {
|
||||
// 执行迁移
|
||||
@@ -85,11 +85,11 @@ final class DataMigrationManager {
|
||||
// 标记迁移完成
|
||||
markMigrationCompleted()
|
||||
|
||||
print("✅ 数据迁移完成")
|
||||
debugInfo("✅ 数据迁移完成")
|
||||
return .completed
|
||||
|
||||
} catch {
|
||||
print("❌ 数据迁移失败: \(error)")
|
||||
debugError("❌ 数据迁移失败: \(error)")
|
||||
return .failed(error)
|
||||
}
|
||||
}
|
||||
@@ -157,9 +157,9 @@ final class DataMigrationManager {
|
||||
do {
|
||||
let accountModel = try JSONDecoder().decode(AccountModel.self, from: accountModelData)
|
||||
try keychain.store(accountModel, forKey: "account_model")
|
||||
print("✅ AccountModel 迁移成功")
|
||||
debugInfo("✅ AccountModel 迁移成功")
|
||||
} catch {
|
||||
print("❌ AccountModel 迁移失败: \(error)")
|
||||
debugError("❌ AccountModel 迁移失败: \(error)")
|
||||
// 如果 AccountModel 迁移失败,尝试从独立字段重建
|
||||
try migrateAccountModelFromIndependentFields(legacyData)
|
||||
}
|
||||
@@ -173,9 +173,9 @@ final class DataMigrationManager {
|
||||
do {
|
||||
let userInfo = try JSONDecoder().decode(UserInfo.self, from: userInfoData)
|
||||
try keychain.store(userInfo, forKey: "user_info")
|
||||
print("✅ UserInfo 迁移成功")
|
||||
debugInfo("✅ UserInfo 迁移成功")
|
||||
} catch {
|
||||
print("❌ UserInfo 迁移失败: \(error)")
|
||||
debugError("❌ UserInfo 迁移失败: \(error)")
|
||||
throw error
|
||||
}
|
||||
}
|
||||
@@ -183,7 +183,7 @@ final class DataMigrationManager {
|
||||
// 迁移语言设置
|
||||
if let appLanguage = legacyData[LegacyStorageKeys.appLanguage] as? String {
|
||||
try keychain.storeString(appLanguage, forKey: "AppLanguage")
|
||||
print("✅ 语言设置迁移成功")
|
||||
debugInfo("✅ 语言设置迁移成功")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ final class DataMigrationManager {
|
||||
private func migrateAccountModelFromIndependentFields(_ legacyData: [String: Any]) throws {
|
||||
guard let userId = legacyData[LegacyStorageKeys.userId] as? String,
|
||||
let accessToken = legacyData[LegacyStorageKeys.accessToken] as? String else {
|
||||
print("ℹ️ 没有足够的独立字段来重建 AccountModel")
|
||||
debugInfo("ℹ️ 没有足够的独立字段来重建 AccountModel")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ final class DataMigrationManager {
|
||||
)
|
||||
|
||||
try KeychainManager.shared.store(accountModel, forKey: "account_model")
|
||||
print("✅ 从独立字段重建 AccountModel 成功")
|
||||
debugInfo("✅ 从独立字段重建 AccountModel 成功")
|
||||
}
|
||||
|
||||
/// 验证迁移结果
|
||||
@@ -240,7 +240,7 @@ final class DataMigrationManager {
|
||||
}
|
||||
}
|
||||
|
||||
print("✅ 迁移数据验证成功")
|
||||
debugInfo("✅ 迁移数据验证成功")
|
||||
}
|
||||
|
||||
/// 清理旧数据
|
||||
@@ -249,11 +249,11 @@ final class DataMigrationManager {
|
||||
|
||||
for key in keys {
|
||||
userDefaults.removeObject(forKey: key)
|
||||
print("🗑️ 清理旧数据: \(key)")
|
||||
debugInfo("🗑️ 清理旧数据: \(key)")
|
||||
}
|
||||
|
||||
userDefaults.synchronize()
|
||||
print("✅ 旧数据清理完成")
|
||||
debugInfo("✅ 旧数据清理完成")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,13 +287,13 @@ extension DataMigrationManager {
|
||||
|
||||
switch migrationResult {
|
||||
case .completed:
|
||||
print("🎉 应用启动时数据迁移完成")
|
||||
debugInfo("🎉 应用启动时数据迁移完成")
|
||||
case .alreadyMigrated:
|
||||
break // 静默处理
|
||||
case .noDataToMigrate:
|
||||
break // 静默处理
|
||||
case .failed(let error):
|
||||
print("⚠️ 应用启动时数据迁移失败: \(error)")
|
||||
debugError("⚠️ 应用启动时数据迁移失败: \(error)")
|
||||
// 这里可以添加错误上报或降级策略
|
||||
}
|
||||
}
|
||||
@@ -307,9 +307,9 @@ extension DataMigrationManager {
|
||||
/// 调试:打印旧数据信息
|
||||
func debugPrintLegacyData() {
|
||||
let legacyData = collectLegacyData()
|
||||
print("🔍 旧版本数据:")
|
||||
debugInfo("🔍 旧版本数据:")
|
||||
for (key, value) in legacyData {
|
||||
print(" - \(key): \(type(of: value))")
|
||||
debugInfo(" - \(key): \(type(of: value))")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ extension DataMigrationManager {
|
||||
userDefaults.set("zh-Hans", forKey: LegacyStorageKeys.appLanguage)
|
||||
userDefaults.synchronize()
|
||||
|
||||
print("🧪 已创建测试用的旧版本数据")
|
||||
debugInfo("🧪 已创建测试用的旧版本数据")
|
||||
}
|
||||
|
||||
/// 调试:清除所有迁移相关数据
|
||||
@@ -331,7 +331,7 @@ extension DataMigrationManager {
|
||||
do {
|
||||
try KeychainManager.shared.clearAll()
|
||||
} catch {
|
||||
print("❌ 清除 Keychain 数据失败: \(error)")
|
||||
debugError("❌ 清除 Keychain 数据失败: \(error)")
|
||||
}
|
||||
|
||||
// 清除 UserDefaults 数据
|
||||
@@ -350,7 +350,7 @@ extension DataMigrationManager {
|
||||
}
|
||||
userDefaults.synchronize()
|
||||
|
||||
print("🧪 已清除所有迁移相关数据")
|
||||
debugInfo("🧪 已清除所有迁移相关数据")
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -108,7 +108,7 @@ final class KeychainManager {
|
||||
throw KeychainError.keychainOperationFailed(status)
|
||||
}
|
||||
|
||||
print("🔐 Keychain 存储成功: \(key)")
|
||||
debugInfo("🔐 Keychain 存储成功: \(key)")
|
||||
}
|
||||
|
||||
/// 从 Keychain 检索 Codable 对象
|
||||
@@ -137,7 +137,7 @@ final class KeychainManager {
|
||||
// 4. 解码数据
|
||||
do {
|
||||
let object = try JSONDecoder().decode(type, from: data)
|
||||
print("🔐 Keychain 读取成功: \(key)")
|
||||
debugInfo("🔐 Keychain 读取成功: \(key)")
|
||||
return object
|
||||
} catch {
|
||||
throw KeychainError.decodingFailed(error)
|
||||
@@ -176,7 +176,7 @@ final class KeychainManager {
|
||||
|
||||
switch status {
|
||||
case errSecSuccess:
|
||||
print("🔐 Keychain 更新成功: \(key)")
|
||||
debugInfo("🔐 Keychain 更新成功: \(key)")
|
||||
|
||||
case errSecItemNotFound:
|
||||
// 如果项目不存在,则创建新项目
|
||||
@@ -196,7 +196,7 @@ final class KeychainManager {
|
||||
|
||||
switch status {
|
||||
case errSecSuccess:
|
||||
print("🔐 Keychain 删除成功: \(key)")
|
||||
debugInfo("🔐 Keychain 删除成功: \(key)")
|
||||
|
||||
case errSecItemNotFound:
|
||||
// 项目不存在,视为删除成功
|
||||
@@ -231,7 +231,7 @@ final class KeychainManager {
|
||||
|
||||
switch status {
|
||||
case errSecSuccess, errSecItemNotFound:
|
||||
print("🔐 Keychain 清除完成")
|
||||
debugInfo("🔐 Keychain 清除完成")
|
||||
|
||||
default:
|
||||
throw KeychainError.keychainOperationFailed(status)
|
||||
@@ -353,9 +353,9 @@ extension KeychainManager {
|
||||
/// 打印所有存储的键(仅用于调试)
|
||||
func debugPrintAllKeys() {
|
||||
let keys = debugListAllKeys()
|
||||
print("🔐 Keychain 中存储的键:")
|
||||
debugInfo("🔐 Keychain 中存储的键:")
|
||||
for key in keys {
|
||||
print(" - \(key)")
|
||||
debugInfo(" - \(key)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user