@capgo/capacitor-updater 3.3.10 → 4.0.0-alpha.1

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,34 +42,43 @@ 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) {
@@ -71,12 +90,21 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
71
90
  }
72
91
 
73
92
  @objc func download(_ call: CAPPluginCall) {
74
- let url = URL(string: call.getString("url") ?? "")
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!)")
75
105
  do {
76
- let res = try implementation.download(url: url!)
77
- call.resolve([
78
- "version": res
79
- ])
106
+ let res = try implementation.download(url: url!, version: version)
107
+ call.resolve(res.toJSON())
80
108
  } catch {
81
109
  call.reject("download failed", error.localizedDescription)
82
110
  }
@@ -84,18 +112,13 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
84
112
 
85
113
  private func _reload() -> Bool {
86
114
  guard let bridge = self.bridge else { return false }
87
-
115
+ let id = self.implementation.getCurrentBundleId()
116
+ let destHot = self.implementation.getPathHot(id: id)
117
+ print("\(self.implementation.TAG) Reloading \(id)")
88
118
  if let vc = bridge.viewController as? CAPBridgeViewController {
89
- let pathHot = implementation.getLastPathHot()
90
- let pathPersist = implementation.getLastPathPersist()
91
- if (pathHot != "" && pathPersist != "") {
92
- UserDefaults.standard.set(String(pathPersist.suffix(10)), forKey: "serverBasePath")
93
- vc.setServerBasePath(path: pathHot)
94
- print("✨ Capacitor-updater: Reload app done")
95
- return true
96
- } else {
97
- return false
98
- }
119
+ vc.setServerBasePath(path: destHot.path)
120
+ self.checkAppReady()
121
+ return true
99
122
  }
100
123
  return false
101
124
  }
@@ -104,57 +127,84 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
104
127
  if (self._reload()) {
105
128
  call.resolve()
106
129
  } else {
107
- 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())
108
147
  }
109
148
  }
110
149
 
111
150
  @objc func set(_ call: CAPPluginCall) {
112
- let version = call.getString("version") ?? ""
113
- let versionName = call.getString("versionName") ?? version
114
- let res = implementation.set(version: version, versionName: versionName)
115
-
116
- if (res && self._reload()) {
117
- print("✨ Capacitor-updater: Set to version: \(version) versionName: \(versionName)")
118
- 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")
119
161
  } else {
120
- call.reject("Update failed, version \(version) doesn't exist")
162
+ self.reload(call)
121
163
  }
122
164
  }
123
165
 
124
166
  @objc func delete(_ call: CAPPluginCall) {
125
- let version = call.getString("version") ?? ""
126
- 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)
127
173
  if (res) {
128
174
  call.resolve()
129
175
  } else {
130
- call.reject("Delete failed, version \(version) doesn't exist")
176
+ call.reject("Delete failed, id \(id) doesn't exist")
131
177
  }
132
178
  }
133
179
 
134
180
  @objc func list(_ call: CAPPluginCall) {
135
181
  let res = implementation.list()
182
+ var resArr: [[String: String]] = []
183
+ for v in res {
184
+ resArr.append(v.toJSON())
185
+ }
136
186
  call.resolve([
137
- "versions": res
187
+ "versions": resArr
138
188
  ])
139
189
  }
140
190
 
141
191
  @objc func _reset(toAutoUpdate: Bool) -> Bool {
142
192
  guard let bridge = self.bridge else { return false }
143
193
  if let vc = bridge.viewController as? CAPBridgeViewController {
194
+ self.implementation.reset()
195
+
144
196
  let LatestVersionAutoUpdate = UserDefaults.standard.string(forKey: "LatestVersionAutoUpdate") ?? ""
145
197
  let LatestVersionNameAutoUpdate = UserDefaults.standard.string(forKey: "LatestVersionNameAutoUpdate") ?? ""
146
198
  if(toAutoUpdate && LatestVersionAutoUpdate != "" && LatestVersionNameAutoUpdate != "") {
147
- let res = implementation.set(version: LatestVersionAutoUpdate, versionName: LatestVersionNameAutoUpdate)
199
+ let res = implementation.set(id: LatestVersionNameAutoUpdate)
148
200
  return res && self._reload()
149
201
  }
150
202
  implementation.reset()
151
- let pathPersist = implementation.getLastPathPersist()
152
- vc.setServerBasePath(path: pathPersist)
153
- UserDefaults.standard.set(pathPersist, forKey: "serverBasePath")
203
+ vc.setServerBasePath(path: "")
154
204
  DispatchQueue.main.async {
155
205
  vc.loadView()
156
206
  vc.viewDidLoad()
157
- print("✨ Capacitor-updater: Reset to original version")
207
+ print("\(self.implementation.TAG) Reset to builtin version")
158
208
  }
159
209
  return true
160
210
  }
@@ -166,146 +216,203 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
166
216
  if (self._reset(toAutoUpdate: toAutoUpdate)) {
167
217
  return call.resolve()
168
218
  }
169
- call.reject("✨ Capacitor-updater: Reset failed")
170
- }
171
-
172
- @objc func versionName(_ call: CAPPluginCall) {
173
- let name = implementation.getVersionName()
174
- call.resolve([
175
- "versionName": name
176
- ])
219
+ call.reject("\(self.implementation.TAG) Reset failed")
177
220
  }
