import Foundation import Darwin struct SettingsRuntime: Equatable { let appName: String let marketingVersion: String let buildVersion: String let platform: String let deviceModel: String } @MainActor final class SettingsViewModel: ObservableObject { @Published private(set) var runtime: SettingsRuntime? @Published private(set) var isLoading = false @Published var storageLabel = "--" @Published var notice: String? @Published var errorMessage: String? private let store: any LogStore init(store: any LogStore) { self.store = store } func refresh() async { isLoading = true errorMessage = nil runtime = SettingsRuntime( appName: AppMetadata.name, marketingVersion: AppMetadata.marketingVersion, buildVersion: AppMetadata.buildVersion, platform: "iOS", deviceModel: Self.deviceModel() ) await loadStorageLabel() isLoading = false } func clearRuntimeLogs() async -> Int { do { let removed = try await store.clearRuntimeLogs() notice = removed > 0 ? "已清除 \(removed) 条运行日志。" : "没有可清除的运行日志。" errorMessage = nil await loadStorageLabel() return removed } catch { notice = nil errorMessage = "清除运行日志失败。" return 0 } } private func loadStorageLabel() async { do { let runtimeCount = try await store.runtimeLogs().count let connectionCount = try await store.connectionLogs().count storageLabel = "\(runtimeCount) 条运行日志 · \(connectionCount) 条连接日志" } catch { storageLabel = "--" errorMessage = "无法读取本地数据状态。" } } private static func deviceModel() -> String { var systemInfo = utsname() guard uname(&systemInfo) == 0 else { return "未知设备" } let bytes = withUnsafeBytes(of: systemInfo.machine) { Data($0) } let model = String( decoding: bytes.prefix { $0 != 0 }, as: UTF8.self ) return model.isEmpty ? "未知设备" : model } }