@capgo/capacitor-updater 3.2.0 → 3.3.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/README.md +4 -4
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdater.java +209 -212
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +188 -182
- package/ios/Plugin/CapacitorUpdater.swift +63 -26
- package/ios/Plugin/CapacitorUpdaterPlugin.m +1 -0
- package/ios/Plugin/CapacitorUpdaterPlugin.swift +13 -9
- package/package.json +1 -1
|
@@ -36,13 +36,33 @@ extension Bundle {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
enum CustomError: Error {
|
|
40
|
+
// Throw when an unzip fail
|
|
41
|
+
case cannotUnzip
|
|
42
|
+
|
|
43
|
+
// Throw in all other cases
|
|
44
|
+
case unexpected(code: Int)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
extension CustomError: LocalizedError {
|
|
48
|
+
public var errorDescription: String? {
|
|
49
|
+
switch self {
|
|
50
|
+
case .cannotUnzip:
|
|
51
|
+
return NSLocalizedString(
|
|
52
|
+
"The file cannot be unzip",
|
|
53
|
+
comment: "Invalid zip"
|
|
54
|
+
)
|
|
55
|
+
case .unexpected(_):
|
|
56
|
+
return NSLocalizedString(
|
|
57
|
+
"An unexpected error occurred.",
|
|
58
|
+
comment: "Unexpected Error"
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
39
64
|
@objc public class CapacitorUpdater: NSObject {
|
|
40
65
|
|
|
41
|
-
public var statsUrl = ""
|
|
42
|
-
public var appId = ""
|
|
43
|
-
public var deviceID = UIDevice.current.identifierForVendor?.uuidString ?? ""
|
|
44
|
-
public var notifyDownload: (Int) -> Void = { _ in }
|
|
45
|
-
public var pluginVersion = "3.2.0"
|
|
46
66
|
private var versionBuild = Bundle.main.releaseVersionNumber ?? ""
|
|
47
67
|
private var versionCode = Bundle.main.buildVersionNumber ?? ""
|
|
48
68
|
private var versionOs = ProcessInfo().operatingSystemVersion.getFullVersion()
|
|
@@ -53,11 +73,17 @@ extension Bundle {
|
|
|
53
73
|
private let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
|
54
74
|
private let libraryUrl = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!
|
|
55
75
|
|
|
56
|
-
|
|
76
|
+
public var statsUrl = ""
|
|
77
|
+
public var appId = ""
|
|
78
|
+
public var deviceID = UIDevice.current.identifierForVendor?.uuidString ?? ""
|
|
79
|
+
public var notifyDownload: (Int) -> Void = { _ in }
|
|
80
|
+
public var pluginVersion = "3.2.0"
|
|
81
|
+
|
|
82
|
+
private func calcTotalPercent(percent: Int, min: Int, max: Int) -> Int {
|
|
57
83
|
return (percent * (max - min)) / 100 + min;
|
|
58
84
|
}
|
|
59
85
|
|
|
60
|
-
|
|
86
|
+
private func randomString(length: Int) -> String {
|
|
61
87
|
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
62
88
|
return String((0..<length).map{ _ in letters.randomElement()! })
|
|
63
89
|
}
|
|
@@ -101,17 +127,19 @@ extension Bundle {
|
|
|
101
127
|
}
|
|
102
128
|
}
|
|
103
129
|
|
|
104
|
-
private func saveDownloaded(sourceZip: URL, version: String, base: URL) {
|
|
130
|
+
private func saveDownloaded(sourceZip: URL, version: String, base: URL) throws {
|
|
105
131
|
prepareFolder(source: base)
|
|
106
132
|
let destHot = base.appendingPathComponent(version)
|
|
107
133
|
let destUnZip = documentsUrl.appendingPathComponent(randomString(length: 10))
|
|
108
|
-
SSZipArchive.unzipFile(atPath: sourceZip.path, toDestination: destUnZip.path)
|
|
134
|
+
if (!SSZipArchive.unzipFile(atPath: sourceZip.path, toDestination: destUnZip.path)) {
|
|
135
|
+
throw CustomError.cannotUnzip
|
|
136
|
+
}
|
|
109
137
|
if (unflatFolder(source: destUnZip, dest: destHot)) {
|
|
110
138
|
deleteFolder(source: destUnZip)
|
|
111
139
|
}
|
|
112
140
|
}
|
|
113
141
|
|
|
114
|
-
|
|
142
|
+
public func getLatest(url: URL) -> AppVersion? {
|
|
115
143
|
let semaphore = DispatchSemaphore(value: 0)
|
|
116
144
|
let latest = AppVersion()
|
|
117
145
|
let headers: HTTPHeaders = [
|
|
@@ -150,9 +178,10 @@ extension Bundle {
|
|
|
150
178
|
return latest.url != "" ? latest : nil
|
|
151
179
|
}
|
|
152
180
|
|
|
153
|
-
|
|
181
|
+
public func download(url: URL) throws -> String {
|
|
154
182
|
let semaphore = DispatchSemaphore(value: 0)
|
|
155
|
-
var version: String
|
|
183
|
+
var version: String = ""
|
|
184
|
+
var mainError: NSError? = nil
|
|
156
185
|
let destination: DownloadRequest.Destination = { _, _ in
|
|
157
186
|
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
|
158
187
|
let fileURL = documentsURL.appendingPathComponent(self.randomString(length: 10))
|
|
@@ -171,24 +200,32 @@ extension Bundle {
|
|
|
171
200
|
case .success:
|
|
172
201
|
self.notifyDownload(71);
|
|
173
202
|
version = self.randomString(length: 10)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
203
|
+
do {
|
|
204
|
+
try self.saveDownloaded(sourceZip: fileURL, version: version, base: self.documentsUrl.appendingPathComponent(self.basePathHot))
|
|
205
|
+
self.notifyDownload(85);
|
|
206
|
+
try self.saveDownloaded(sourceZip: fileURL, version: version, base: self.libraryUrl.appendingPathComponent(self.basePathPersist))
|
|
207
|
+
self.notifyDownload(100);
|
|
208
|
+
self.deleteFolder(source: fileURL)
|
|
209
|
+
} catch {
|
|
210
|
+
print("✨ Capacitor-updater: download unzip error", error)
|
|
211
|
+
mainError = error as NSError
|
|
212
|
+
}
|
|
179
213
|
case let .failure(error):
|
|
180
214
|
print("✨ Capacitor-updater: download error", error)
|
|
181
|
-
|
|
215
|
+
mainError = error as NSError
|
|
182
216
|
}
|
|
183
217
|
}
|
|
184
218
|
semaphore.signal()
|
|
185
219
|
}
|
|
186
220
|
self.notifyDownload(0);
|
|
187
221
|
semaphore.wait()
|
|
222
|
+
if (mainError != nil) {
|
|
223
|
+
throw mainError!
|
|
224
|
+
}
|
|
188
225
|
return version
|
|
189
226
|
}
|
|
190
227
|
|
|
191
|
-
|
|
228
|
+
public func list() -> [String] {
|
|
192
229
|
let dest = documentsUrl.appendingPathComponent(basePathHot)
|
|
193
230
|
do {
|
|
194
231
|
let files = try FileManager.default.contentsOfDirectory(atPath: dest.path)
|
|
@@ -199,7 +236,7 @@ extension Bundle {
|
|
|
199
236
|
}
|
|
200
237
|
}
|
|
201
238
|
|
|
202
|
-
|
|
239
|
+
public func delete(version: String, versionName: String) -> Bool {
|
|
203
240
|
let destHot = documentsUrl.appendingPathComponent(basePathHot).appendingPathComponent(version)
|
|
204
241
|
let destPersist = libraryUrl.appendingPathComponent(basePathPersist).appendingPathComponent(version)
|
|
205
242
|
do {
|
|
@@ -217,7 +254,7 @@ extension Bundle {
|
|
|
217
254
|
return true
|
|
218
255
|
}
|
|
219
256
|
|
|
220
|
-
|
|
257
|
+
public func set(version: String, versionName: String) -> Bool {
|
|
221
258
|
let destHot = documentsUrl.appendingPathComponent(basePathHot).appendingPathComponent(version)
|
|
222
259
|
let indexHot = destHot.appendingPathComponent("index.html")
|
|
223
260
|
let destHotPersist = libraryUrl.appendingPathComponent(basePathPersist).appendingPathComponent(version)
|
|
@@ -233,19 +270,19 @@ extension Bundle {
|
|
|
233
270
|
return false
|
|
234
271
|
}
|
|
235
272
|
|
|
236
|
-
|
|
273
|
+
public func getLastPathHot() -> String {
|
|
237
274
|
return UserDefaults.standard.string(forKey: "lastPathHot") ?? ""
|
|
238
275
|
}
|
|
239
276
|
|
|
240
|
-
|
|
277
|
+
public func getVersionName() -> String {
|
|
241
278
|
return UserDefaults.standard.string(forKey: "versionName") ?? ""
|
|
242
279
|
}
|
|
243
280
|
|
|
244
|
-
|
|
281
|
+
public func getLastPathPersist() -> String {
|
|
245
282
|
return UserDefaults.standard.string(forKey: "lastPathPersist") ?? ""
|
|
246
283
|
}
|
|
247
284
|
|
|
248
|
-
|
|
285
|
+
public func reset() {
|
|
249
286
|
let version = UserDefaults.standard.string(forKey: "versionName") ?? ""
|
|
250
287
|
sendStats(action: "reset", version: version)
|
|
251
288
|
UserDefaults.standard.set("", forKey: "lastPathHot")
|
|
@@ -254,7 +291,7 @@ extension Bundle {
|
|
|
254
291
|
UserDefaults.standard.synchronize()
|
|
255
292
|
}
|
|
256
293
|
|
|
257
|
-
|
|
294
|
+
func sendStats(action: String, version: String) {
|
|
258
295
|
if (statsUrl == "") { return }
|
|
259
296
|
let parameters: [String: String] = [
|
|
260
297
|
"platform": "ios",
|
|
@@ -15,4 +15,5 @@ CAP_PLUGIN(CapacitorUpdaterPlugin, "CapacitorUpdater",
|
|
|
15
15
|
CAP_PLUGIN_METHOD(notifyAppReady, CAPPluginReturnPromise);
|
|
16
16
|
CAP_PLUGIN_METHOD(delayUpdate, CAPPluginReturnPromise);
|
|
17
17
|
CAP_PLUGIN_METHOD(getId, CAPPluginReturnPromise);
|
|
18
|
+
CAP_PLUGIN_METHOD(getPluginVersion, CAPPluginReturnPromise);
|
|
18
19
|
)
|
|
@@ -65,16 +65,20 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
|
|
|
65
65
|
@objc func getId(_ call: CAPPluginCall) {
|
|
66
66
|
call.resolve(["id": implementation.deviceID])
|
|
67
67
|
}
|
|
68
|
+
|
|
69
|
+
@objc func getPluginVersion(_ call: CAPPluginCall) {
|
|
70
|
+
call.resolve(["version": implementation.pluginVersion])
|
|
71
|
+
}
|
|
68
72
|
|
|
69
73
|
@objc func download(_ call: CAPPluginCall) {
|
|
70
74
|
let url = URL(string: call.getString("url") ?? "")
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
do {
|
|
76
|
+
let res = try implementation.download(url: url!)
|
|
73
77
|
call.resolve([
|
|
74
|
-
"version": res
|
|
78
|
+
"version": res
|
|
75
79
|
])
|
|
76
|
-
}
|
|
77
|
-
call.reject("download failed")
|
|
80
|
+
} catch {
|
|
81
|
+
call.reject("download failed", error.localizedDescription)
|
|
78
82
|
}
|
|
79
83
|
}
|
|
80
84
|
|
|
@@ -221,14 +225,14 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
|
|
|
221
225
|
print("✨ Capacitor-updater: Cannot get version \(failingVersion) \(newVersion)")
|
|
222
226
|
}
|
|
223
227
|
if (newVersion != "0.0.0" && newVersion != failingVersion) {
|
|
224
|
-
|
|
225
|
-
|
|
228
|
+
do {
|
|
229
|
+
let dl = try self.implementation.download(url: downloadUrl)
|
|
226
230
|
print("✨ Capacitor-updater: New version: \(newVersion) found. Current is \(currentVersion == "" ? "builtin" : currentVersion), next backgrounding will trigger update")
|
|
227
231
|
UserDefaults.standard.set(dl, forKey: "nextVersion")
|
|
228
232
|
UserDefaults.standard.set(newVersion.description, forKey: "nextVersionName")
|
|
229
233
|
self.notifyListeners("updateAvailable", data: ["version": newVersion])
|
|
230
|
-
}
|
|
231
|
-
print("✨ Capacitor-updater: Download version \(newVersion) fail")
|
|
234
|
+
} catch {
|
|
235
|
+
print("✨ Capacitor-updater: Download version \(newVersion) fail", error.localizedDescription)
|
|
232
236
|
}
|
|
233
237
|
} else {
|
|
234
238
|
print("✨ Capacitor-updater: No need to update, \(currentVersion) is the latest")
|