mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-02-06 20:28:39 +01:00
- Define enumerations for preferences that can be managed in an enterprise environment using MDM - Add methods in AppState to check for managed preferences - Update Advanced, Download, Experiments and Update preference panes to disable controls to modify any of the managed preferences - Update Xcode category list button to be disabled if preference is managed
162 lines
5.8 KiB
Swift
162 lines
5.8 KiB
Swift
import AppleAPI
|
|
import Sparkle
|
|
import SwiftUI
|
|
|
|
struct UpdatesPreferencePane: View {
|
|
@EnvironmentObject var updater: ObservableUpdater
|
|
|
|
@AppStorage("autoInstallation") var autoInstallationType: AutoInstallationType = .none
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 20) {
|
|
GroupBox(label: Text("Versions")) {
|
|
VStack(alignment: .leading) {
|
|
Toggle(
|
|
"AutomaticInstallNewVersion",
|
|
isOn: $autoInstallationType.isAutoInstalling
|
|
)
|
|
.disabled(updater.disableAutoInstallNewVersions)
|
|
|
|
Toggle(
|
|
"IncludePreRelease",
|
|
isOn: $autoInstallationType.isAutoInstallingBeta
|
|
)
|
|
.disabled(updater.disableIncludePrereleaseVersions)
|
|
}
|
|
.fixedSize(horizontal: false, vertical: true)
|
|
}
|
|
.groupBoxStyle(PreferencesGroupBoxStyle())
|
|
|
|
Divider()
|
|
|
|
GroupBox(label: Text("AppUpdates")) {
|
|
VStack(alignment: .leading) {
|
|
Toggle(
|
|
"CheckForAppUpdates",
|
|
isOn: $updater.automaticallyChecksForUpdates
|
|
)
|
|
.fixedSize(horizontal: true, vertical: false)
|
|
.disabled(updater.disableAutoUpdateXcodesApp)
|
|
|
|
Toggle(
|
|
"IncludePreRelease",
|
|
isOn: $updater.includePrereleaseVersions
|
|
)
|
|
.disabled(updater.disableAutoUpdateXcodesAppPrereleaseVersions)
|
|
|
|
Button("CheckNow") {
|
|
updater.checkForUpdates()
|
|
}
|
|
.padding(.top)
|
|
.disabled(updater.disableAutoUpdateXcodesApp)
|
|
|
|
Text(String(format: localizeString("LastChecked"), lastUpdatedString))
|
|
.font(.footnote)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
}
|
|
.groupBoxStyle(PreferencesGroupBoxStyle())
|
|
}
|
|
}
|
|
|
|
private var lastUpdatedString: String {
|
|
if let lastUpdatedDate = updater.lastUpdateCheckDate {
|
|
return Self.formatter.string(from: lastUpdatedDate)
|
|
} else {
|
|
return localizeString("Never")
|
|
}
|
|
}
|
|
|
|
private static let formatter = configure(DateFormatter()) {
|
|
$0.dateStyle = .medium
|
|
$0.timeStyle = .medium
|
|
}
|
|
}
|
|
|
|
class ObservableUpdater: ObservableObject {
|
|
private let updater: SPUUpdater
|
|
private let updaterDelegate = UpdaterDelegate()
|
|
|
|
@Published var automaticallyChecksForUpdates = false {
|
|
didSet {
|
|
updater.automaticallyChecksForUpdates = automaticallyChecksForUpdates
|
|
}
|
|
}
|
|
private var automaticallyChecksForUpdatesObservation: NSKeyValueObservation?
|
|
@Published var lastUpdateCheckDate: Date?
|
|
private var lastUpdateCheckDateObservation: NSKeyValueObservation?
|
|
@Published var includePrereleaseVersions = false {
|
|
didSet {
|
|
Current.defaults.set(includePrereleaseVersions, forKey: "includePrereleaseVersions")
|
|
|
|
updaterDelegate.includePrereleaseVersions = includePrereleaseVersions
|
|
}
|
|
}
|
|
|
|
var disableAutoInstallNewVersions: Bool { PreferenceKey.autoInstallation.isManaged() }
|
|
var disableIncludePrereleaseVersions: Bool { PreferenceKey.autoInstallation.isManaged() }
|
|
|
|
var disableAutoUpdateXcodesApp: Bool { PreferenceKey.SUEnableAutomaticChecks.isManaged() }
|
|
var disableAutoUpdateXcodesAppPrereleaseVersions: Bool { PreferenceKey.includePrereleaseVersions.isManaged() }
|
|
|
|
init() {
|
|
updater = SPUStandardUpdaterController(startingUpdater: true, updaterDelegate: updaterDelegate, userDriverDelegate: nil).updater
|
|
|
|
// upgrade from an old sparkle version which set feeds via the updater
|
|
// now it uses the `updaterDelegate`
|
|
updater.clearFeedURLFromUserDefaults()
|
|
|
|
automaticallyChecksForUpdatesObservation = updater.observe(
|
|
\.automaticallyChecksForUpdates,
|
|
options: [.initial, .new, .old],
|
|
changeHandler: { [unowned self] updater, change in
|
|
guard change.newValue != change.oldValue else { return }
|
|
self.automaticallyChecksForUpdates = updater.automaticallyChecksForUpdates
|
|
}
|
|
)
|
|
lastUpdateCheckDateObservation = updater.observe(
|
|
\.lastUpdateCheckDate,
|
|
options: [.initial, .new, .old],
|
|
changeHandler: { [unowned self] updater, change in
|
|
self.lastUpdateCheckDate = updater.lastUpdateCheckDate
|
|
}
|
|
)
|
|
includePrereleaseVersions = Current.defaults.bool(forKey: "includePrereleaseVersions") ?? false
|
|
}
|
|
|
|
func checkForUpdates() {
|
|
updater.checkForUpdates()
|
|
}
|
|
}
|
|
|
|
class UpdaterDelegate: NSObject, SPUUpdaterDelegate {
|
|
var includePrereleaseVersions: Bool = false
|
|
|
|
func feedURLString(for updater: SPUUpdater) -> String? {
|
|
if includePrereleaseVersions {
|
|
return .prereleaseAppcast
|
|
} else {
|
|
return .appcast
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
extension String {
|
|
static let appcast = "https://www.xcodes.app/appcast.xml"
|
|
static let prereleaseAppcast = "https://www.xcodes.app/appcast_pre.xml"
|
|
}
|
|
|
|
struct UpdatesPreferencePane_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
Group {
|
|
UpdatesPreferencePane()
|
|
.environmentObject(AppState())
|
|
.environmentObject(ObservableUpdater())
|
|
.frame(maxWidth: 600)
|
|
.frame(minHeight: 300)
|
|
}
|
|
}
|
|
}
|