178
221
 
179
222
  @objc func current(_ call: CAPPluginCall) {
180
- let pathHot = implementation.getLastPathHot()
181
- let current = pathHot.count >= 10 ? pathHot.suffix(10) : "builtin"
223
+ let bundle: BundleInfo = self.implementation.getCurrentBundle()
182
224
  call.resolve([
183
- "current": current,
184
- "currentNative": currentVersionNative
225
+ "bundle": bundle.toJSON(),
226
+ "native": self.currentVersionNative
185
227
  ])
186
228
  }
187
229
 
188
230
  @objc func notifyAppReady(_ call: CAPPluginCall) {
189
- 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)
190
234
  call.resolve()
191
235
  }
192
236
 
193
- @objc func delayUpdate(_ call: CAPPluginCall) {
194
- 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")
195
244
  call.resolve()
196
245
  }
197
246
 
198
- @objc func cancelDelay(_ call: CAPPluginCall) {
199
- UserDefaults.standard.set(false, forKey: "delayUpdate")
200
- call.resolve()
247
+ private func _isAutoUpdateEnabled() -> Bool {
248
+ return self.autoUpdate && self.autoUpdateUrl != ""
201
249
  }
202
250
 
203
- @objc func appMovedToForeground() {
204
- DispatchQueue.global(qos: .background).async {
205
- print("✨ Capacitor-updater: Check for update in the server")
206
- let url = URL(string: self.autoUpdateUrl)!
207
- let res = self.implementation.getLatest(url: url)
208
- 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) {
209
279
  return
210
280
  }
211
- guard let downloadUrl = URL(string: res?.url ?? "") else {
212
- print("✨ Capacitor-updater: Error \(res?.message ?? "Unknow error")")
213
- if (res?.major == true) {
214
- 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
215
296
  }
216
- return
217
- }
218
- let currentVersion = self.implementation.getVersionName()
219
- var failingVersion: Version = "0.0.0"
220
- var newVersion: Version = "0.0.0"
221
- do {
222
- newVersion = try Version(res?.version ?? "0.0.0")
223
- failingVersion = try Version(UserDefaults.standard.string(forKey: "failingVersion") ?? "0.0.0")
224
- } catch {
225
- print("✨ Capacitor-updater: Cannot get version \(failingVersion) \(newVersion)")
226
- }
227
- if (newVersion != "0.0.0" && newVersion != failingVersion) {
228
- do {
229
- let dl = try self.implementation.download(url: downloadUrl)
230
- print("✨ Capacitor-updater: New version: \(newVersion) found. Current is \(currentVersion == "" ? "builtin" : currentVersion), next backgrounding will trigger update")
231
- UserDefaults.standard.set(dl, forKey: "nextVersion")
232
- UserDefaults.standard.set(newVersion.description, forKey: "nextVersionName")
233
- self.notifyListeners("updateAvailable", data: ["version": newVersion])
234
- } catch {
235
- print("✨ Capacitor-updater: Download version \(newVersion) fail", error.localizedDescription)
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
+ }
236
328
  }
237
- } else {
238
- print("✨ Capacitor-updater: No need to update, \(currentVersion) is the latest")
239
329
  }
240
330
  }
331
+
332
+ self.checkAppReady()
241
333
  }
242
334
 
