feat: 更新素材管理和举报风险地图
This commit is contained in:
87
suixinkan/Features/Setting/ViewModels/SettingViewModel.swift
Normal file
87
suixinkan/Features/Setting/ViewModels/SettingViewModel.swift
Normal file
@ -0,0 +1,87 @@
|
||||
//
|
||||
// SettingViewModel.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// 设置中心 ViewModel,管理版本展示、协议入口和更新标记。
|
||||
final class SettingViewModel {
|
||||
private let infoDictionary: [String: Any]?
|
||||
private let environment: APIEnvironment
|
||||
|
||||
private(set) var latestVersion: VersionResponse?
|
||||
private(set) var hasNewVersion = false
|
||||
|
||||
var onStateChange: (() -> Void)?
|
||||
|
||||
init(
|
||||
infoDictionary: [String: Any]? = Bundle.main.infoDictionary,
|
||||
environment: APIEnvironment = .current
|
||||
) {
|
||||
self.infoDictionary = infoDictionary
|
||||
self.environment = environment
|
||||
}
|
||||
|
||||
var appVersion: String {
|
||||
AppClientInfo.appVersion(infoDictionary: infoDictionary)
|
||||
}
|
||||
|
||||
var appDownloadURL: URL {
|
||||
environment.baseURL.appending(path: "h5/app/download")
|
||||
}
|
||||
|
||||
/// 静默检查最新版本,失败时保持当前页面状态。
|
||||
func checkLatestVersion(api: SettingAPI) async {
|
||||
do {
|
||||
let response = try await api.checkLatestVersion()
|
||||
latestVersion = response
|
||||
hasNewVersion = Self.isNewerVersionCode(response.versionCode, than: currentVersionCode(infoDictionary: infoDictionary))
|
||||
notifyStateChange()
|
||||
} catch is CancellationError {
|
||||
return
|
||||
} catch {
|
||||
latestVersion = nil
|
||||
hasNewVersion = false
|
||||
notifyStateChange()
|
||||
}
|
||||
}
|
||||
|
||||
/// 返回指定协议入口的标题和 URL。
|
||||
func agreementDestination(for kind: SettingAgreementKind) -> SettingAgreementDestination {
|
||||
switch kind {
|
||||
case .aboutUs:
|
||||
SettingAgreementDestination(
|
||||
title: "关于我们",
|
||||
url: environment.baseURL.appending(path: "h5/app/about-us")
|
||||
)
|
||||
case .userAgreement:
|
||||
SettingAgreementDestination(
|
||||
title: "用户协议",
|
||||
url: environment.baseURL.appending(path: "h5/app/user-agreement")
|
||||
)
|
||||
case .privacyPolicy:
|
||||
SettingAgreementDestination(
|
||||
title: "隐私政策",
|
||||
url: environment.baseURL.appending(path: "h5/app/privacy-policy")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// 判断后端版本号是否高于当前构建号。
|
||||
nonisolated static func isNewerVersionCode(_ latestVersionCode: Int, than currentVersionCode: Int?) -> Bool {
|
||||
guard let currentVersionCode else { return false }
|
||||
return latestVersionCode > currentVersionCode
|
||||
}
|
||||
|
||||
private func currentVersionCode(infoDictionary: [String: Any]?) -> Int? {
|
||||
let build = (infoDictionary?["CFBundleVersion"] as? String)?
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard let build, !build.isEmpty else { return nil }
|
||||
return Int(build)
|
||||
}
|
||||
|
||||
private func notifyStateChange() {
|
||||
onStateChange?()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user