@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.
- package/README.md +207 -130
- 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 +403 -275
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +485 -268
- package/dist/docs.json +512 -109
- package/dist/esm/definitions.d.ts +201 -69
- package/dist/esm/web.d.ts +21 -16
- package/dist/esm/web.js +29 -23
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +29 -23
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +29 -23
- 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 +348 -84
- package/ios/Plugin/CapacitorUpdaterPlugin.m +4 -2
- package/ios/Plugin/CapacitorUpdaterPlugin.swift +277 -166
- package/ios/Plugin/ObjectPreferences.swift +97 -0
- package/package.json +2 -1
|
@@ -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,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
|
-
|
|
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) {
|
|
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
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
call.reject("
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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("
|
|
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
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
162
|
+
self.reload(call)
|
|
117
163
|
}
|
|
118
164
|
}
|
|
119
165
|
|
|
120
166
|
@objc func delete(_ call: CAPPluginCall) {
|
|
121
|
-
let
|
|
122
|
-
|
|
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,
|
|
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":
|
|
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(
|
|
199
|
+
let res = implementation.set(id: LatestVersionNameAutoUpdate)
|
|
144
200
|
return res && self._reload()
|
|
145
201
|
}
|
|
146
202
|
implementation.reset()
|
|
147
|
-
|
|
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("
|
|
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("
|
|
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
|
|
177
|
-
let current = pathHot.count >= 10 ? pathHot.suffix(10) : "builtin"
|
|
223
|
+
let bundle: BundleInfo = self.implementation.getCurrentBundle()
|
|
178
224
|
call.resolve([
|
|
179
|
-
"
|
|
180
|
-
"
|
|
225
|
+
"bundle": bundle.toJSON(),
|
|
226
|
+
"native": self.currentVersionNative
|
|
181
227
|
])
|
|
182
228
|
}
|
|
183
229
|
|
|
184
230
|
@objc func notifyAppReady(_ call: CAPPluginCall) {
|
|
185
|
-
|
|
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
|
|
190
|
-
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
call.resolve()
|
|
247
|
+
private func _isAutoUpdateEnabled() -> Bool {
|
|
248
|
+
return self.autoUpdate && self.autoUpdateUrl != ""
|
|
197
249
|
}
|
|
198
250
|
|
|
199
|
-
@objc func
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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("
|
|
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("
|
|
340
|
+
print("\(self.implementation.TAG) Update delayed to next backgrounding")
|
|
245
341
|
return
|
|
246
342
|
}
|
|
247
|
-
|
|
248
|
-
let
|
|
249
|
-
let
|
|
250
|
-
let
|
|
251
|
-
|
|
252
|
-
let
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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("
|
|
359
|
+
print("\(self.implementation.TAG) Updated to bundle: \(next!) Failed!")
|
|
267
360
|
}
|
|
268
|
-
} else if (!
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
|
-
|
|
386
|
+
if (self._reset(toAutoUpdate: false)) {
|
|
387
|
+
print("\(self.implementation.TAG) Reverted to 'builtin' bundle.")
|
|
388
|
+
}
|
|
284
389
|
}
|
|
285
|
-
|
|
286
|
-
if self.
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
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
|
}
|