243
335
  @objc func appMovedToBackground() {
244
- print("✨ Capacitor-updater: Check for waiting update")
336
+ print("\(self.implementation.TAG) Check for waiting update")
245
337
  let delayUpdate = UserDefaults.standard.bool(forKey: "delayUpdate")
246
338
  UserDefaults.standard.set(false, forKey: "delayUpdate")
247
339
  if (delayUpdate) {
248
- print("✨ Capacitor-updater: Update delayed to next backgrounding")
340
+ print("\(self.implementation.TAG) Update delayed to next backgrounding")
249
341
  return
250
342
  }
251
- let nextVersion = UserDefaults.standard.string(forKey: "nextVersion") ?? ""
252
- let nextVersionName = UserDefaults.standard.string(forKey: "nextVersionName") ?? ""
253
- let pastVersion = UserDefaults.standard.string(forKey: "pastVersion") ?? ""
254
- let pastVersionName = UserDefaults.standard.string(forKey: "pastVersionName") ?? ""
255
- let notifyAppReady = UserDefaults.standard.bool(forKey: "notifyAppReady")
256
- let curVersion = implementation.getLastPathPersist().components(separatedBy: "/").last!
257
- let curVersionName = implementation.getVersionName()
258
- if (nextVersion != "" && nextVersionName != "") {
259
- let res = implementation.set(version: nextVersion, versionName: nextVersionName)
260
- if (res && self._reload()) {
261
- print("✨ Capacitor-updater: Auto update to version: \(nextVersionName)")
262
- UserDefaults.standard.set(nextVersion, forKey: "LatestVersionAutoUpdate")
263
- UserDefaults.standard.set(nextVersionName, forKey: "LatestVersionNameAutoUpdate")
264
- UserDefaults.standard.set("", forKey: "nextVersion")
265
- UserDefaults.standard.set("", forKey: "nextVersionName")
266
- UserDefaults.standard.set(curVersion, forKey: "pastVersion")
267
- UserDefaults.standard.set(curVersionName, forKey: "pastVersionName")
268
- 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)
269
358
  } else {
270
- print("✨ Capacitor-updater: Auto update to version: \(nextVersionName) Failed");
359
+ print("\(self.implementation.TAG) Updated to bundle: \(next!) Failed!")
271
360
  }
272
- } else if (!notifyAppReady && curVersionName != "") {
273
- print("✨ Capacitor-updater: notifyAppReady never trigger")
274
- print("✨ Capacitor-updater: Version: \(curVersionName), is considered broken")
275
- print("✨ Capacitor-updater: Will downgraded to version: \(pastVersionName == "" ? "builtin" : pastVersionName) for next start")
276
- print("✨ Capacitor-updater: Don't forget to trigger 'notifyAppReady()' in js code to validate a version.")
277
- implementation.sendStats(action: "revert", version: curVersionName)
278
- if (pastVersion != "" && pastVersionName != "") {
279
- let res = implementation.set(version: pastVersion, versionName: pastVersionName)
280
- if (res && self._reload()) {
281
- print("✨ Capacitor-updater: Revert to version: \(pastVersionName == "" ? "builtin" : pastVersionName)")
282
- UserDefaults.standard.set(pastVersion, forKey: "LatestVersionAutoUpdate")
283
- UserDefaults.standard.set(pastVersionName, forKey: "LatestVersionNameAutoUpdate")
284
- UserDefaults.standard.set("", forKey: "pastVersion")
285
- 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
+ }
286
385
  } else {
287
- 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
+ }
288
389
  }
289
- } else {
290
- if self._reset(toAutoUpdate: false) {
291
- UserDefaults.standard.set("", forKey: "LatestVersionAutoUpdate")
292
- UserDefaults.standard.set("", forKey: "LatestVersionNameAutoUpdate")
293
- 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
+ }
294
399
  }
400
+ } else {
401
+ // Nothing we can/should do by default if the 'builtin' bundle fails to call 'notifyAppReady()'.
295
402
  }
296
- UserDefaults.standard.set(curVersionName, forKey: "failingVersion")
297
- let res = implementation.delete(version: curVersion, versionName: curVersionName)
298
- if (res) {
299
- print("✨ Capacitor-updater: Delete failing version: \(curVersionName)")
300
- }
301
- } else if (pastVersion != "") {
302
- print("✨ Capacitor-updater: Validated version: \(curVersionName)")
303
- let res = implementation.delete(version: pastVersion, versionName: curVersionName)
304
- if (res) {
305
- 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
+ }
306
415
  }
307
- UserDefaults.standard.set("", forKey: "pastVersion")
308
- UserDefaults.standard.set("", forKey: "pastVersionName")
309
416
  }
310
417
  }
311
418
  }