@capgo/capacitor-updater 3.0.10 → 3.2.1-alpha.0

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.
@@ -9,22 +9,32 @@ import Version
9
9
  @objc(CapacitorUpdaterPlugin)
10
10
  public class CapacitorUpdaterPlugin: CAPPlugin {
11
11
  private var implementation = CapacitorUpdater()
12
- static let autoUpdateUrlDefault = "https://capgo.app/api/auto_update"
13
- static let statsUrlDefault = "https://capgo.app/api/stats"
12
+ static let autoUpdateUrlDefault = "https://xvwzpoazmxkqosrdewyv.functions.supabase.co/updates"
13
+ static let statsUrlDefault = "https://xvwzpoazmxkqosrdewyv.functions.supabase.co/stats"
14
+ static let DELAY_UPDATE = "delayUpdate"
14
15
  private var autoUpdateUrl = ""
16
+ private var statsUrl = ""
15
17
  private var currentVersionNative: Version = "0.0.0"
16
18
  private var autoUpdate = false
17
- private var statsUrl = ""
18
- private var resetWhenUpdate = true;
19
+ private var appReadyTimeout = 10000
20
+ private var appReadyCheck: DispatchWorkItem?
21
+ private var resetWhenUpdate = true
22
+ private var autoDeleteFailed = false
23
+ private var autoDeletePrevious = false
19
24
 
20
25
  override public func load() {
21
26
  do {
22
27
  currentVersionNative = try Version(Bundle.main.buildVersionNumber ?? "0.0.0")
23
28
  } catch {
24
- print("✨ Capacitor-updater: Cannot get version native \(currentVersionNative)")
29
+ print("\(self.implementation.TAG) Cannot get version native \(currentVersionNative)")
25
30
  }
31
+ autoDeleteFailed = getConfigValue("autoDeleteFailed") as? Bool ?? false
32
+ autoDeletePrevious = getConfigValue("autoDeletePrevious") as? Bool ?? false
26
33
  autoUpdateUrl = getConfigValue("autoUpdateUrl") as? String ?? CapacitorUpdaterPlugin.autoUpdateUrlDefault
27
34
  autoUpdate = getConfigValue("autoUpdate") as? Bool ?? false
35
+ appReadyTimeout = getConfigValue("appReadyTimeout") as? Int ?? 10000
36
+ resetWhenUpdate = getConfigValue("resetWhenUpdate") as? Bool ?? true
37
+
28
38
  implementation.appId = Bundle.main.bundleIdentifier ?? ""
29
39
  implementation.notifyDownload = notifyDownload
30
40
  let config = (self.bridge?.viewController as? CAPBridgeViewController)?.instanceDescriptor().legacyConfig
@@ -32,66 +42,83 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
32
42
  implementation.appId = config?["appId"] as! String
33
43
  }
34
44
  implementation.statsUrl = getConfigValue("statsUrl") as? String ?? CapacitorUpdaterPlugin.statsUrlDefault
35
- resetWhenUpdate = getConfigValue("resetWhenUpdate") as? Bool ?? true
45
+
36
46
  if (resetWhenUpdate) {
37
- var LatestVersionNative: Version = "0.0.0"
38
- do {
39
- LatestVersionNative = try Version(UserDefaults.standard.string(forKey: "LatestVersionNative") ?? "0.0.0")
40
- } catch {
41
- print("✨ Capacitor-updater: Cannot get version native \(currentVersionNative)")
42
- }
43
- if (LatestVersionNative != "0.0.0" && currentVersionNative.major > LatestVersionNative.major) {
44
- _ = self._reset(toAutoUpdate: false)
45
- UserDefaults.standard.set("", forKey: "LatestVersionAutoUpdate")
46
- UserDefaults.standard.set("", forKey: "LatestVersionNameAutoUpdate")
47
- let res = implementation.list()
48
- res.forEach { version in
49
- _ = implementation.delete(version: version, versionName: "")
50
- }
51
- }
52
- UserDefaults.standard.set( Bundle.main.buildVersionNumber, forKey: "LatestVersionNative")
47
+ self.cleanupObsoleteVersions()
53
48
  }
54
- if (!autoUpdate || autoUpdateUrl == "") { return }
55
49
  let nc = NotificationCenter.default
56
50
  nc.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
57
51
  nc.addObserver(self, selector: #selector(appMovedToForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
58
52
  self.appMovedToForeground()
59
53
  }
60
-
61
- @objc func notifyDownload(percent: Int) {
62
- self.notifyListeners("download", data: ["percent": percent])
54
+
55
+ private func cleanupObsoleteVersions() {
56
+ var LatestVersionNative: Version = "0.0.0"
57
+ do {
58
+ LatestVersionNative = try Version(UserDefaults.standard.string(forKey: "LatestVersionNative") ?? "0.0.0")
59
+ } catch {
60
+ print("\(self.implementation.TAG) Cannot get version native \(currentVersionNative)")
61
+ }
62
+ if (LatestVersionNative != "0.0.0" && currentVersionNative.major > LatestVersionNative.major) {
63
+ _ = self._reset(toAutoUpdate: false)
64
+ UserDefaults.standard.set("", forKey: "LatestVersionAutoUpdate")
65
+ UserDefaults.standard.set("", forKey: "LatestVersionNameAutoUpdate")
66
+ let res = implementation.list()
67
+ res.forEach { version in
68
+ print("\(self.implementation.TAG) Deleting obsolete bundle: \(version)")
69
+ _ = implementation.delete(id: version.getId())
70
+ }
71
+ }
72
+ UserDefaults.standard.set( self.currentVersionNative.description, forKey: "LatestVersionNative")
73
+ UserDefaults.standard.synchronize()
74
+ }
75
+
76
+ @objc func notifyDownload(id: String, percent: Int) {
77
+ let bundle = self.implementation.getBundleInfo(id: id)
78
+ self.notifyListeners("download", data: ["percent": percent, "bundle": bundle.toJSON()])
79
+ if (percent == 100) {
80
+ self.notifyListeners("downloadComplete", data: ["bundle": bundle.toJSON()])
81
+ }
63
82
  }
64
83
 
65
84
  @objc func getId(_ call: CAPPluginCall) {
66
85
  call.resolve(["id": implementation.deviceID])
67
86
  }
87
+
88
+ @objc func getPluginVersion(_ call: CAPPluginCall) {
89
+ call.resolve(["version": implementation.pluginVersion])
90
+ }
68
91
 
69
92
  @objc func download(_ call: CAPPluginCall) {
70
- let url = URL(string: call.getString("url") ?? "")
71
- let res = implementation.download(url: url!)
72
- if ((res) != nil) {
73
- call.resolve([
74
- "version": res!
75
- ])
76
- } else {
77
- call.reject("download failed")
93
+ guard let urlString = call.getString("url") else {
94
+ print("\(self.implementation.TAG) Download called without url")
95
+ call.reject("Download called without url")
96
+ return
97
+ }
98
+ guard let version = call.getString("version") else {
99
+ print("\(self.implementation.TAG) Download called without version")
100
+ call.reject("Download called without version")
101
+ return
102
+ }
103
+ let url = URL(string: urlString)
104
+ print("\(self.implementation.TAG) Downloading \(url!)")
105
+ do {
106
+ let res = try implementation.download(url: url!, version: version)
107
+ call.resolve(res.toJSON())
108
+ } catch {
109
+ call.reject("download failed", error.localizedDescription)
78
110
  }
79
111
  }
80
112
 
81
113
  private func _reload() -> Bool {
82
114
  guard let bridge = self.bridge else { return false }
83
-
115
+ let id = self.implementation.getCurrentBundleId()
116
+ let destHot = self.implementation.getPathHot(id: id)
117
+ print("\(self.implementation.TAG) Reloading \(id)")
84
118
  if let vc = bridge.viewController as? CAPBridgeViewController {
85
- let pathHot = implementation.getLastPathHot()
86
- let pathPersist = implementation.getLastPathPersist()
87
- if (pathHot != "" && pathPersist != "") {
88
- UserDefaults.standard.set(String(pathPersist.suffix(10)), forKey: "serverBasePath")
89
- vc.setServerBasePath(path: pathHot)
90
- print("✨ Capacitor-updater: Reload app done")
91
- return true
92
- } else {
93
- return false
94
- }
119
+ vc.setServerBasePath(path: destHot.path)
120
+ self.checkAppReady()
121
+ return true
95
122
  }
96
123
  return false
97
124
  }
@@ -100,57 +127,84 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
100
127
  if (self._reload()) {
101
128
  call.resolve()
102
129
  } else {
103
- call.reject("Cannot reload")
130
+ call.reject("Reload failed")
131
+ print("\(self.implementation.TAG) Reload failed")
132
+ }
133
+ }
134
+
135
+ @objc func next(_ call: CAPPluginCall) {
136
+ guard let id = call.getString("id") else {
137
+ print("\(self.implementation.TAG) Next called without id")
138
+ call.reject("Next called without id")
139
+ return
140
+ }
141
+
142
+ print("\(self.implementation.TAG) Setting next active id \(id)")
143
+ if (!self.implementation.setNextVersion(next: id)) {
144
+ call.reject("Set next version failed. id \(id) does not exist.")
145
+ } else {
146
+ call.resolve(self.implementation.getBundleInfo(id: id).toJSON())
104
147
  }
105
148
  }
106
149
 
107
150
  @objc func set(_ call: CAPPluginCall) {
108
- let version = call.getString("version") ?? ""
109
- let versionName = call.getString("versionName") ?? version
110
- let res = implementation.set(version: version, versionName: versionName)
111
-
112
- if (res && self._reload()) {
113
- print("✨ Capacitor-updater: Set to version: \(version) versionName: \(versionName)")
114
- call.resolve()
151
+ guard let id = call.getString("id") else {
152
+ print("\(self.implementation.TAG) Set called without id")
153
+ call.reject("Set called without id")
154
+ return
155
+ }
156
+ let res = implementation.set(id: id)
157
+ print("\(self.implementation.TAG) Set active bundle: \(id)")
158
+ if (!res) {
159
+ print("\(self.implementation.TAG) Bundle successfully set to: \(id) ")
160
+ call.reject("Update failed, id \(id) doesn't exist")
115
161
  } else {
116
- call.reject("Update failed, version \(version) doesn't exist")
162
+ self.reload(call)
117
163
  }
118
164
  }
119
165
 
120
166
  @objc func delete(_ call: CAPPluginCall) {
121
- let version = call.getString("version") ?? ""
122
- let res = implementation.delete(version: version, versionName: "")
167
+ guard let id = call.getString("id") else {
168
+ print("\(self.implementation.TAG) Delete called without version")
169
+ call.reject("Delete called without id")
170
+ return
171
+ }
172
+ let res = implementation.delete(id: id)
123
173
  if (res) {
124
174
  call.resolve()
125
175
  } else {
126
- call.reject("Delete failed, version \(version) doesn't exist")
176
+ call.reject("Delete failed, id \(id) doesn't exist")
127
177
  }
128
178
  }
129
179
 
130
180
  @objc func list(_ call: CAPPluginCall) {
131
181
  let res = implementation.list()
182
+ var resArr: [[String: String]] = []
183
+ for v in res {
184
+ resArr.append(v.toJSON())
185
+ }
132
186
  call.resolve([
133
- "versions": res
187
+ "versions": resArr
134
188
  ])
135
189
  }
136
190
 
137
191
  @objc func _reset(toAutoUpdate: Bool) -> Bool {
138
192
  guard let bridge = self.bridge else { return false }
139
193
  if let vc = bridge.viewController as? CAPBridgeViewController {
194
+ self.implementation.reset()
195
+
140
196
  let LatestVersionAutoUpdate = UserDefaults.standard.string(forKey: "LatestVersionAutoUpdate") ?? ""
141
197
  let LatestVersionNameAutoUpdate = UserDefaults.standard.string(forKey: "LatestVersionNameAutoUpdate") ?? ""
142
198
  if(toAutoUpdate && LatestVersionAutoUpdate != "" && LatestVersionNameAutoUpdate != "") {
143
- let res = implementation.set(version: LatestVersionAutoUpdate, versionName: LatestVersionNameAutoUpdate)
199
+ let res = implementation.set(id: LatestVersionNameAutoUpdate)
144
200
  return res && self._reload()
145
201
  }
146
202
  implementation.reset()
147
- let pathPersist = implementation.getLastPathPersist()
148
- vc.setServerBasePath(path: pathPersist)
149
- UserDefaults.standard.set(pathPersist, forKey: "serverBasePath")
203
+ vc.setServerBasePath(path: "")
150
204
  DispatchQueue.main.async {
151
205
  vc.loadView()
152
206
  vc.viewDidLoad()
153
- print("✨ Capacitor-updater: Reset to original version")
207
+ print("\(self.implementation.TAG) Reset to builtin version")
154
208
  }
155
209
  return true
156
210
  }
@@ -162,146 +216,203 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
162
216
  if (self._reset(toAutoUpdate: toAutoUpdate)) {
163
217
  return call.resolve()
164
218
  }
165
- call.reject("✨ Capacitor-updater: Reset failed")
166
- }
167
-
168
- @objc func versionName(_ call: CAPPluginCall) {
169
- let name = implementation.getVersionName()
170
- call.resolve([
171
- "versionName": name
172
- ])
219
+ call.reject("\(self.implementation.TAG) Reset failed")
173
220
  }
174
221
 
175
222
  @objc func current(_ call: CAPPluginCall) {
176
- let pathHot = implementation.getLastPathHot()
177
- let current = pathHot.count >= 10 ? pathHot.suffix(10) : "builtin"
223
+ let bundle: BundleInfo = self.implementation.getCurrentBundle()
178
224
  call.resolve([
179
- "current": current,
180
- "currentNative": currentVersionNative
225
+ "bundle": bundle.toJSON(),
226
+ "native": self.currentVersionNative
181
227
  ])
182
228
  }
183
229
 
184
230
  @objc func notifyAppReady(_ call: CAPPluginCall) {
185
- UserDefaults.standard.set(true, forKey: "notifyAppReady")
231
+ print("\(self.implementation.TAG) Current bundle loaded successfully. ['notifyAppReady()' was called]")
232
+ let version = self.implementation.getCurrentBundle()
233
+ self.implementation.commit(bundle: version)
186
234
  call.resolve()
187
235
  }
188
236
 
189
- @objc func delayUpdate(_ call: CAPPluginCall) {
190
- UserDefaults.standard.set(true, forKey: "delayUpdate")
237
+ @objc func setDelay(_ call: CAPPluginCall) {
238
+ guard let delay = call.getBool("delay") else {
239
+ print("\(self.implementation.TAG) setDelay called without delay")
240
+ call.reject("setDelay called without delay")
241
+ return
242
+ }
243
+ UserDefaults.standard.set(delay, forKey: "delayUpdate")
191
244
  call.resolve()
192
245
  }
193
246
 
194
- @objc func cancelDelay(_ call: CAPPluginCall) {
195
- UserDefaults.standard.set(false, forKey: "delayUpdate")
196
- call.resolve()
247
+ private func _isAutoUpdateEnabled() -> Bool {
248
+ return self.autoUpdate && self.autoUpdateUrl != ""
197
249
  }
198
250
 
199
- @objc func appMovedToForeground() {
200
- DispatchQueue.global(qos: .background).async {
201
- print("✨ Capacitor-updater: Check for update in the server")
202
- let url = URL(string: self.autoUpdateUrl)!
203
- let res = self.implementation.getLatest(url: url)
204
- if (res == nil) {
251
+ @objc func isAutoUpdateEnabled(_ call: CAPPluginCall) {
252
+ call.resolve([
253
+ "enabled": self._isAutoUpdateEnabled()
254
+ ])
255
+ }
256
+
257
+ func checkAppReady() {
258
+ self.appReadyCheck?.cancel()
259
+ self.appReadyCheck = DispatchWorkItem(block: {
260
+ self.DeferredNotifyAppReadyCheck()
261
+ })
262
+ print("\(self.implementation.TAG) Wait for \(self.appReadyTimeout) ms, then check for notifyAppReady")
263
+ DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(self.appReadyTimeout), execute: self.appReadyCheck!)
264
+ }
265
+
266
+ func DeferredNotifyAppReadyCheck() {
267
+ // Automatically roll back to fallback version if notifyAppReady has not been called yet
268
+ let current: BundleInfo = self.implementation.getCurrentBundle()
269
+ if(current.isBuiltin()) {
270
+ print("\(self.implementation.TAG) Built-in bundle is active. Nothing to do.")
271
+ return
272
+ }
273
+
274
+ if(BundleStatus.SUCCESS.localizedString != current.getStatus()) {
275
+ print("\(self.implementation.TAG) notifyAppReady was not called, roll back current bundle: \(current.toString())")
276
+ self.implementation.rollback(bundle: current)
277
+ let res = self._reset(toAutoUpdate: true)
278
+ if (!res) {
205
279
  return
206
280
  }
207
- guard let downloadUrl = URL(string: res?.url ?? "") else {
208
- print("✨ Capacitor-updater: Error \(res?.message ?? "Unknow error")")
209
- if (res?.major == true) {
210
- self.notifyListeners("majorAvailable", data: ["version": res?.version ?? "0.0.0"])
281
+ } else {
282
+ print("\(self.implementation.TAG) notifyAppReady was called. This is fine: \(current.toString())")
283
+ }
284
+ self.appReadyCheck = nil
285
+ }
286
+
287
+ @objc func appMovedToForeground() {
288
+ if (self._isAutoUpdateEnabled()) {
289
+ DispatchQueue.global(qos: .background).async {
290
+ print("\(self.implementation.TAG) Check for update via \(self.autoUpdateUrl)")
291
+ let url = URL(string: self.autoUpdateUrl)!
292
+ let res = self.implementation.getLatest(url: url)
293
+ if (res == nil) {
294
+ print("\(self.implementation.TAG) No result found in \(self.autoUpdateUrl)")
295
+ return
211
296
  }
212
- return
213
- }
214
- let currentVersion = self.implementation.getVersionName()
215
- var failingVersion: Version = "0.0.0"
216
- var newVersion: Version = "0.0.0"
217
- do {
218
- newVersion = try Version(res?.version ?? "0.0.0")
219
- failingVersion = try Version(UserDefaults.standard.string(forKey: "failingVersion") ?? "0.0.0")
220
- } catch {
221
- print("✨ Capacitor-updater: Cannot get version \(failingVersion) \(newVersion)")
222
- }
223
- if (newVersion != "0.0.0" && newVersion != failingVersion) {
224
- let dlOp = self.implementation.download(url: downloadUrl)
225
- if let dl = dlOp {
226
- print("✨ Capacitor-updater: New version: \(newVersion) found. Current is \(currentVersion == "" ? "builtin" : currentVersion), next backgrounding will trigger update")
227
- UserDefaults.standard.set(dl, forKey: "nextVersion")
228
- UserDefaults.standard.set(newVersion.description, forKey: "nextVersionName")
229
- self.notifyListeners("updateAvailable", data: ["version": newVersion])
230
- } else {
231
- print("✨ Capacitor-updater: Download version \(newVersion) fail")
297
+ guard let downloadUrl = URL(string: res?.url ?? "") else {
298
+ print("\(self.implementation.TAG) Error \(res?.message ?? "Unknow error")")
299
+ if (res?.major == true) {
300
+ self.notifyListeners("majorAvailable", data: ["version": res?.version ?? "0.0.0"])
301
+ }
302
+ return
303
+ }
304
+ let current = self.implementation.getCurrentBundle()
305
+ let latestVersionName = res?.version
306
+ if (latestVersionName != nil && latestVersionName != "" && current.getVersionName() != latestVersionName) {
307
+ let latest = self.implementation.getBundleInfoByVersionName(version: latestVersionName!)
308
+ if (latest != nil) {
309
+ if(latest!.isErrorStatus()) {
310
+ print("\(self.implementation.TAG) Latest version already exists, and is in error state. Aborting update.")
311
+ return
312
+ }
313
+ if(latest!.isDownloaded()){
314
+ print("\(self.implementation.TAG) Latest version already exists and download is NOT required. Update will occur next time app moves to background.")
315
+ let _ = self.implementation.setNextVersion(next: latest!.getId())
316
+ return
317
+ }
318
+ }
319
+
320
+ do {
321
+ print("\(self.implementation.TAG) New bundle: \(latestVersionName!) found. Current is: \(current.getVersionName()). Update will occur next time app moves to background.")
322
+ let next = try self.implementation.download(url: downloadUrl, version: latestVersionName!)
323
+
324
+ let _ = self.implementation.setNextVersion(next: next.getId())
325
+ } catch {
326
+ print("\(self.implementation.TAG) Error downloading file", error.localizedDescription)
327
+ }
232
328
  }
233
- } else {
234
- print("✨ Capacitor-updater: No need to update, \(currentVersion) is the latest")
235
329
  }
236
330
  }
331
+
332
+ self.checkAppReady()
237
333
  }
238
334
 
239
335
  @objc func appMovedToBackground() {
240
- print("✨ Capacitor-updater: Check for waiting update")
336
+ print("\(self.implementation.TAG) Check for waiting update")
241
337
  let delayUpdate = UserDefaults.standard.bool(forKey: "delayUpdate")
242
338
  UserDefaults.standard.set(false, forKey: "delayUpdate")
243
339
  if (delayUpdate) {
244
- print("✨ Capacitor-updater: Update delayed to next backgrounding")
340
+ print("\(self.implementation.TAG) Update delayed to next backgrounding")
245
341
  return
246
342
  }
247
- let nextVersion = UserDefaults.standard.string(forKey: "nextVersion") ?? ""
248
- let nextVersionName = UserDefaults.standard.string(forKey: "nextVersionName") ?? ""
249
- let pastVersion = UserDefaults.standard.string(forKey: "pastVersion") ?? ""
250
- let pastVersionName = UserDefaults.standard.string(forKey: "pastVersionName") ?? ""
251
- let notifyAppReady = UserDefaults.standard.bool(forKey: "notifyAppReady")
252
- let curVersion = implementation.getLastPathPersist().components(separatedBy: "/").last!
253
- let curVersionName = implementation.getVersionName()
254
- if (nextVersion != "" && nextVersionName != "") {
255
- let res = implementation.set(version: nextVersion, versionName: nextVersionName)
256
- if (res && self._reload()) {
257
- print("✨ Capacitor-updater: Auto update to version: \(nextVersionName)")
258
- UserDefaults.standard.set(nextVersion, forKey: "LatestVersionAutoUpdate")
259
- UserDefaults.standard.set(nextVersionName, forKey: "LatestVersionNameAutoUpdate")
260
- UserDefaults.standard.set("", forKey: "nextVersion")
261
- UserDefaults.standard.set("", forKey: "nextVersionName")
262
- UserDefaults.standard.set(curVersion, forKey: "pastVersion")
263
- UserDefaults.standard.set(curVersionName, forKey: "pastVersionName")
264
- UserDefaults.standard.set(false, forKey: "notifyAppReady")
343
+
344
+ let fallback: BundleInfo = self.implementation.getFallbackVersion()
345
+ let current: BundleInfo = self.implementation.getCurrentBundle()
346
+ let next: BundleInfo? = self.implementation.getNextVersion()
347
+
348
+ let success: Bool = current.getStatus() == BundleStatus.SUCCESS.localizedString
349
+
350
+ print("\(self.implementation.TAG) Fallback bundle is: \(fallback.toString())")
351
+ print("\(self.implementation.TAG) Current bundle is: \(current.toString())")
352
+
353
+ if (next != nil && !next!.isErrorStatus() && (next!.getVersionName() != current.getVersionName())) {
354
+ print("\(self.implementation.TAG) Next bundle is: \(next!.toString())")
355
+ if (self.implementation.set(bundle: next!) && self._reload()) {
356
+ print("\(self.implementation.TAG) Updated to bundle: \(next!)")
357
+ let _ = self.implementation.setNextVersion(next: Optional<String>.none)
265
358
  } else {
266
- print("✨ Capacitor-updater: Auto update to version: \(nextVersionName) Failed");
359
+ print("\(self.implementation.TAG) Updated to bundle: \(next!) Failed!")
267
360
  }
268
- } else if (!notifyAppReady && curVersionName != "") {
269
- print("✨ Capacitor-updater: notifyAppReady never trigger")
270
- print("✨ Capacitor-updater: Version: \(curVersionName), is considered broken")
271
- print("✨ Capacitor-updater: Will downgraded to version: \(pastVersionName == "" ? "builtin" : pastVersionName) for next start")
272
- print("✨ Capacitor-updater: Don't forget to trigger 'notifyAppReady()' in js code to validate a version.")
273
- implementation.sendStats(action: "revert", version: curVersionName)
274
- if (pastVersion != "" && pastVersionName != "") {
275
- let res = implementation.set(version: pastVersion, versionName: pastVersionName)
276
- if (res && self._reload()) {
277
- print("✨ Capacitor-updater: Revert to version: \(pastVersionName == "" ? "builtin" : pastVersionName)")
278
- UserDefaults.standard.set(pastVersion, forKey: "LatestVersionAutoUpdate")
279
- UserDefaults.standard.set(pastVersionName, forKey: "LatestVersionNameAutoUpdate")
280
- UserDefaults.standard.set("", forKey: "pastVersion")
281
- UserDefaults.standard.set("", forKey: "pastVersionName")
361
+ } else if (!success) {
362
+ // There is a no next version, and the current version has failed
363
+
364
+ if(!current.isBuiltin()) {
365
+ // Don't try to roll back the builtin version. Nothing we can do.
366
+
367
+ self.implementation.rollback(bundle: current)
368
+
369
+ print("\(self.implementation.TAG) Update failed: 'notifyAppReady()' was never called.")
370
+ print("\(self.implementation.TAG) Version: \(current.toString()), is in error state.")
371
+ print("\(self.implementation.TAG) Will fallback to: \(fallback.toString()) on application restart.")
372
+ print("\(self.implementation.TAG) Did you forget to call 'notifyAppReady()' in your Capacitor App code?")
373
+
374
+ self.notifyListeners("updateFailed", data: [
375
+ "bundle": current.toJSON()
376
+ ])
377
+ self.implementation.sendStats(action: "revert", bundle: current)
378
+ if (!fallback.isBuiltin() && !(fallback == current)) {
379
+ let res = self.implementation.set(bundle: fallback)
380
+ if (res && self._reload()) {
381
+ print("\(self.implementation.TAG) Revert to bundle: \(fallback.toString())")
382
+ } else {
383
+ print("\(self.implementation.TAG) Revert to bundle: \(fallback.toString()) Failed!")
384
+ }
282
385
  } else {
283
- print("✨ Capacitor-updater: Revert to version: \(pastVersionName == "" ? "builtin" : pastVersionName) Failed");
386
+ if (self._reset(toAutoUpdate: false)) {
387
+ print("\(self.implementation.TAG) Reverted to 'builtin' bundle.")
388
+ }
284
389
  }
285
- } else {
286
- if self._reset(toAutoUpdate: false) {
287
- UserDefaults.standard.set("", forKey: "LatestVersionAutoUpdate")
288
- UserDefaults.standard.set("", forKey: "LatestVersionNameAutoUpdate")
289
- print("✨ Capacitor-updater: Auto reset done")
390
+
391
+ if (self.autoDeleteFailed) {
392
+ print("\(self.implementation.TAG) Deleting failing bundle: \(current.toString())")
393
+ let res = self.implementation.delete(id: current.getId())
394
+ if (!res) {
395
+ print("\(self.implementation.TAG) Delete version deleted: \(current.toString())")
396
+ } else {
397
+ print("\(self.implementation.TAG) Failed to delete failed bundle: \(current.toString())")
398
+ }
290
399
  }
400
+ } else {
401
+ // Nothing we can/should do by default if the 'builtin' bundle fails to call 'notifyAppReady()'.
291
402
  }
292
- UserDefaults.standard.set(curVersionName, forKey: "failingVersion")
293
- let res = implementation.delete(version: curVersion, versionName: curVersionName)
294
- if (res) {
295
- print("✨ Capacitor-updater: Delete failing version: \(curVersionName)")
296
- }
297
- } else if (pastVersion != "") {
298
- print("✨ Capacitor-updater: Validated version: \(curVersionName)")
299
- let res = implementation.delete(version: pastVersion, versionName: curVersionName)
300
- if (res) {
301
- print("✨ Capacitor-updater: Delete past version: \(pastVersionName)")
403
+ } else if (!fallback.isBuiltin()) {
404
+ // There is a no next version, and the current version has succeeded
405
+ self.implementation.commit(bundle: current)
406
+
407
+ if(self.autoDeletePrevious) {
408
+ print("\(self.implementation.TAG) Version successfully loaded: \(current.toString())")
409
+ let res = self.implementation.delete(id: fallback.getId())
410
+ if (res) {
411
+ print("\(self.implementation.TAG) Deleted previous bundle: \(fallback.toString())")
412
+ } else {
413
+ print("\(self.implementation.TAG) Failed to delete previous bundle: \(fallback.toString())")
414
+ }
302
415
  }
303
- UserDefaults.standard.set("", forKey: "pastVersion")
304
- UserDefaults.standard.set("", forKey: "pastVersionName")
305
416
  }
306
417
  }
307
418
  }