@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.
- package/LICENCE +656 -160
- package/README.md +199 -136
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleInfo.java +130 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleStatus.java +36 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdater.java +316 -198
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +454 -244
- package/dist/docs.json +509 -121
- package/dist/esm/definitions.d.ts +201 -76
- package/dist/esm/web.d.ts +18 -16
- package/dist/esm/web.js +26 -24
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +26 -24
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +26 -24
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/BundleInfo.swift +94 -0
- package/ios/Plugin/BundleStatus.swift +41 -0
- package/ios/Plugin/CapacitorUpdater.swift +298 -82
- package/ios/Plugin/CapacitorUpdaterPlugin.m +3 -2
- package/ios/Plugin/CapacitorUpdaterPlugin.swift +270 -163
- package/ios/Plugin/ObjectPreferences.swift +97 -0
- package/package.json +3 -2
|
@@ -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://
|
|
13
|
-
static let statsUrlDefault = "https://
|
|
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
|
|
18
|
-
private var
|
|
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("
|
|
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
|
-
|
|
45
|
+
|
|
36
46
|
if (resetWhenUpdate) {
|
|
37
|
-
|
|
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
|
-
|
|
62
|
-
|
|
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
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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("
|
|
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
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
162
|
+
self.reload(call)
|
|
121
163
|
}
|
|
122
164
|
}
|
|
123
165
|
|
|
124
166
|
@objc func delete(_ call: CAPPluginCall) {
|
|
125
|
-
let
|
|
126
|
-
|
|
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,
|
|
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":
|
|
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(
|
|
199
|
+
let res = implementation.set(id: LatestVersionNameAutoUpdate)
|
|
148
200
|
return res && self._reload()
|
|
149
201
|
}
|
|
150
202
|
implementation.reset()
|
|
151
|
-
|
|
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("
|
|
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("
|
|
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
|
|
181
|
-
let current = pathHot.count >= 10 ? pathHot.suffix(10) : "builtin"
|
|
223
|
+
let bundle: BundleInfo = self.implementation.getCurrentBundle()
|
|
182
224
|
call.resolve([
|
|
183
|
-
"
|
|
184
|
-
"
|
|
225
|
+
"bundle": bundle.toJSON(),
|
|
226
|
+
"native": self.currentVersionNative
|
|
185
227
|
])
|
|
186
228
|
}
|
|
187
229
|
|
|
188
230
|
@objc func notifyAppReady(_ call: CAPPluginCall) {
|
|
189
|
-
|
|
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
|
|
194
|
-
|
|
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
|
-
|
|
199
|
-
|
|
200
|
-
call.resolve()
|
|
247
|
+
private func _isAutoUpdateEnabled() -> Bool {
|
|
248
|
+
return self.autoUpdate && self.autoUpdateUrl != ""
|
|
201
249
|
}
|
|
202
250
|
|
|
203
|
-
@objc func
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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("
|
|
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("
|
|
340
|
+
print("\(self.implementation.TAG) Update delayed to next backgrounding")
|
|
249
341
|
return
|
|
250
342
|
}
|
|
251
|
-
|
|
252
|
-
let
|
|
253
|
-
let
|
|
254
|
-
let
|
|
255
|
-
|
|
256
|
-
let
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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("
|
|
359
|
+
print("\(self.implementation.TAG) Updated to bundle: \(next!) Failed!")
|
|
271
360
|
}
|
|
272
|
-
} else if (!
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
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
|
-
|
|
386
|
+
if (self._reset(toAutoUpdate: false)) {
|
|
387
|
+
print("\(self.implementation.TAG) Reverted to 'builtin' bundle.")
|
|
388
|
+
}
|
|
288
389
|
}
|
|
289
|
-
|
|
290
|
-
if self.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
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
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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
|
}
|