@capgo/capacitor-updater 3.3.12 → 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.
@@ -10,6 +10,11 @@ extension URL {
10
10
  return FileManager().fileExists(atPath: self.path)
11
11
  }
12
12
  }
13
+ extension Date {
14
+ func adding(minutes: Int) -> Date {
15
+ return Calendar.current.date(byAdding: .minute, value: minutes, to: self)!
16
+ }
17
+ }
13
18
  struct AppVersionDec: Decodable {
14
19
  let version: String?
15
20
  let url: String?
@@ -36,9 +41,43 @@ extension Bundle {
36
41
  }
37
42
  }
38
43
 
44
+ extension ISO8601DateFormatter {
45
+ convenience init(_ formatOptions: Options) {
46
+ self.init()
47
+ self.formatOptions = formatOptions
48
+ }
49
+ }
50
+ extension Formatter {
51
+ static let iso8601withFractionalSeconds = ISO8601DateFormatter([.withInternetDateTime, .withFractionalSeconds])
52
+ }
53
+ extension Date {
54
+ var iso8601withFractionalSeconds: String { return Formatter.iso8601withFractionalSeconds.string(from: self) }
55
+ }
56
+ extension String {
57
+
58
+ var fileURL: URL {
59
+ return URL(fileURLWithPath: self)
60
+ }
61
+
62
+ var lastPathComponent:String {
63
+ get {
64
+ return fileURL.lastPathComponent
65
+ }
66
+ }
67
+ var iso8601withFractionalSeconds: Date? {
68
+ return Formatter.iso8601withFractionalSeconds.date(from: self)
69
+ }
70
+ func trim(using characterSet: CharacterSet = .whitespacesAndNewlines) -> String {
71
+ return trimmingCharacters(in: characterSet)
72
+ }
73
+ }
74
+
39
75
  enum CustomError: Error {
40
76
  // Throw when an unzip fail
41
77
  case cannotUnzip
78
+ case cannotUnflat
79
+ case cannotCreateDirectory
80
+ case cannotDeleteDirectory
42
81
 
43
82
  // Throw in all other cases
44
83
  case unexpected(code: Int)
@@ -52,6 +91,21 @@ extension CustomError: LocalizedError {
52
91
  "The file cannot be unzip",
53
92
  comment: "Invalid zip"
54
93
  )
94
+ case .cannotCreateDirectory:
95
+ return NSLocalizedString(
96
+ "The folder cannot be created",
97
+ comment: "Invalid folder"
98
+ )
99
+ case .cannotDeleteDirectory:
100
+ return NSLocalizedString(
101
+ "The folder cannot be deleted",
102
+ comment: "Invalid folder"
103
+ )
104
+ case .cannotUnflat:
105
+ return NSLocalizedString(
106
+ "The file cannot be unflat",
107
+ comment: "Invalid folder"
108
+ )
55
109
  case .unexpected(_):
56
110
  return NSLocalizedString(
57
111
  "An unexpected error occurred.",
@@ -63,21 +117,29 @@ extension CustomError: LocalizedError {
63
117
 
64
118
  @objc public class CapacitorUpdater: NSObject {
65
119
 
66
- private var versionBuild = Bundle.main.releaseVersionNumber ?? ""
67
- private var versionCode = Bundle.main.buildVersionNumber ?? ""
68
- private var versionOs = ProcessInfo().operatingSystemVersion.getFullVersion()
120
+ private let versionBuild = Bundle.main.releaseVersionNumber ?? ""
121
+ private let versionCode = Bundle.main.buildVersionNumber ?? ""
122
+ private let versionOs = ProcessInfo().operatingSystemVersion.getFullVersion()
123
+ private let documentsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
124
+ private let libraryDir = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!
125
+ private let bundleDirectoryHot = "versions"
126
+ private let DEFAULT_FOLDER = ""
127
+ private let bundleDirectory = "NoCloud/ionic_built_snapshots"
128
+ private let INFO_SUFFIX = "_info"
129
+ private let FALLBACK_VERSION = "pastVersion"
130
+ private let NEXT_VERSION = "nextVersion"
131
+
69
132
  private var lastPathHot = ""
70
133
  private var lastPathPersist = ""
71
- private let basePathHot = "versions"
72
- private let basePathPersist = "NoCloud/ionic_built_snapshots"
73
- private let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
74
- private let libraryUrl = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!
75
134
 
135
+ public let TAG = "✨ Capacitor-updater:";
136
+ public let CAP_SERVER_PATH = "serverBasePath"
137
+ public let pluginVersion = "4.0.0-alpha.1"
76
138
  public var statsUrl = ""
77
139
  public var appId = ""
78
140
  public var deviceID = UIDevice.current.identifierForVendor?.uuidString ?? ""
79
- public var notifyDownload: (Int) -> Void = { _ in }
80
- public var pluginVersion = "3.2.0"
141
+
142
+ public var notifyDownload: (String, Int) -> Void = { _,_ in }
81
143
 
82
144
  private func calcTotalPercent(percent: Int, min: Int, max: Int) -> Int {
83
145
  return (percent * (max - min)) / 100 + min;
@@ -92,25 +154,27 @@ extension CustomError: LocalizedError {
92
154
  // Hot Reload path /var/mobile/Containers/Data/Application/8C0C07BE-0FD3-4FD4-B7DF-90A88E12B8C3/Documents/FOLDER
93
155
  // Normal /private/var/containers/Bundle/Application/8C0C07BE-0FD3-4FD4-B7DF-90A88E12B8C3/App.app/public
94
156
 
95
- private func prepareFolder(source: URL) {
157
+ private func prepareFolder(source: URL) throws {
96
158
  if (!FileManager.default.fileExists(atPath: source.path)) {
97
159
  do {
98
160
  try FileManager.default.createDirectory(atPath: source.path, withIntermediateDirectories: true, attributes: nil)
99
161
  } catch {
100
- print("✨ Capacitor-updater: Cannot createDirectory \(source.path)")
162
+ print("\(self.TAG) Cannot createDirectory \(source.path)")
163
+ throw CustomError.cannotCreateDirectory
101
164
  }
102
165
  }
103
166
  }
104
167
 
105
- private func deleteFolder(source: URL) {
168
+ private func deleteFolder(source: URL) throws {
106
169
  do {
107
170
  try FileManager.default.removeItem(atPath: source.path)
108
171
  } catch {
109
- print("✨ Capacitor-updater: File not removed. \(source.path)")
172
+ print("\(self.TAG) File not removed. \(source.path)")
173
+ throw CustomError.cannotDeleteDirectory
110
174
  }
111
175
  }
112
176
 
113
- private func unflatFolder(source: URL, dest: URL) -> Bool {
177
+ private func unflatFolder(source: URL, dest: URL) throws -> Bool {
114
178
  let index = source.appendingPathComponent("index.html")
115
179
  do {
116
180
  let files = try FileManager.default.contentsOfDirectory(atPath: source.path)
@@ -122,37 +186,37 @@ extension CustomError: LocalizedError {
122
186
  return false
123
187
  }
124
188
  } catch {
125
- print("✨ Capacitor-updater: File not moved. source: \(source.path) dest: \(dest.path)")
126
- return true
189
+ print("\(self.TAG) File not moved. source: \(source.path) dest: \(dest.path)")
190
+ throw CustomError.cannotUnflat
127
191
  }
128
192
  }
129
193
 
130
- private func saveDownloaded(sourceZip: URL, version: String, base: URL) throws {
131
- prepareFolder(source: base)
132
- let destHot = base.appendingPathComponent(version)
133
- let destUnZip = documentsUrl.appendingPathComponent(randomString(length: 10))
194
+ private func saveDownloaded(sourceZip: URL, id: String, base: URL) throws {
195
+ try prepareFolder(source: base)
196
+ let destHot = base.appendingPathComponent(id)
197
+ let destUnZip = documentsDir.appendingPathComponent(randomString(length: 10))
134
198
  if (!SSZipArchive.unzipFile(atPath: sourceZip.path, toDestination: destUnZip.path)) {
135
199
  throw CustomError.cannotUnzip
136
200
  }
137
- if (unflatFolder(source: destUnZip, dest: destHot)) {
138
- deleteFolder(source: destUnZip)
201
+ if (try unflatFolder(source: destUnZip, dest: destHot)) {
202
+ try deleteFolder(source: destUnZip)
139
203
  }
140
204
  }
141
205
 
142
206
  public func getLatest(url: URL) -> AppVersion? {
143
207
  let semaphore = DispatchSemaphore(value: 0)
144
208
  let latest = AppVersion()
145
- let headers: HTTPHeaders = [
146
- "cap_platform": "ios",
147
- "cap_device_id": self.deviceID,
148
- "cap_app_id": self.appId,
149
- "cap_version_build": self.versionBuild,
150
- "cap_version_code": self.versionCode,
151
- "cap_version_os": self.versionOs,
152
- "cap_plugin_version": self.pluginVersion,
153
- "cap_version_name": UserDefaults.standard.string(forKey: "versionName") ?? "builtin"
209
+ let parameters: [String: String] = [
210
+ "platform": "ios",
211
+ "device_id": self.deviceID,
212
+ "app_id": self.appId,
213
+ "version_build": self.versionBuild,
214
+ "version_code": self.versionCode,
215
+ "version_os": self.versionOs,
216
+ "plugin_version": self.pluginVersion,
217
+ "version_name": self.getCurrentBundle().getVersionName()
154
218
  ]
155
- let request = AF.request(url, headers: headers)
219
+ let request = AF.request(url, method: .post,parameters: parameters, encoder: JSONParameterEncoder.default)
156
220
 
157
221
  request.validate().responseDecodable(of: AppVersionDec.self) { response in
158
222
  switch response.result {
@@ -168,9 +232,10 @@ extension CustomError: LocalizedError {
168
232
  }
169
233
  if let message = response.value?.message {
170
234
  latest.message = message
235
+ print("\(self.TAG) Auto-update message: \(message)")
171
236
  }
172
237
  case let .failure(error):
173
- print("✨ Capacitor-updater: Error getting Latest", error )
238
+ print("\(self.TAG) Error getting Latest", error )
174
239
  }
175
240
  semaphore.signal()
176
241
  }
@@ -178,9 +243,15 @@ extension CustomError: LocalizedError {
178
243
  return latest.url != "" ? latest : nil
179
244
  }
180
245
 
181
- public func download(url: URL) throws -> String {
246
+ private func setCurrentBundle(bundle: String) {
247
+ UserDefaults.standard.set(bundle, forKey: self.CAP_SERVER_PATH)
248
+ print("\(self.TAG) Current bundle set to: \(bundle)")
249
+ UserDefaults.standard.synchronize()
250
+ }
251
+
252
+ public func download(url: URL, version: String) throws -> BundleInfo {
182
253
  let semaphore = DispatchSemaphore(value: 0)
183
- var version: String = ""
254
+ let id: String = self.randomString(length: 10)
184
255
  var mainError: NSError? = nil
185
256
  let destination: DownloadRequest.Destination = { _, _ in
186
257
  let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
@@ -192,112 +263,143 @@ extension CustomError: LocalizedError {
192
263
 
193
264
  request.downloadProgress { progress in
194
265
  let percent = self.calcTotalPercent(percent: Int(progress.fractionCompleted * 100), min: 10, max: 70)
195
- self.notifyDownload(percent)
266
+ self.notifyDownload(id, percent)
196
267
  }
197
268
  request.responseURL { (response) in
198
269
  if let fileURL = response.fileURL {
199
270
  switch response.result {
200
271
  case .success:
201
- self.notifyDownload(71);
202
- version = self.randomString(length: 10)
272
+ self.notifyDownload(id, 71)
203
273
  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)
274
+ try self.saveDownloaded(sourceZip: fileURL, id: id, base: self.documentsDir.appendingPathComponent(self.bundleDirectoryHot))
275
+ self.notifyDownload(id, 85)
276
+ try self.saveDownloaded(sourceZip: fileURL, id: id, base: self.libraryDir.appendingPathComponent(self.bundleDirectory))
277
+ self.notifyDownload(id, 100)
278
+ try self.deleteFolder(source: fileURL)
209
279
  } catch {
210
- print("✨ Capacitor-updater: download unzip error", error)
280
+ print("\(self.TAG) download unzip error", error)
211
281
  mainError = error as NSError
212
282
  }
213
283
  case let .failure(error):
214
- print("✨ Capacitor-updater: download error", error)
284
+ print("\(self.TAG) download error", error)
215
285
  mainError = error as NSError
216
286
  }
217
287
  }
218
288
  semaphore.signal()
219
289
  }
220
- self.notifyDownload(0);
290
+ self.saveBundleInfo(id: id, bundle: BundleInfo(id: id, version: version, status: BundleStatus.DOWNLOADING, downloaded: Date()))
291
+ self.notifyDownload(id, 0)
221
292
  semaphore.wait()
222
293
  if (mainError != nil) {
223
294
  throw mainError!
224
295
  }
225
- return version
296
+ let info: BundleInfo = BundleInfo(id: id, version: version, status: BundleStatus.PENDING, downloaded: Date())
297
+ self.saveBundleInfo(id: id, bundle: info)
298
+ return info
226
299
  }
227
300
 
228
- public func list() -> [String] {
229
- let dest = documentsUrl.appendingPathComponent(basePathHot)
301
+ public func list() -> [BundleInfo] {
302
+ let dest = documentsDir.appendingPathComponent(bundleDirectoryHot)
230
303
  do {
231
304
  let files = try FileManager.default.contentsOfDirectory(atPath: dest.path)
232
- return files
305
+ var res: [BundleInfo] = []
306
+ print("\(self.TAG) list File : \(dest.path)")
307
+ if (dest.exist) {
308
+ for id in files {
309
+ res.append(self.getBundleInfo(id: id));
310
+ }
311
+ }
312
+ return res
233
313
  } catch {
234
- print("✨ Capacitor-updater: No version available \(dest.path)")
314
+ print("\(self.TAG) No version available \(dest.path)")
235
315
  return []
236
316
  }
237
317
  }
238
318
 
239
- public func delete(version: String, versionName: String) -> Bool {
240
- let destHot = documentsUrl.appendingPathComponent(basePathHot).appendingPathComponent(version)
241
- let destPersist = libraryUrl.appendingPathComponent(basePathPersist).appendingPathComponent(version)
319
+ public func delete(id: String) -> Bool {
320
+ let deleted: BundleInfo = self.getBundleInfo(id: id)
321
+ let destHot = documentsDir.appendingPathComponent(bundleDirectoryHot).appendingPathComponent(id)
322
+ let destPersist = libraryDir.appendingPathComponent(bundleDirectory).appendingPathComponent(id)
242
323
  do {
243
324
  try FileManager.default.removeItem(atPath: destHot.path)
244
325
  } catch {
245
- print("✨ Capacitor-updater: Hot Folder \(destHot.path), not removed.")
326
+ print("\(self.TAG) Hot Folder \(destHot.path), not removed.")
246
327
  }
247
328
  do {
248
329
  try FileManager.default.removeItem(atPath: destPersist.path)
249
330
  } catch {
250
- print("✨ Capacitor-updater: Folder \(destPersist.path), not removed.")
331
+ print("\(self.TAG) Folder \(destPersist.path), not removed.")
251
332
  return false
252
333
  }
253
- sendStats(action: "delete", version: versionName)
334
+ self.removeBundleInfo(id: id)
335
+ self.sendStats(action: "delete", bundle: deleted)
254
336
  return true
255
337
  }
256
338
 
257
- public func set(version: String, versionName: String) -> Bool {
258
- let destHot = documentsUrl.appendingPathComponent(basePathHot).appendingPathComponent(version)
339
+ public func getBundleDirectory(id: String) -> URL {
340
+ return libraryDir.appendingPathComponent(self.bundleDirectory).appendingPathComponent(id)
341
+ }
342
+
343
+ public func set(bundle: BundleInfo) -> Bool {
344
+ return self.set(id: bundle.getId());
345
+ }
346
+
347
+ public func set(id: String) -> Bool {
348
+ let destHot = self.getPathHot(id: id)
349
+ let destHotPersist = self.getPathPersist(id: id)
259
350
  let indexHot = destHot.appendingPathComponent("index.html")
260
- let destHotPersist = libraryUrl.appendingPathComponent(basePathPersist).appendingPathComponent(version)
261
351
  let indexPersist = destHotPersist.appendingPathComponent("index.html")
262
- if (destHot.isDirectory && destHotPersist.isDirectory && indexHot.exist && indexPersist.exist) {
263
- UserDefaults.standard.set(destHot.path, forKey: "lastPathHot")
264
- UserDefaults.standard.set(destHotPersist.path, forKey: "lastPathPersist")
265
- UserDefaults.standard.set(versionName, forKey: "versionName")
266
- sendStats(action: "set", version: versionName)
352
+ let existing: BundleInfo = self.getBundleInfo(id: id)
353
+ let bundle: URL = self.getBundleDirectory(id: id)
354
+ print("bundle", bundle.path)
355
+ if (bundle.isDirectory && destHotPersist.isDirectory && indexHot.exist && indexPersist.exist) {
356
+ self.setCurrentBundle(bundle: String(bundle.path.suffix(10)))
357
+ self.setBundleStatus(id: id, status: BundleStatus.PENDING)
358
+ sendStats(action: "set", bundle: existing)
267
359
  return true
268
360
  }
269
- sendStats(action: "set_fail", version: versionName)
361
+ sendStats(action: "set_fail", bundle: existing)
270
362
  return false
271
363
  }
272
364
 
273
- public func getLastPathHot() -> String {
274
- return UserDefaults.standard.string(forKey: "lastPathHot") ?? ""
365
+ public func getPathHot(id: String) -> URL {
366
+ return documentsDir.appendingPathComponent(self.bundleDirectoryHot).appendingPathComponent(id)
275
367
  }
276
368
 
277
- public func getVersionName() -> String {
278
- return UserDefaults.standard.string(forKey: "versionName") ?? ""
369
+ public func getPathPersist(id: String) -> URL {
370
+ return libraryDir.appendingPathComponent(self.bundleDirectory).appendingPathComponent(id)
279
371
  }
280
372
 
281
- public func getLastPathPersist() -> String {
282
- return UserDefaults.standard.string(forKey: "lastPathPersist") ?? ""
373
+ public func reset() {
374
+ self.reset(isInternal: false)
283
375
  }
284
376
 
285
- public func reset() {
286
- let version = UserDefaults.standard.string(forKey: "versionName") ?? ""
287
- sendStats(action: "reset", version: version)
288
- UserDefaults.standard.set("", forKey: "lastPathHot")
289
- UserDefaults.standard.set("", forKey: "lastPathPersist")
290
- UserDefaults.standard.set("", forKey: "versionName")
377
+ public func reset(isInternal: Bool) {
378
+ self.setCurrentBundle(bundle: "")
379
+ self.setFallbackVersion(fallback: Optional<BundleInfo>.none)
380
+ let _ = self.setNextVersion(next: Optional<String>.none)
291
381
  UserDefaults.standard.synchronize()
382
+ if(!isInternal) {
383
+ sendStats(action: "reset", bundle: self.getCurrentBundle())
384
+ }
385
+ }
386
+
387
+ public func commit(bundle: BundleInfo) {
388
+ self.setBundleStatus(id: bundle.getId(), status: BundleStatus.SUCCESS)
389
+ self.setFallbackVersion(fallback: bundle)
390
+ }
391
+
392
+ public func rollback(bundle: BundleInfo) {
393
+ self.setBundleStatus(id: bundle.getId(), status: BundleStatus.ERROR);
292
394
  }
293
395
 
294
- func sendStats(action: String, version: String) {
396
+ func sendStats(action: String, bundle: BundleInfo) {
295
397
  if (statsUrl == "") { return }
296
398
  let parameters: [String: String] = [
297
399
  "platform": "ios",
298
400
  "action": action,
299
401
  "device_id": self.deviceID,
300
- "version_name": version,
402
+ "version_name": bundle.getVersionName(),
301
403
  "version_build": self.versionBuild,
302
404
  "version_code": self.versionCode,
303
405
  "version_os": self.versionOs,
@@ -307,8 +409,122 @@ extension CustomError: LocalizedError {
307
409
 
308
410
  DispatchQueue.global(qos: .background).async {
309
411
  let _ = AF.request(self.statsUrl, method: .post,parameters: parameters, encoder: JSONParameterEncoder.default)
310
- print("✨ Capacitor-updater: Stats send for \(action), version \(version)")
412
+ print("\(self.TAG) Stats send for \(action), version \(bundle.getVersionName())")
311
413
  }
312
414
  }
313
-
415
+
416
+ public func getBundleInfo(id: String = BundleInfo.ID_BUILTIN) -> BundleInfo {
417
+ print("\(self.TAG) Getting info for bundle [\(id)]")
418
+ if(BundleInfo.ID_BUILTIN == id) {
419
+ return BundleInfo(id: id, version: "", status: BundleStatus.SUCCESS)
420
+ }
421
+ do {
422
+ let result: BundleInfo = try UserDefaults.standard.getObj(forKey: "\(id)\(self.INFO_SUFFIX)", castTo: BundleInfo.self)
423
+ print("\(self.TAG) Returning info bundle [\(id)]", result.toString())
424
+ return result
425
+ } catch {
426
+ print("\(self.TAG) Failed to parse info for bundle [\(id)]", error.localizedDescription)
427
+ return BundleInfo(id: id, version: "", status: BundleStatus.PENDING)
428
+ }
429
+ }
430
+
431
+ public func getBundleInfoByVersionName(version: String) -> BundleInfo? {
432
+ let installed : Array<BundleInfo> = self.list()
433
+ for i in installed {
434
+ if(i.getVersionName() == version) {
435
+ return i
436
+ }
437
+ }
438
+ return nil
439
+ }
440
+
441
+ private func removeBundleInfo(id: String) {
442
+ self.saveBundleInfo(id: id, bundle: nil)
443
+ }
444
+
445
+ private func saveBundleInfo(id: String, bundle: BundleInfo?) {
446
+ if (bundle != nil && (bundle!.isBuiltin() || bundle!.isUnknown())) {
447
+ print("\(self.TAG) Not saving info for bundle [\(id)]", bundle!.toString())
448
+ return
449
+ }
450
+ if(bundle == nil) {
451
+ print("\(self.TAG) Removing info for bundle [\(id)]")
452
+ UserDefaults.standard.removeObject(forKey: "\(id)\(self.INFO_SUFFIX)")
453
+ } else {
454
+ let update = bundle!.setId(id: id)
455
+ print("\(self.TAG) Storing info for bundle [\(id)]", update.toString())
456
+ do {
457
+ try UserDefaults.standard.setObj(update, forKey: "\(id)\(self.INFO_SUFFIX)")
458
+ } catch {
459
+ print("\(self.TAG) Failed to save info for bundle [\(id)]", error.localizedDescription)
460
+ }
461
+ }
462
+ UserDefaults.standard.synchronize()
463
+ }
464
+
465
+ public func setVersionName(id: String, version: String) {
466
+ print("\(self.TAG) Setting version for folder [\(id)] to \(version)")
467
+ let info = self.getBundleInfo(id: id)
468
+ self.saveBundleInfo(id: id, bundle: info.setVersionName(version: version))
469
+ }
470
+
471
+ private func setBundleStatus(id: String, status: BundleStatus) {
472
+ print("\(self.TAG) Setting status for bundle [\(id)] to \(status)")
473
+ let info = self.getBundleInfo(id: id)
474
+ self.saveBundleInfo(id: id, bundle: info.setStatus(status: status.localizedString))
475
+ }
476
+
477
+ private func getCurrentBundleVersion() -> String {
478
+ if(self.isUsingBuiltin()) {
479
+ return BundleInfo.ID_BUILTIN
480
+ } else {
481
+ let path: String = self.getCurrentBundleId()
482
+ return path.lastPathComponent
483
+ }
484
+ }
485
+
486
+ public func getCurrentBundle() -> BundleInfo {
487
+ return self.getBundleInfo(id: self.getCurrentBundleId());
488
+ }
489
+
490
+ public func getCurrentBundleId() -> String {
491
+ return UserDefaults.standard.string(forKey: self.CAP_SERVER_PATH) ?? self.DEFAULT_FOLDER
492
+ }
493
+
494
+ public func isUsingBuiltin() -> Bool {
495
+ return self.getCurrentBundleId() == self.DEFAULT_FOLDER
496
+ }
497
+
498
+ public func getFallbackVersion() -> BundleInfo {
499
+ let id: String = UserDefaults.standard.string(forKey: self.FALLBACK_VERSION) ?? BundleInfo.ID_BUILTIN
500
+ return self.getBundleInfo(id: id)
501
+ }
502
+
503
+ private func setFallbackVersion(fallback: BundleInfo?) {
504
+ UserDefaults.standard.set(fallback == nil ? BundleInfo.ID_BUILTIN : fallback!.getId(), forKey: self.FALLBACK_VERSION)
505
+ }
506
+
507
+ public func getNextVersion() -> BundleInfo? {
508
+ let id: String = UserDefaults.standard.string(forKey: self.NEXT_VERSION) ?? ""
509
+ if(id != "") {
510
+ return self.getBundleInfo(id: id)
511
+ } else {
512
+ return nil
513
+ }
514
+ }
515
+
516
+ public func setNextVersion(next: String?) -> Bool {
517
+ if (next == nil) {
518
+ UserDefaults.standard.removeObject(forKey: self.NEXT_VERSION)
519
+ } else {
520
+ let bundle: URL = self.getBundleDirectory(id: next!)
521
+ if (!bundle.exist) {
522
+ return false
523
+ }
524
+ UserDefaults.standard.set(next, forKey: self.NEXT_VERSION)
525
+ self.setBundleStatus(id: next!, status: BundleStatus.PENDING);
526
+ }
527
+ UserDefaults.standard.synchronize()
528
+ return true
529
+ }
314
530
  }
@@ -11,9 +11,10 @@ CAP_PLUGIN(CapacitorUpdaterPlugin, "CapacitorUpdater",
11
11
  CAP_PLUGIN_METHOD(reset, CAPPluginReturnPromise);
12
12
  CAP_PLUGIN_METHOD(current, CAPPluginReturnPromise);
13
13
  CAP_PLUGIN_METHOD(reload, CAPPluginReturnPromise);
14
- CAP_PLUGIN_METHOD(versionName, CAPPluginReturnPromise);
15
14
  CAP_PLUGIN_METHOD(notifyAppReady, CAPPluginReturnPromise);
16
- CAP_PLUGIN_METHOD(delayUpdate, CAPPluginReturnPromise);
15
+ CAP_PLUGIN_METHOD(setDelay, CAPPluginReturnPromise);
17
16
  CAP_PLUGIN_METHOD(getId, CAPPluginReturnPromise);
18
17
  CAP_PLUGIN_METHOD(getPluginVersion, CAPPluginReturnPromise);
18
+ CAP_PLUGIN_METHOD(next, CAPPluginReturnPromise);
19
+ CAP_PLUGIN_METHOD(isAutoUpdateEnabled, CAPPluginReturnPromise);
19
20
  )