从 iOS 17 Observation 迁移至 iOS 16 兼容的 Combine 架构
将最低部署版本降至 iOS 16,以 ObservableObject 替换 @Observable,新增导航与 UI 兼容层,并补充登录冒烟 UI 测试。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Observation
|
||||
import Combine
|
||||
|
||||
/// 账号缓存快照实体,保存可重建、非敏感的账号展示和业务上下文。
|
||||
struct AccountSnapshot: Codable, Equatable {
|
||||
@ -41,13 +41,12 @@ struct AccountSnapshot: Codable, Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
@Observable
|
||||
/// 账号快照存储服务,使用 UserDefaults 保存非敏感登录上下文。
|
||||
final class AccountSnapshotStore {
|
||||
@ObservationIgnored private let defaults: UserDefaults
|
||||
@ObservationIgnored private let key: String
|
||||
@ObservationIgnored private let encoder: JSONEncoder
|
||||
@ObservationIgnored private let decoder: JSONDecoder
|
||||
private let defaults: UserDefaults
|
||||
private let key: String
|
||||
private let encoder: JSONEncoder
|
||||
private let decoder: JSONDecoder
|
||||
|
||||
/// 初始化账号快照存储服务,并允许测试注入独立的 UserDefaults。
|
||||
init(
|
||||
|
||||
@ -6,14 +6,13 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Observation
|
||||
import Combine
|
||||
|
||||
@Observable
|
||||
/// App 偏好存储服务,保存上次手机号和协议状态等非敏感设置。
|
||||
final class AppPreferencesStore {
|
||||
@ObservationIgnored private let defaults: UserDefaults
|
||||
@ObservationIgnored private let lastLoginUsernameKey = "suixinkan.preferences.last_login_username"
|
||||
@ObservationIgnored private let privacyAgreementAcceptedKey = "suixinkan.preferences.privacy_agreement_accepted"
|
||||
private let defaults: UserDefaults
|
||||
private let lastLoginUsernameKey = "suixinkan.preferences.last_login_username"
|
||||
private let privacyAgreementAcceptedKey = "suixinkan.preferences.privacy_agreement_accepted"
|
||||
|
||||
/// 初始化偏好存储服务,并允许测试注入独立的 UserDefaults。
|
||||
init(defaults: UserDefaults = .standard) {
|
||||
@ -43,4 +42,10 @@ final class AppPreferencesStore {
|
||||
func loadPrivacyAgreementAccepted() -> Bool {
|
||||
defaults.bool(forKey: privacyAgreementAcceptedKey)
|
||||
}
|
||||
|
||||
/// 清空登录页偏好。
|
||||
func clear() {
|
||||
defaults.removeObject(forKey: lastLoginUsernameKey)
|
||||
defaults.removeObject(forKey: privacyAgreementAcceptedKey)
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Observation
|
||||
import Combine
|
||||
import Security
|
||||
|
||||
/// 登录 token 存储错误实体,表示 Keychain 读写失败的具体状态。
|
||||
@ -21,11 +21,10 @@ enum SessionTokenStoreError: LocalizedError {
|
||||
}
|
||||
}
|
||||
|
||||
@Observable
|
||||
/// 正式登录 token 存储服务,封装 Keychain 读写并避免业务层接触安全 API。
|
||||
final class SessionTokenStore {
|
||||
@ObservationIgnored private let service: String
|
||||
@ObservationIgnored private let account: String
|
||||
private let service: String
|
||||
private let account: String
|
||||
|
||||
/// 初始化 token 存储服务,默认按 App Bundle 隔离 Keychain 项。
|
||||
init(
|
||||
|
||||
Reference in New Issue
Block a user