@capgo/capacitor-updater 8.47.8 → 8.47.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -79,7 +79,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
79
79
  CAPPluginMethod(name: "completeFlexibleUpdate", returnType: CAPPluginReturnPromise)
80
80
  ]
81
81
  public var implementation = CapgoUpdater()
82
- private let pluginVersion: String = "8.47.8"
82
+ private let pluginVersion: String = "8.47.9"
83
83
  static let updateUrlDefault = "https://plugin.capgo.app/updates"
84
84
  static let statsUrlDefault = "https://plugin.capgo.app/stats"
85
85
  static let channelUrlDefault = "https://plugin.capgo.app/channel_self"
@@ -989,6 +989,29 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
989
989
  }
990
990
  }
991
991
 
992
+ func reloadWithoutWaitingForAppReady() -> Bool {
993
+ guard let bridge = self.bridge else { return false }
994
+
995
+ let performReload: () -> Bool = {
996
+ guard self.applyCurrentBundleToBridge(bridge) else {
997
+ return false
998
+ }
999
+ self.checkAppReady()
1000
+ self.notifyListeners("appReloaded", data: [:])
1001
+ return true
1002
+ }
1003
+
1004
+ if Thread.isMainThread {
1005
+ return performReload()
1006
+ } else {
1007
+ var result = false
1008
+ DispatchQueue.main.sync {
1009
+ result = performReload()
1010
+ }
1011
+ return result
1012
+ }
1013
+ }
1014
+
992
1015
  @objc func reload(_ call: CAPPluginCall) {
993
1016
  let current: BundleInfo = self.implementation.getCurrentBundle()
994
1017
  let next: BundleInfo? = self.implementation.getNextBundle()
@@ -1206,7 +1229,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1206
1229
  }
1207
1230
 
1208
1231
  let previewFallbackBundle = self.implementation.getPreviewFallbackBundle()
1209
- self.endPreviewSession()
1232
+ self.endPreviewSession(keepPreviewGuard: true)
1210
1233
  let restoredNextBundle = self.implementation.getNextBundle()
1211
1234
  self.deletePreviewBundleIfUnused(previewBundle, previewFallbackBundle: previewFallbackBundle, restoredNextBundle: restoredNextBundle)
1212
1235
  return true
@@ -1232,12 +1255,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1232
1255
 
