Skip to content

Commit

Permalink
feat: add versionName and reload + WIP auto update
Browse files Browse the repository at this point in the history
  • Loading branch information
riderx committed Jan 7, 2022
1 parent 5f93f71 commit cae43cc
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,14 @@ public Boolean delete(String version) throws IOException {
return false;
}

public Boolean set(String version) {
public Boolean set(String version, String versionName) {
File destHot = new File(this.context.getFilesDir() + "/" + basePathHot + "/" + version);
File destIndex = new File(destHot.getPath() + "/index.html");
Log.i(TAG, "set File : " + destHot.getPath());
if (destHot.exists() && destIndex.exists()) {
editor.putString("lastPathHot", destHot.getPath());
editor.putString("serverBasePath", destHot.getPath());
editor.putString("versionName", versionName);
editor.commit();
return true;
}
Expand All @@ -206,6 +207,9 @@ public Boolean set(String version) {
public String getLastPathHot() {
return prefs.getString("lastPathHot", "");
}
public String getVersionName() {
return prefs.getString("versionName", "");
}
public void reset() {
editor.putString("lastPathHot", "public");
editor.putString("serverBasePath", "public");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,27 @@
import java.util.ArrayList;

@CapacitorPlugin(name = "CapacitorUpdater")
public class CapacitorUpdaterPlugin extends Plugin {
public class CapacitorUpdaterPlugin extends Plugin{
// public class CapacitorUpdaterPlugin extends Plugin, Application.ActivityLifecycleCallbacks {
private CapacitorUpdater implementation;

@Override
public void load() {
super.load();
implementation = new CapacitorUpdater(this.getContext());
// registerActivityLifecycleCallbacks(AppLifecycleTracker());
}
// private CapacitorUpdater implementation = new CapacitorUpdater(this.getContext());

// override fun onActivityStarted(activity: Activity?) {
// Log.i("CapacitorUpdater", "on foreground");
// }

// override fun onActivityStopped(activity: Activity?) {
// Log.i("CapacitorUpdater", "oN background");

// }

@PluginMethod
public void download(PluginCall call) {
String url = call.getString("url");
Expand All @@ -37,10 +48,25 @@ public void download(PluginCall call) {
}
}

private boolean _reload() {
String pathHot = implementation.getLastPathHot();
Log.i("CapacitorUpdater", "getLastPathHot : " + pathHot);
this.bridge.setServerBasePath(pathHot);
return true;
}
@PluginMethod
public void reload(PluginCall call) {
if (this._reload()) {
call.resolve();
} else {
call.reject("reload failed");
}
}
@PluginMethod
public void set(PluginCall call) {
String version = call.getString("version");
Boolean res = implementation.set(version);
String versionName = call.getString("versionName", version);
Boolean res = implementation.set(version, versionName);

if (!res) {
call.reject("Update failed, version don't exist");
Expand Down Expand Up @@ -93,4 +119,12 @@ public void current(PluginCall call) {
ret.put("current", current);
call.resolve(ret);
}

@PluginMethod
public void versionName(PluginCall call) {
String name = implementation.getVersionName();
JSObject ret = new JSObject();
ret.put("versionName", name);
call.resolve(ret);
}
}
24 changes: 23 additions & 1 deletion ios/Plugin/CapacitorUpdater.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ extension URL {
return FileManager().fileExists(atPath: self.path)
}
}
public class AppVersion: NSObject {
var version: String = ""
var url: String = ""
}

@objc public class CapacitorUpdater: NSObject {

Expand Down Expand Up @@ -92,6 +96,19 @@ extension URL {
}
}

@objc public func getLatest(url: URL) -> AppVersion? {
print("URL " + url.path)
let r = Just.get(url)
if r.ok {
let latest = r.json as? AppVersion
// { version: version.name, url: res.signedURL }
return latest
} else {
print("Error get Latest", r.error ?? "unknow")
}
return nil
}

@objc public func download(url: URL) -> String? {
print("URL " + url.path)
let r = Just.get(url)
Expand Down Expand Up @@ -130,14 +147,15 @@ extension URL {
return true
}

@objc public func set(version: String) -> Bool {
@objc public func set(version: String, versionName: String) -> Bool {
let destHot = documentsUrl.appendingPathComponent(basePathHot).appendingPathComponent(version)
let indexHot = destHot.appendingPathComponent("index.html")
let destHotPersist = libraryUrl.appendingPathComponent(basePathPersist).appendingPathComponent(version)
let indexPersist = destHot.appendingPathComponent("index.html")
if (destHot.isDirectory && destHotPersist.isDirectory && indexHot.exist && indexPersist.exist) {
UserDefaults.standard.set(destHot.path, forKey: "lastPathHot")
UserDefaults.standard.set(destHotPersist.path, forKey: "lastPathPersist")
UserDefaults.standard.set(versionName, forKey: "versionName")
return true
}
return false
Expand All @@ -147,6 +165,10 @@ extension URL {
return UserDefaults.standard.string(forKey: "lastPathHot") ?? ""
}

@objc public func getVersionName() -> String {
return UserDefaults.standard.string(forKey: "versionName") ?? ""
}

@objc public func getLastPathPersist() -> String {
return UserDefaults.standard.string(forKey: "lastPathPersist") ?? ""
}
Expand Down
2 changes: 2 additions & 0 deletions ios/Plugin/CapacitorUpdaterPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@
CAP_PLUGIN_METHOD(load, CAPPluginReturnNone);
CAP_PLUGIN_METHOD(reset, CAPPluginReturnNone);
CAP_PLUGIN_METHOD(current, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(reload, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(versionName, CAPPluginReturnPromise);
)
123 changes: 94 additions & 29 deletions ios/Plugin/CapacitorUpdaterPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,53 @@ import Capacitor
@objc(CapacitorUpdaterPlugin)
public class CapacitorUpdaterPlugin: CAPPlugin {
private let implementation = CapacitorUpdater()
private var autoUpdate = false
private var autoUpdateUrl = ""

override public func load() {
autoUpdateUrl = getConfigValue("autoUpdateUrl") as? String ?? ""
if autoUpdateUrl != "" {
autoUpdate = true
let nc = NotificationCenter.default
nc.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
nc.addObserver(self, selector: #selector(appMovedToForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
}
}

@objc func appMovedToBackground() {
print("appMovedToBackground")
let nextVersion = UserDefaults.standard.string(forKey: "nextVersion") ?? ""
let nextVersionName = UserDefaults.standard.string(forKey: "nextVersionName") ?? ""
if (nextVersion != "" && nextVersionName != "") {
let res = implementation.set(version: nextVersion, versionName: nextVersionName)
if (res) {
if (self._reload()) {
print("Auto update to VersionName: " + nextVersionName + ", Version: " + nextVersion)
}
UserDefaults.standard.set("", forKey: "nextVersion")
UserDefaults.standard.set("", forKey: "nextVersionName")
}

}
}

@objc func appMovedToForeground() {
print("appMovedToForeground")
let url = URL(string: autoUpdateUrl)!
let res = implementation.getLatest(url: url)
guard let downloadUrl = URL(string: res?.url ?? "") else {
return
}
let name = implementation.getVersionName()
if (res?.version != name) {
let dl = implementation.download(url: downloadUrl)
UserDefaults.standard.set(dl, forKey: "nextVersion")
UserDefaults.standard.set(res?.version, forKey: "nextVersionName")
}
}

@objc func download(_ call: CAPPluginCall) {
let url = URL(string: call.getString("url") ?? "")

let res = implementation.download(url: url!)
if ((res) != nil) {
call.resolve([
Expand All @@ -22,26 +65,42 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
}
}

private func _reload() -> Bool {
guard let bridge = self.bridge else { return false }

if let vc = bridge.viewController as? CAPBridgeViewController {
let pathHot = implementation.getLastPathHot()
let pathPersist = implementation.getLastPathPersist()
if (pathHot != "" && pathPersist != "") {
UserDefaults.standard.set(String(pathPersist.suffix(10)), forKey: "serverBasePath")
vc.setServerBasePath(path: pathHot)
return true
} else {
return false
}
}
return false
}

@objc func reload(_ call: CAPPluginCall) {
if (self._reload()) {
call.resolve()
} else {
call.reject("Cannot reload")
}
}

@objc func set(_ call: CAPPluginCall) {
let version = call.getString("version") ?? ""
let res = implementation.set(version: version)
let defaults = UserDefaults.standard
let versionName = call.getString("versionName") ?? version
let res = implementation.set(version: version, versionName: versionName)

if (res) {
guard let bridge = self.bridge else { return call.reject("bridge missing") }

if let vc = bridge.viewController as? CAPBridgeViewController {
let pathHot = implementation.getLastPathHot()
let pathPersist = implementation.getLastPathPersist()
if (pathHot != "" && pathPersist != "") {
defaults.set(String(pathPersist.suffix(10)), forKey: "serverBasePath")
vc.setServerBasePath(path: pathHot)
return call.resolve()
} else {
return call.reject("cannot set " + version)
}
if (self._reload()) {
call.resolve()
} else {
call.reject("Cannot reload")
}
call.reject("Update failed, viewController missing")
} else {
call.reject("Update failed, version " + version + " don't exist")
}
Expand All @@ -65,22 +124,28 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
}

@objc func reset(_ call: CAPPluginCall) {
guard let bridge = self.bridge else { return call.reject("bridge missing") }
if let vc = bridge.viewController as? CAPBridgeViewController {
let defaults = UserDefaults.standard
implementation.reset()
let pathPersist = implementation.getLastPathPersist()
vc.setServerBasePath(path: pathPersist)
defaults.set("", forKey: "serverBasePath")
DispatchQueue.main.async {
vc.loadView()
vc.viewDidLoad()
}
return call.resolve()
}
guard let bridge = self.bridge else { return call.reject("bridge missing") }
if let vc = bridge.viewController as? CAPBridgeViewController {
implementation.reset()
let pathPersist = implementation.getLastPathPersist()
vc.setServerBasePath(path: pathPersist)
UserDefaults.standard.set("", forKey: "serverBasePath")
DispatchQueue.main.async {
vc.loadView()
vc.viewDidLoad()
}
return call.resolve()
}
call.reject("Reset failed, not implemented")
}

@objc func versionName(_ call: CAPPluginCall) {
let name = implementation.getVersionName()
call.resolve([
"versionName": name
])
}

@objc func current(_ call: CAPPluginCall) {
let pathHot = implementation.getLastPathHot()
let current = pathHot.count >= 10 ? pathHot.suffix(10) : "default"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "capacitor-updater",
"version": "1.0.24",
"version": "1.0.25",
"license": "AGPL-3.0-only",
"description": "Download app update from url",
"main": "dist/plugin.cjs.js",
Expand Down
15 changes: 13 additions & 2 deletions src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ export interface CapacitorUpdaterPlugin {
*/
download(options: { url: string }): Promise<{ version: string }>;
/**
* set version as current version, set will return error if there are no index.html file inside the version folder
* set version as current version, set will return error if there are no index.html file inside the version folder, versionName is optional and it's a custom value who will be saved for you
* @returns {Promise<void>} an empty Promise when the version is set, if there are no index.html or no version folder throw an error
* @param version The version name to set as current version
*/
set(options: { version: string }): Promise<void>;
set(options: { version: string, versionName }): Promise<void>;
/**
* delete version in storage
* @returns {Promise<void>} an empty Promise when the version is delete, otherwise throw an error
Expand All @@ -32,4 +32,15 @@ export interface CapacitorUpdaterPlugin {
* @returns {Promise<{ current: string }>} an Promise with the current version name
*/
current(): Promise<{ current: string }>;
/**
* reload the view
* @returns {Promise<void>} an Promise resolved when the view is reloaded
*/
reload(): Promise<void>;
/**
* Get the version name, if it was set during the set phase
* @returns {Promise<{ versionName: string }>} an Promise witht the current versionName
*/
versionName(): Promise<{ versionName: string }>;

}

0 comments on commit cae43cc

Please sign in to comment.