included Sparkle
This commit is contained in:
95
Sources/ViewModels/UpdateViewModel.swift
Normal file
95
Sources/ViewModels/UpdateViewModel.swift
Normal file
@@ -0,0 +1,95 @@
|
||||
import Foundation
|
||||
#if os(macOS)
|
||||
import AppKit
|
||||
#endif
|
||||
|
||||
@MainActor
|
||||
final class UpdateViewModel: ObservableObject {
|
||||
struct StatusAlert: Identifiable {
|
||||
let id = UUID()
|
||||
let title: String
|
||||
let message: String
|
||||
}
|
||||
|
||||
@Published var availableRelease: ReleaseInfo?
|
||||
@Published var latestFetchedRelease: ReleaseInfo?
|
||||
@Published var statusAlert: StatusAlert?
|
||||
@Published var isChecking = false
|
||||
|
||||
private let service: UpdateService
|
||||
private let userDefaults: UserDefaults
|
||||
private let autoCheckKey = "autoCheckUpdates"
|
||||
private let includePrereleaseKey = "includePrereleaseUpdates"
|
||||
|
||||
init(service: UpdateService = UpdateService(), userDefaults: UserDefaults = .standard) {
|
||||
self.service = service
|
||||
self.userDefaults = userDefaults
|
||||
registerDefaultsIfNeeded()
|
||||
}
|
||||
|
||||
func startAutomaticCheckIfNeeded() {
|
||||
if userDefaults.bool(forKey: autoCheckKey) {
|
||||
checkForUpdates(userInitiated: false)
|
||||
}
|
||||
}
|
||||
|
||||
func checkForUpdates(userInitiated: Bool) {
|
||||
guard !isChecking else { return }
|
||||
isChecking = true
|
||||
|
||||
Task {
|
||||
do {
|
||||
let release = try await service.fetchLatestRelease(includePrerelease: userDefaults.bool(forKey: includePrereleaseKey))
|
||||
handle(release: release, userInitiated: userInitiated)
|
||||
} catch {
|
||||
if userInitiated {
|
||||
statusAlert = StatusAlert(
|
||||
title: "Update Check Failed",
|
||||
message: error.localizedDescription
|
||||
)
|
||||
}
|
||||
}
|
||||
self.isChecking = false
|
||||
}
|
||||
}
|
||||
|
||||
func openReleaseNotes() {
|
||||
guard let releaseURL = availableRelease?.releaseURL ?? latestFetchedRelease?.releaseURL else { return }
|
||||
#if os(macOS)
|
||||
NSWorkspace.shared.open(releaseURL)
|
||||
#endif
|
||||
}
|
||||
|
||||
func downloadLatest() {
|
||||
let release = availableRelease ?? latestFetchedRelease
|
||||
availableRelease = nil
|
||||
guard let downloadURL = release?.downloadURL else { return }
|
||||
#if os(macOS)
|
||||
NSWorkspace.shared.open(downloadURL)
|
||||
#endif
|
||||
}
|
||||
|
||||
private func handle(release: ReleaseInfo, userInitiated: Bool) {
|
||||
let currentVersion = VersionNumber(
|
||||
Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "0.0.0"
|
||||
)
|
||||
|
||||
latestFetchedRelease = release
|
||||
|
||||
if release.version > currentVersion {
|
||||
availableRelease = release
|
||||
} else if userInitiated {
|
||||
statusAlert = StatusAlert(
|
||||
title: "You're Up To Date",
|
||||
message: "iKeyMon \(currentVersion.rawValue) is the latest version."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private func registerDefaultsIfNeeded() {
|
||||
userDefaults.register(defaults: [
|
||||
autoCheckKey: true,
|
||||
includePrereleaseKey: true
|
||||
])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user