Skip to content

Commit 095bf83

Browse files
committed
feat: support disabling the built-in updater
1 parent de4b0e5 commit 095bf83

File tree

2 files changed

+48
-24
lines changed

2 files changed

+48
-24
lines changed

Coder-Desktop/Coder-Desktop/UpdaterService.swift

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,64 @@ import Sparkle
22
import SwiftUI
33

44
final class UpdaterService: NSObject, ObservableObject {
5-
private lazy var inner: SPUStandardUpdaterController = .init(
6-
startingUpdater: true,
7-
updaterDelegate: self,
8-
userDriverDelegate: self
9-
)
10-
private var updater: SPUUpdater!
5+
6+
// The auto-updater can be entirely disabled by setting the
7+
// `disableUpdater` UserDefaults key to `true`. This is designed for use in
8+
// MDM configurations, where the value can be set to `true` permanently.
9+
@Published var disabled: Bool = UserDefaults.standard.bool(forKey: Keys.disableUpdater) {
10+
didSet {
11+
UserDefaults.standard.set(disabled, forKey: Keys.disableUpdater)
12+
}
13+
}
14+
1115
@Published var canCheckForUpdates = true
1216

1317
@Published var autoCheckForUpdates: Bool! {
1418
didSet {
1519
if let autoCheckForUpdates, autoCheckForUpdates != oldValue {
16-
updater.automaticallyChecksForUpdates = autoCheckForUpdates
20+
inner?.updater.automaticallyChecksForUpdates = autoCheckForUpdates
1721
}
1822
}
1923
}
2024

2125
@Published var updateChannel: UpdateChannel {
2226
didSet {
23-
UserDefaults.standard.set(updateChannel.rawValue, forKey: Self.updateChannelKey)
27+
UserDefaults.standard.set(updateChannel.rawValue, forKey: Keys.updateChannel)
2428
}
2529
}
30+
private var inner: (controller: SPUStandardUpdaterController, updater: SPUUpdater)?
2631

27-
static let updateChannelKey = "updateChannel"
2832

2933
override init() {
30-
updateChannel = UserDefaults.standard.string(forKey: Self.updateChannelKey)
34+
updateChannel = UserDefaults.standard.string(forKey: Keys.updateChannel)
3135
.flatMap { UpdateChannel(rawValue: $0) } ?? .stable
3236
super.init()
33-
updater = inner.updater
37+
38+
guard !disabled else {
39+
return
40+
}
41+
42+
let inner = SPUStandardUpdaterController(
43+
startingUpdater: true,
44+
updaterDelegate: self,
45+
userDriverDelegate: self
46+
)
47+
48+
let updater = inner.updater
49+
self.inner = (inner, updater)
50+
3451
autoCheckForUpdates = updater.automaticallyChecksForUpdates
3552
updater.publisher(for: \.canCheckForUpdates).assign(to: &$canCheckForUpdates)
3653
}
3754

3855
func checkForUpdates() {
39-
guard canCheckForUpdates else { return }
40-
updater.checkForUpdates()
56+
guard let inner, canCheckForUpdates else { return }
57+
inner.updater.checkForUpdates()
58+
}
59+
60+
enum Keys {
61+
static let disableUpdater = "disableUpdater"
62+
static let updateChannel = "updateChannel"
4163
}
4264
}
4365

Coder-Desktop/Coder-Desktop/Views/Settings/GeneralTab.swift

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,20 @@ struct GeneralTab: View {
1919
Text("Start Coder Connect on launch")
2020
}
2121
}
22-
Section {
23-
Toggle(isOn: $updater.autoCheckForUpdates) {
24-
Text("Automatically check for updates")
25-
}
26-
Picker("Update channel", selection: $updater.updateChannel) {
27-
ForEach(UpdateChannel.allCases) { channel in
28-
Text(channel.name).tag(channel)
22+
if !updater.disabled {
23+
Section {
24+
Toggle(isOn: $updater.autoCheckForUpdates) {
25+
Text("Automatically check for updates")
26+
}
27+
Picker("Update channel", selection: $updater.updateChannel) {
28+
ForEach(UpdateChannel.allCases) { channel in
29+
Text(channel.name).tag(channel)
30+
}
31+
}
32+
HStack {
33+
Spacer()
34+
Button("Check for updates") { updater.checkForUpdates() }.disabled(!updater.canCheckForUpdates)
2935
}
30-
}
31-
HStack {
32-
Spacer()
33-
Button("Check for updates") { updater.checkForUpdates() }.disabled(!updater.canCheckForUpdates)
3436
}
3537
}
3638
}.formStyle(.grouped)

0 commit comments

Comments
 (0)