1233
1256
  private func leavePreviewSessionWithoutReload(keepPreviewGuard: Bool = false) -> Bool {
1234
1257
  let previewBundle = self.implementation.getCurrentBundle()
1235
- guard let previewFallbackBundle = self.implementation.getPreviewFallbackBundle(), !previewFallbackBundle.isErrorStatus() else {
1236
- logger.error("No preview fallback bundle available")
1237
- return false
1238
- }
1239
- guard self.implementation.canSet(bundle: previewFallbackBundle) else {
1240
- logger.error("Preview fallback bundle is not installable")
1258
+ guard let previewFallbackBundle = self.resolvePreviewFallbackBundle(reason: "preview deeplink launch") else {
1241
1259
  return false
1242
1260
  }
1243
1261
  guard self.implementation.stagePreviewFallbackReload(bundle: previewFallbackBundle) else {
@@ -1254,14 +1272,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1254
1272
  private func leavePreviewSessionForIncomingPreviewLink() -> Bool {
1255
1273
  self.showPreviewTransitionLoader(reason: "incoming-preview-deeplink")
1256
1274
  let previewBundle = self.implementation.getCurrentBundle()
1257
- guard let previewFallbackBundle = self.implementation.getPreviewFallbackBundle(), !previewFallbackBundle.isErrorStatus() else {
1258
- logger.error("No preview fallback bundle available")
1259
- self.clearIncomingPreviewTransition()
1260
- self.hidePreviewTransitionLoader(reason: "incoming-preview-deeplink-failed")
1261
- return false
1262
- }
1263
- guard self.implementation.canSet(bundle: previewFallbackBundle) else {
1264
- logger.error("Preview fallback bundle is not installable")
1275
+ guard let previewFallbackBundle = self.resolvePreviewFallbackBundle(reason: "incoming preview deeplink") else {
1265
1276
  self.clearIncomingPreviewTransition()
1266
1277
  self.hidePreviewTransitionLoader(reason: "incoming-preview-deeplink-failed")
1267
1278
  return false
@@ -1275,7 +1286,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1275
1286
  return false
1276
1287
  }
1277
1288
 
1278
- let didReload = self._reload()
1289
+ let didReload = self.reloadWithoutWaitingForAppReady()
1279
1290
  if didReload {
1280
1291
  self.endPreviewSession(keepPreviewGuard: true)
1281
1292
  let restoredNextBundle = self.implementation.getNextBundle()
@@ -1312,7 +1323,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1312
1323
  if let payloadUrl = self.storedPreviewPayloadUrl() {
1313
1324
  didReload = self.refreshPreviewSessionFromPayloadUrl(payloadUrl)
1314
1325
  } else {
1315
- didReload = self._reload()
1326
+ didReload = self.reloadWithoutWaitingForAppReady()
1316
1327
  }
1317
1328
 
1318
1329
  if !didReload {
@@ -1325,21 +1336,16 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1325
1336
  self.previewSessionEnabled
1326
1337
  }
1327
1338
 
1328
- private func resetToPreviewFallbackBundle() -> Bool {
1339
+ func resetToPreviewFallbackBundle() -> Bool {
1329
1340
  guard self.canPerformResetTransition() else { return false }
1330
- guard let fallback = self.implementation.getPreviewFallbackBundle(), !fallback.isErrorStatus() else {
1331
- logger.error("No preview fallback bundle available")
1332
- return false
1333
- }
1334
- guard self.implementation.canSet(bundle: fallback) else {
1335
- logger.error("Preview fallback bundle is not installable")
1341
+ guard let fallback = self.resolvePreviewFallbackBundle(reason: "leave preview") else {
1336
1342
  return false
1337
1343
  }
1338
1344
 
1339
1345
  let previousState = self.implementation.captureResetState()
1340
1346
  let previousBundleName = self.implementation.getCurrentBundle().getVersionName()
1341
1347
  logger.info("Resetting to preview fallback bundle: \(fallback.toString())")
1342
- if self.implementation.stagePreviewFallbackReload(bundle: fallback) && self._reload() {
1348
+ if self.implementation.stagePreviewFallbackReload(bundle: fallback) && self.reloadWithoutWaitingForAppReady() {
1343
1349
  self.implementation.finalizeResetTransition(previousBundleName: previousBundleName, isInternal: false)
1344
1350
  self.notifyBundleSet(fallback)
1345
1351
  return true
@@ -1349,11 +1355,36 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1349
1355
  return false
1350
1356
  }
1351
1357
 
1358
+ private func resolvePreviewFallbackBundle(reason: String) -> BundleInfo? {
1359
+ let fallback = self.implementation.getPreviewFallbackBundle()
1360
+ if let fallback, !fallback.isErrorStatus(), self.implementation.canSet(bundle: fallback) {
1361
+ return fallback
1362
+ }
1363
+
1364
+ if let fallback {
1365
+ if fallback.isErrorStatus() {
1366
+ logger.warn("Preview fallback bundle is in error state for \(reason). Falling back to builtin bundle.")
1367
+ } else {
1368
+ logger.warn("Preview fallback bundle is not installable for \(reason). Falling back to builtin bundle.")
1369
+ }
1370
+ } else {
1371
+ logger.warn("No preview fallback bundle available for \(reason). Falling back to builtin bundle.")
1372
+ }
1373
+
1374
+ let builtin = self.implementation.getBundleInfo(id: BundleInfo.ID_BUILTIN)
1375
+ if !builtin.isErrorStatus(), self.implementation.canSet(bundle: builtin) {
1376
+ return builtin
1377
+ }
1378
+
1379
+ logger.error("Builtin bundle is not available to leave preview for \(reason)")
1380
+ return nil
1381
+ }
1382
+
1352
1383
  private func endPreviewSession(keepPreviewGuard: Bool = false) {
1353
1384
  let previousShakeMenuEnabled = UserDefaults.standard.object(forKey: self.previewPreviousShakeMenuDefaultsKey) as? Bool
1354
- ?? getConfig().getBoolean("shakeMenu", false)
1385
+ ?? self.getBooleanConfig("shakeMenu", defaultValue: false)
1355
1386
  let previousShakeChannelSelectorEnabled = UserDefaults.standard.object(forKey: self.previewPreviousShakeChannelSelectorDefaultsKey) as? Bool
1356
- ?? getConfig().getBoolean("allowShakeChannelSelector", false)
1387
+ ?? self.getBooleanConfig("allowShakeChannelSelector", defaultValue: false)
1357
1388
  self.restorePreviewPreviousNextBundle()
1358
1389
  self.restorePreviewPreviousAppId()
1359
1390
  self.restorePreviewPreviousDefaultChannel()
@@ -1374,15 +1405,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1374
1405
 
1375
1406
  private func clearPreviewSessionBecauseDisabled() {
1376
1407
  logger.info("Preview session disabled by config; restoring preview fallback")
1377
- let fallback = self.implementation.getPreviewFallbackBundle()
1378
- let bundleToRestore: BundleInfo
1379
- if let fallback, !fallback.isErrorStatus() {
1380
- bundleToRestore = fallback
1381
- } else {
1382
- bundleToRestore = self.implementation.getBundleInfo(id: BundleInfo.ID_BUILTIN)
1383
- }
1384
-
1385
- if self.implementation.canSet(bundle: bundleToRestore) {
1408
+ if let bundleToRestore = self.resolvePreviewFallbackBundle(reason: "preview disabled") {
1386
1409
  _ = self.implementation.stagePreviewFallbackReload(bundle: bundleToRestore)
1387
1410
  } else {
1388
1411
  logger.warn("Could not restore preview fallback while disabling preview")
@@ -1396,11 +1419,25 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1396
1419
  self.isLeavingPreviewForIncomingLink = false
1397
1420
  self.implementation.previewSession = false
1398
1421
  self.hidePreviewTransitionLoader(reason: "preview-session-disabled")
1399
- self.shakeMenuEnabled = getConfig().getBoolean("shakeMenu", false)
1400
- self.shakeChannelSelectorEnabled = getConfig().getBoolean("allowShakeChannelSelector", false)
1422
+ self.shakeMenuEnabled = self.getBooleanConfig("shakeMenu", defaultValue: false)
1423
+ self.shakeChannelSelectorEnabled = self.getBooleanConfig("allowShakeChannelSelector", defaultValue: false)
1401
1424
  self.clearPreviewSessionPreferences()
1402
1425
  }
1403
1426
 
1427
+ private func getBooleanConfig(_ key: String, defaultValue: Bool) -> Bool {
1428
+ guard self.bridge != nil else {
1429
+ return defaultValue
1430
+ }
1431
+ return getConfig().getBoolean(key, defaultValue)
1432
+ }
1433
+
1434
+ private func getStringConfig(_ key: String, defaultValue: String) -> String {
1435
+ guard self.bridge != nil else {
1436
+ return defaultValue
1437
+ }
1438
+ return getConfig().getString(key, defaultValue) ?? defaultValue
1439
+ }
1440
+
1404
1441
  private func clearPreviewSessionPreferences() {
1405
1442
  _ = self.implementation.setPreviewFallbackBundle(fallback: nil)
1406
1443
  UserDefaults.standard.removeObject(forKey: self.previewSessionDefaultsKey)
@@ -1426,7 +1463,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1426
1463
  }
1427
1464
 
1428
1465
  private func restorePreviewPreviousDefaultChannel() {
1429
- let configDefaultChannel = self.getConfig().getString("defaultChannel", "")!
1466
+ let configDefaultChannel = self.getStringConfig("defaultChannel", defaultValue: "")
1430
1467
  let hadPreviousDefaultChannel = UserDefaults.standard.object(forKey: self.previewPreviousDefaultChannelWasSetDefaultsKey) as? Bool ?? false
1431
1468
 
1432
1469
  guard hadPreviousDefaultChannel,
@@ -1579,7 +1616,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1579
1616
  let current = self.implementation.getCurrentBundle()
1580
1617
  if current.getVersionName() == version {
1581
1618
  self.logger.info("Preview payload unchanged, reloading current bundle")
1582
- return self._reload()
1619
+ return self.reloadWithoutWaitingForAppReady()
1583
1620
  }
1584
1621
 
1585
1622
  let next = try self.downloadBundle(
@@ -1597,7 +1634,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1597
1634
  }
1598
1635
 
1599
1636
  self.notifyBundleSet(next)
1600
- return self._reload()
1637
+ return self.reloadWithoutWaitingForAppReady()
1601
1638
  } catch {
1602
1639
  self.logger.error("Could not refresh preview session: \(error.localizedDescription)")
1603
1640
  return false
@@ -1613,8 +1650,8 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1613
1650
  self.previewSessionAlertPending = false
1614
1651
  self.isLeavingPreviewForIncomingLink = false
1615
1652
  self.implementation.previewSession = false
1616
- self.shakeMenuEnabled = getConfig().getBoolean("shakeMenu", false)
1617
- self.shakeChannelSelectorEnabled = getConfig().getBoolean("allowShakeChannelSelector", false)
1653
+ self.shakeMenuEnabled = self.getBooleanConfig("shakeMenu", defaultValue: false)
1654
+ self.shakeChannelSelectorEnabled = self.getBooleanConfig("allowShakeChannelSelector", defaultValue: false)
1618
1655
  self.restorePreviewPreviousAppId()
1619
1656
  self.restorePreviewPreviousDefaultChannel()
1620
1657
  _ = self.implementation.setPreviewFallbackBundle(fallback: nil)
@@ -1885,7 +1922,13 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1885
1922
  let triggerAutoUpdate = call.getBool("triggerAutoUpdate") ?? false
1886
1923
  self.saveCallForAsyncHandling(call)
1887
1924
  DispatchQueue.global(qos: .utility).async {
1888
- let res = self.implementation.setChannel(channel: channel, defaultChannelKey: self.defaultChannelDefaultsKey, allowSetDefaultChannel: self.allowSetDefaultChannel)
1925
+ let configDefaultChannel = self.getConfig().getString("defaultChannel", "")!
1926
+ let res = self.implementation.setChannel(
1927
+ channel: channel,
1928
+ defaultChannelKey: self.defaultChannelDefaultsKey,
1929
+ allowSetDefaultChannel: self.allowSetDefaultChannel,
1930
+ configDefaultChannel: configDefaultChannel
1931
+ )
1889
1932
  if res.error != "" {
1890
1933
  // Fire channelPrivate event if channel doesn't allow self-assignment
1891
1934
  if res.error.contains("cannot_update_via_private_channel") || res.error.contains("channel_self_set_not_allowed") {
@@ -1916,7 +1959,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
1916
1959
  @objc func getChannel(_ call: CAPPluginCall) {
1917
1960
  self.saveCallForAsyncHandling(call)
1918
1961
  DispatchQueue.global(qos: .utility).async {
1919
- let res = self.implementation.getChannel()
1962
+ let res = self.implementation.getChannel(defaultChannelKey: self.defaultChannelDefaultsKey)
1920
1963
  if res.error != "" {
1921
1964
  self.rejectCall(call, message: res.error, code: "GETCHANNEL_FAILED", data: [
1922
1965
  "message": res.error,
@@ -2151,7 +2151,12 @@ import UIKit
2151
2151
  return setChannel
2152
2152
  }
2153
2153
 
2154
- func setChannel(channel: String, defaultChannelKey: String, allowSetDefaultChannel: Bool) -> SetChannel {
2154
+ func setChannel(
2155
+ channel: String,
2156
+ defaultChannelKey: String,
2157
+ allowSetDefaultChannel: Bool,
2158
+ configDefaultChannel: String = ""
2159
+ ) -> SetChannel {
2155
2160
  let setChannel: SetChannel = SetChannel()
2156
2161
 
2157
2162
  // Check if setting defaultChannel is allowed
@@ -2231,6 +2236,7 @@ import UIKit
2231
2236
  } else if responseValue.unset == true {
2232
2237
  UserDefaults.standard.removeObject(forKey: defaultChannelKey)
2233
2238
  UserDefaults.standard.synchronize()
2239
+ self.defaultChannel = configDefaultChannel
2234
2240
  self.logger.info("Public channel requested, channel override removed")
2235
2241
 
2236
2242
  setChannel.status = responseValue.status ?? "ok"
@@ -2247,7 +2253,7 @@ import UIKit
2247
2253
  return setChannel
2248
2254
  }
2249
2255
 
2250
- func getChannel() -> GetChannel {
2256
+ func getChannel(defaultChannelKey: String? = nil) -> GetChannel {
2251
2257
  let getChannel: GetChannel = GetChannel()
2252
2258
 
2253
2259
  // Check if rate limit was exceeded
@@ -2334,10 +2340,26 @@ import UIKit
2334
2340
  getChannel.message = responseValue.message ?? ""
2335
2341
  getChannel.channel = responseValue.channel ?? ""
2336
2342
  getChannel.allowSet = responseValue.allowSet ?? true
2343
+ persistDefaultChannelFromResponse(channel: responseValue.channel, defaultChannelKey: defaultChannelKey)
2337
2344
  }
2338
2345
  return getChannel
2339
2346
  }
2340
2347
 
2348
+ func persistDefaultChannelFromResponse(channel: String?, defaultChannelKey: String?) {
2349
+ guard let channelName = channel?.trimmingCharacters(in: .whitespacesAndNewlines),
2350
+ !channelName.isEmpty,
2351
+ channelName != BundleInfo.ID_BUILTIN else {
2352
+ return
2353
+ }
2354
+
2355
+ self.defaultChannel = channelName
2356
+ if let defaultChannelKey, !defaultChannelKey.isEmpty {
2357
+ UserDefaults.standard.set(channelName, forKey: defaultChannelKey)
2358
+ UserDefaults.standard.synchronize()
2359
+ }
2360
+ logger.info("defaultChannel synchronized from getChannel(): \(channelName)")
2361
+ }
2362
+
2341
2363
  func listChannels() -> ListChannels {
2342
2364
  let listChannels: ListChannels = ListChannels()
2343
2365
 
@@ -7,6 +7,9 @@
7
7
  import UIKit
8
8
  import Capacitor
9
9
 
10
+ private var lastShakeMenuShownAt: TimeInterval = 0
11
+ private let shakeMenuCooldownSeconds: TimeInterval = 1.2
12
+
10
13
  extension UIApplication {
11
14
  // swiftlint:disable:next line_length
12
15
  public class func topViewController(_ base: UIViewController? = UIApplication.shared.windows.first?.rootViewController) -> UIViewController? {
@@ -43,25 +46,38 @@ extension UIWindow {
43
46
  return
44
47
  }
45
48
 
49
+ let now = Date().timeIntervalSince1970
50
+ guard now - lastShakeMenuShownAt >= shakeMenuCooldownSeconds else {
51
+ plugin.logger.info("Shake menu ignored because cooldown is active")
52
+ return
53
+ }
54
+
46
55
  if canShowPreviewMenu {
47
- showDefaultMenu(plugin: plugin, bridge: bridge)
56
+ if showDefaultMenu(plugin: plugin, bridge: bridge) {
57
+ lastShakeMenuShownAt = now
58
+ }
48
59
  } else {
49
- showChannelSelector(plugin: plugin, bridge: bridge)
60
+ if showChannelSelector(plugin: plugin, bridge: bridge) {
61
+ lastShakeMenuShownAt = now
62
+ }
50
63
  }
51
64
  }
52
65
  }
53
66
 
54
- private func showDefaultMenu(plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) {
67
+ @discardableResult
68
+ private func showDefaultMenu(plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) -> Bool {
55
69
  // Prevent multiple alerts from showing
56
- if let topVC = UIApplication.topViewController(),
57
- topVC.isKind(of: UIAlertController.self) {
70
+ guard let topVC = UIApplication.topViewController() else {
71
+ return false
72
+ }
73
+ if topVC.isKind(of: UIAlertController.self) {
58
74
  plugin.logger.info("UIAlertController is already presented")
59
- return
75
+ return false
60
76
  }
61
77
 
62
78
  guard plugin.hasActivePreviewSession() else {
63
79
  plugin.logger.info("Shake preview menu ignored because no preview session is active")
64
- return
80
+ return false
65
81
  }
66
82
 
67
83
  let appName = Bundle.main.infoDictionary?["CFBundleDisplayName"] as? String ?? "App"
@@ -96,7 +112,7 @@ extension UIWindow {
96
112
  if plugin.shakeChannelSelectorEnabled {
97
113
  alertShake.addAction(UIAlertAction(title: "Switch channel", style: .default) { _ in
98
114
  let showSelector = {
99
- self.showChannelSelector(plugin: plugin, bridge: bridge)
115
+ _ = self.showChannelSelector(plugin: plugin, bridge: bridge)
100
116
  }
101
117
 
102
118
  if let presenter = alertShake.presentingViewController {
@@ -110,10 +126,9 @@ extension UIWindow {
110
126
  alertShake.addAction(UIAlertAction(title: cancelButtonTitle, style: .default))
111
127
 
112
128
  DispatchQueue.main.async {
113
- if let topVC = UIApplication.topViewController() {
114
- topVC.present(alertShake, animated: true)
115
- }
129
+ topVC.present(alertShake, animated: true)
116
130
  }
131
+ return true
117
132
  }
118
133
 
119
134
  private func showConfiguredDefaultMenu(plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) {
@@ -179,12 +194,15 @@ extension UIWindow {
179
194
  }
180
195
  }
181
196
 
182
- private func showChannelSelector(plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) {
197
+ @discardableResult
198
+ private func showChannelSelector(plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) -> Bool {
183
199
  // Prevent multiple alerts from showing
184
- if let topVC = UIApplication.topViewController(),
185
- topVC.isKind(of: UIAlertController.self) {
200
+ guard let topVC = UIApplication.topViewController() else {
201
+ return false
202
+ }
203
+ if topVC.isKind(of: UIAlertController.self) {
186
204
  plugin.logger.info("UIAlertController is already presented")
187
- return
205
+ return false
188
206
  }
189
207
 
190
208
  let updater = plugin.implementation
@@ -208,28 +226,27 @@ extension UIWindow {
208
226
  })
209
227
 
210
228
  DispatchQueue.main.async {
211
- if let topVC = UIApplication.topViewController() {
212
- topVC.present(loadingAlert, animated: true) {
213
- // Fetch channels in background
214
- DispatchQueue.global(qos: .userInitiated).async {
215
- let result = updater.listChannels()
229
+ topVC.present(loadingAlert, animated: true) {
230
+ // Fetch channels in background
231
+ DispatchQueue.global(qos: .userInitiated).async {
232
+ let result = updater.listChannels()
216
233
 
217
- DispatchQueue.main.async {
218
- loadingAlert.dismiss(animated: true) {
219
- guard !didCancel else { return }
220
- if !result.error.isEmpty {
221
- self.showError(message: "Failed to load channels: \(result.error)", plugin: plugin)
222
- } else if result.channels.isEmpty {
223
- self.showError(message: "No channels available for self-assignment", plugin: plugin)
224
- } else {
225
- self.presentChannelPicker(channels: result.channels, plugin: plugin, bridge: bridge)
226
- }
234
+ DispatchQueue.main.async {
235
+ loadingAlert.dismiss(animated: true) {
236
+ guard !didCancel else { return }
237
+ if !result.error.isEmpty {
238
+ self.showError(message: "Failed to load channels: \(result.error)", plugin: plugin)
239
+ } else if result.channels.isEmpty {
240
+ self.showError(message: "No channels available for self-assignment", plugin: plugin)
241
+ } else {
242
+ self.presentChannelPicker(channels: result.channels, plugin: plugin, bridge: bridge)
227
243
  }
228
244
  }
229
245
  }
230
246
  }
231
247
  }
232
248
  }
249
+ return true
233
250
  }
234
251
 
235
252
  private func presentChannelPicker(channels: [[String: Any]], plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) {
@@ -338,7 +355,8 @@ extension UIWindow {
338
355
  let setResult = updater.setChannel(
339
356
  channel: name,
340
357
  defaultChannelKey: "CapacitorUpdater.defaultChannel",
341
- allowSetDefaultChannel: plugin.allowSetDefaultChannel
358
+ allowSetDefaultChannel: plugin.allowSetDefaultChannel,
359
+ configDefaultChannel: plugin.getConfig().getString("defaultChannel", "") ?? ""
342
360
  )
343
361
 
344
362
  if !setResult.error.isEmpty {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-updater",
3
- "version": "8.47.8",
3
+ "version": "8.47.10",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Live update for capacitor apps",
6
6
  "main": "dist/plugin.cjs.js",