// // LoginState.swift // punchnet // // Created by 安礼成 on 2026/1/16. // import Foundation import Observation @Observable class UserContext { var loginCredit: Credit? var networkSession: SDLAPIClient.NetworkSession? enum Credit { case token(token: String) case accountAndPasword(account: String, password: String) } func loginWith(credit: Credit) async throws -> Bool { switch credit { case .token(let token): self.networkSession = try await SDLAPIClient.loginWithToken(token: token) // 将数据缓存到keychain if let data = token.data(using: .utf8) { try KeychainStore.shared.save(data, account: "token") } case .accountAndPasword(let username, let password): self.networkSession = try await SDLAPIClient.loginWithAccountAndPassword(username: username, password: password) // 将数据缓存到keychain if let data = "\(username):\(password)".data(using: .utf8) { try KeychainStore.shared.save(data, account: "accountAndPasword") } } self.loginCredit = credit return true } func loadCacheToken() -> String? { if let data = try? KeychainStore.shared.load(account: "token") { return String(data: data, encoding: .utf8) } return nil } func loadCacheUsernameAndPassword() -> (String, String)? { if let data = try? KeychainStore.shared.load(account: "accountAndPasword"), let str = String(data: data, encoding: .utf8) { let parts = str.split(separator: ":") if parts.count == 2 { return (String(parts[0]), String(parts[1])) } } return nil } // 退出登陆 func logout() async throws { try await VPNManager.shared.disableVpn() } }