updateflow 1.0.0 → 1.0.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/android-setup/MainActivity.java +45 -63
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/updateflow.service.d.ts +2 -27
- package/dist/updateflow.service.d.ts.map +1 -1
- package/dist/updateflow.service.js +40 -60
- package/dist/updateflow.service.js.map +1 -1
- package/ios-setup/AppDelegate.swift +30 -24
- package/ios-setup/Main.storyboard +1 -1
- package/ios-setup/ViewController.swift +3 -3
- package/package.json +1 -7
|
@@ -1,91 +1,73 @@
|
|
|
1
|
-
package io.ionic.starter;
|
|
1
|
+
package io.ionic.starter; // <-- Apna package name check kar lein agar alag hai toh
|
|
2
2
|
|
|
3
|
-
import android.content.SharedPreferences;
|
|
4
3
|
import android.os.Bundle;
|
|
5
4
|
import android.util.Log;
|
|
6
|
-
|
|
7
5
|
import com.getcapacitor.BridgeActivity;
|
|
8
|
-
|
|
9
6
|
import java.io.File;
|
|
10
7
|
|
|
11
8
|
public class MainActivity extends BridgeActivity {
|
|
12
9
|
|
|
13
|
-
private static final String TAG = "OTA";
|
|
14
|
-
|
|
15
|
-
// FIX: Yeh keys Angular service se match karni chahiye
|
|
16
|
-
private static final String KEY_VERSION = "app_current_version"; // ← Angular service wali key
|
|
17
|
-
private static final String KEY_PATH = "local_ota_path";
|
|
18
|
-
|
|
19
10
|
@Override
|
|
20
|
-
|
|
11
|
+
protected void onCreate(Bundle savedInstanceState) {
|
|
21
12
|
super.onCreate(savedInstanceState);
|
|
22
|
-
applyOtaUpdateIfAvailable();
|
|
23
13
|
}
|
|
24
14
|
|
|
25
15
|
@Override
|
|
26
|
-
public void
|
|
27
|
-
super.
|
|
28
|
-
|
|
16
|
+
public void onStart() {
|
|
17
|
+
super.onStart();
|
|
18
|
+
applyOTAUpdate();
|
|
29
19
|
}
|
|
30
20
|
|
|
31
|
-
private void
|
|
21
|
+
private void applyOTAUpdate() {
|
|
32
22
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
File filesDir = getFilesDir();
|
|
24
|
+
File updatesDir = new File(filesDir, "updates");
|
|
35
25
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (otaVersion == null) {
|
|
40
|
-
Log.i(TAG, "No OTA version saved — standard boot.");
|
|
26
|
+
if (!updatesDir.exists()) {
|
|
27
|
+
Log.d("OTA_DEBUG", "Updates folder nahi mila: " + updatesDir.getPath());
|
|
41
28
|
return;
|
|
42
29
|
}
|
|
43
30
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
File
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
31
|
+
File[] folders = updatesDir.listFiles();
|
|
32
|
+
if (folders == null || folders.length == 0) return;
|
|
33
|
+
|
|
34
|
+
double maxVer = -1.0;
|
|
35
|
+
File bestPath = null;
|
|
36
|
+
|
|
37
|
+
for (File folder : folders) {
|
|
38
|
+
if (folder.isDirectory()) {
|
|
39
|
+
try {
|
|
40
|
+
String folderName = folder.getName().toLowerCase().replace("v", "");
|
|
41
|
+
double v = Double.parseDouble(folderName);
|
|
42
|
+
|
|
43
|
+
if (v >= maxVer) {
|
|
44
|
+
File wwwIndex = new File(folder, "www/index.html");
|
|
45
|
+
File rootIndex = new File(folder, "index.html");
|
|
46
|
+
|
|
47
|
+
if (wwwIndex.exists()) {
|
|
48
|
+
maxVer = v;
|
|
49
|
+
bestPath = new File(folder, "www");
|
|
50
|
+
} else if (rootIndex.exists()) {
|
|
51
|
+
maxVer = v;
|
|
52
|
+
bestPath = folder;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
} catch (Exception e) {
|
|
56
|
+
Log.e("OTA_DEBUG", "Folder parsing error: " + folder.getName());
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
52
60
|
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
Log.
|
|
57
|
-
} else if (indexFile.exists()) {
|
|
58
|
-
// root index.html mila
|
|
59
|
-
Log.i(TAG, "Found root index.html");
|
|
61
|
+
if (bestPath != null) {
|
|
62
|
+
String absolutePath = bestPath.getAbsolutePath();
|
|
63
|
+
this.bridge.setServerBasePath(absolutePath);
|
|
64
|
+
Log.d("OTA_DEBUG", "🔥 OTA SUCCESS: v" + maxVer + " from " + absolutePath);
|
|
60
65
|
} else {
|
|
61
|
-
Log.
|
|
62
|
-
clearOtaPreferences();
|
|
63
|
-
return;
|
|
66
|
+
Log.d("OTA_DEBUG", "Koi valid OTA version nahi mila.");
|
|
64
67
|
}
|
|
65
68
|
|
|
66
|
-
setCapacitorServerPath(otaFolderPath);
|
|
67
|
-
Log.i(TAG, "OTA ACTIVE: v" + otaVersion + " -> " + otaFolderPath);
|
|
68
|
-
|
|
69
69
|
} catch (Exception e) {
|
|
70
|
-
Log.e(
|
|
70
|
+
Log.e("OTA_DEBUG", "OTA check error: ", e);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
|
|
74
|
-
private void setCapacitorServerPath(String path) {
|
|
75
|
-
getBridge().setServerBasePath(path);
|
|
76
|
-
|
|
77
|
-
getSharedPreferences("CapWebViewSettings", MODE_PRIVATE)
|
|
78
|
-
.edit().putString("serverBasePath", path).apply();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
private void clearOtaPreferences() {
|
|
82
|
-
getSharedPreferences("CapacitorStorage", MODE_PRIVATE)
|
|
83
|
-
.edit()
|
|
84
|
-
.remove(KEY_VERSION)
|
|
85
|
-
.remove(KEY_PATH)
|
|
86
|
-
.apply();
|
|
87
|
-
|
|
88
|
-
getSharedPreferences("CapWebViewSettings", MODE_PRIVATE)
|
|
89
|
-
.edit().remove("serverBasePath").apply();
|
|
90
|
-
}
|
|
91
73
|
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EAAE,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -1,46 +1,21 @@
|
|
|
1
1
|
import { HttpClient } from '@angular/common/http';
|
|
2
2
|
import { Platform } from '@ionic/angular';
|
|
3
3
|
export interface UpdateFlowConfig {
|
|
4
|
-
/** UpdateFlow dashboard se API URL — Required */
|
|
5
4
|
apiUrl: string;
|
|
6
|
-
/** Dashboard se milne wali unique API key — Required */
|
|
7
5
|
apiKey: string;
|
|
8
|
-
/** Update ke baad alert dikhaye? Default: true */
|
|
9
6
|
showAlerts?: boolean;
|
|
10
|
-
/** Debug logs? Default: false */
|
|
11
7
|
debug?: boolean;
|
|
12
8
|
}
|
|
13
|
-
export interface UpdateInfo {
|
|
14
|
-
update_available: boolean;
|
|
15
|
-
new_version?: string;
|
|
16
|
-
url?: string;
|
|
17
|
-
is_critical?: boolean;
|
|
18
|
-
release_notes?: string;
|
|
19
|
-
}
|
|
20
9
|
export declare class UpdateFlowService {
|
|
21
10
|
private http;
|
|
22
11
|
private platform;
|
|
23
12
|
currentVersion: string;
|
|
24
13
|
private config;
|
|
25
|
-
private readonly KEY_VERSION;
|
|
26
|
-
private readonly KEY_PATH;
|
|
27
14
|
constructor(http: HttpClient, platform: Platform);
|
|
28
|
-
/**
|
|
29
|
-
* App start par call karo — app.component.ts ke ngOnInit mein
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* await this.updateFlow.init({
|
|
33
|
-
* apiUrl: 'https://YOUR-DASHBOARD/check_update.php',
|
|
34
|
-
* apiKey: 'YOUR_API_KEY'
|
|
35
|
-
* });
|
|
36
|
-
*/
|
|
37
15
|
init(config: UpdateFlowConfig): Promise<void>;
|
|
38
|
-
private
|
|
39
|
-
private
|
|
40
|
-
/** Current version return karta hai */
|
|
16
|
+
private checkServerForUpdate;
|
|
17
|
+
private downloadAndExtract;
|
|
41
18
|
getVersion(): string;
|
|
42
|
-
/** Manually update check trigger karo */
|
|
43
19
|
checkNow(): void;
|
|
44
|
-
private log;
|
|
45
20
|
}
|
|
46
21
|
//# sourceMappingURL=updateflow.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updateflow.service.d.ts","sourceRoot":"","sources":["../src/updateflow.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAK1C,MAAM,WAAW,gBAAgB;IAC/B,
|
|
1
|
+
{"version":3,"file":"updateflow.service.d.ts","sourceRoot":"","sources":["../src/updateflow.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAK1C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBACa,iBAAiB;IAM1B,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,QAAQ;IALX,cAAc,SAAM;IAC3B,OAAO,CAAC,MAAM,CAAoB;gBAGxB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ;IAGf,IAAI,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B1D,OAAO,CAAC,oBAAoB;YAsBd,kBAAkB;IAyDzB,UAAU,IAAI,MAAM;IACpB,QAAQ,IAAI,IAAI;CACxB"}
|
|
@@ -22,23 +22,11 @@ let UpdateFlowService = class UpdateFlowService {
|
|
|
22
22
|
this.http = http;
|
|
23
23
|
this.platform = platform;
|
|
24
24
|
this.currentVersion = '';
|
|
25
|
-
// iOS AppDelegate + Android MainActivity se match karne wali keys
|
|
26
|
-
this.KEY_VERSION = 'app_current_version';
|
|
27
|
-
this.KEY_PATH = 'local_ota_path';
|
|
28
25
|
}
|
|
29
|
-
/**
|
|
30
|
-
* App start par call karo — app.component.ts ke ngOnInit mein
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* await this.updateFlow.init({
|
|
34
|
-
* apiUrl: 'https://YOUR-DASHBOARD/check_update.php',
|
|
35
|
-
* apiKey: 'YOUR_API_KEY'
|
|
36
|
-
* });
|
|
37
|
-
*/
|
|
38
26
|
async init(config) {
|
|
39
27
|
this.config = Object.assign({ showAlerts: true, debug: false }, config);
|
|
40
28
|
if (!this.platform.is('hybrid')) {
|
|
41
|
-
|
|
29
|
+
console.log('[UpdateFlow] Browser: OTA skipped.');
|
|
42
30
|
return;
|
|
43
31
|
}
|
|
44
32
|
if (!config.apiKey || !config.apiUrl) {
|
|
@@ -46,95 +34,87 @@ let UpdateFlowService = class UpdateFlowService {
|
|
|
46
34
|
return;
|
|
47
35
|
}
|
|
48
36
|
try {
|
|
49
|
-
const { value } = await preferences_1.Preferences.get({ key:
|
|
37
|
+
const { value } = await preferences_1.Preferences.get({ key: 'app_current_version' });
|
|
50
38
|
const appInfo = await app_1.App.getInfo();
|
|
51
39
|
this.currentVersion = value || appInfo.version;
|
|
52
|
-
|
|
53
|
-
this.
|
|
40
|
+
console.log('[UpdateFlow] Current App Version:', this.currentVersion);
|
|
41
|
+
this.checkServerForUpdate();
|
|
54
42
|
}
|
|
55
|
-
catch (
|
|
56
|
-
console.error('[UpdateFlow] Init
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.error('[UpdateFlow] Init Error:', error);
|
|
57
45
|
}
|
|
58
46
|
}
|
|
59
|
-
|
|
47
|
+
checkServerForUpdate() {
|
|
60
48
|
const url = `${this.config.apiUrl}?current_version=${this.currentVersion}&api_key=${this.config.apiKey}`;
|
|
61
49
|
this.http.get(url).subscribe({
|
|
62
|
-
next: async (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.
|
|
66
|
-
await this.downloadAndApply(res.url, res.new_version, (_a = res.is_critical) !== null && _a !== void 0 ? _a : false);
|
|
50
|
+
next: async (response) => {
|
|
51
|
+
if (response && response.update_available) {
|
|
52
|
+
console.log('[UpdateFlow] New version found:', response.new_version);
|
|
53
|
+
await this.downloadAndExtract(response.url, response.new_version, response.is_critical);
|
|
67
54
|
}
|
|
68
55
|
else {
|
|
69
|
-
|
|
56
|
+
console.log('[UpdateFlow] App is up to date.');
|
|
70
57
|
}
|
|
71
58
|
},
|
|
72
59
|
error: (err) => {
|
|
73
60
|
if (err.status === 401) {
|
|
74
61
|
console.error('[UpdateFlow] Invalid API key');
|
|
75
62
|
}
|
|
76
|
-
else if (err.status === 403) {
|
|
77
|
-
console.error('[UpdateFlow] Account suspended');
|
|
78
|
-
}
|
|
79
63
|
else {
|
|
80
|
-
console.error('[UpdateFlow] Server error:', err
|
|
64
|
+
console.error('[UpdateFlow] Server error:', err);
|
|
81
65
|
}
|
|
82
66
|
}
|
|
83
67
|
});
|
|
84
68
|
}
|
|
85
|
-
async
|
|
69
|
+
async downloadAndExtract(zipUrl, newVersion, isCritical) {
|
|
86
70
|
try {
|
|
87
|
-
|
|
71
|
+
console.log('[UpdateFlow] Downloading zip...');
|
|
88
72
|
const download = await filesystem_1.Filesystem.downloadFile({
|
|
89
73
|
url: zipUrl,
|
|
90
|
-
path: `
|
|
74
|
+
path: `update_${newVersion}.zip`,
|
|
91
75
|
directory: filesystem_1.Directory.Data
|
|
92
76
|
});
|
|
77
|
+
console.log('[UpdateFlow] Download complete. Starting unzip...');
|
|
78
|
+
const targetFolder = `updates/${newVersion}`;
|
|
93
79
|
const targetUri = await filesystem_1.Filesystem.getUri({
|
|
94
80
|
directory: filesystem_1.Directory.Data,
|
|
95
|
-
path:
|
|
81
|
+
path: targetFolder
|
|
96
82
|
});
|
|
97
|
-
|
|
83
|
+
console.log('[UpdateFlow] Target URI:', targetUri.uri);
|
|
98
84
|
zip.unzip(download.path, targetUri.uri, async (result) => {
|
|
99
85
|
if (result === 0) {
|
|
100
|
-
|
|
101
|
-
await preferences_1.Preferences.set({ key:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
});
|
|
106
|
-
this.currentVersion = newVersion;
|
|
86
|
+
console.log('[UpdateFlow] Unzip Success!');
|
|
87
|
+
await preferences_1.Preferences.set({ key: 'app_current_version', value: newVersion });
|
|
88
|
+
const absolutePath = targetUri.uri.replace('file://', '');
|
|
89
|
+
await preferences_1.Preferences.set({ key: 'local_ota_path', value: absolutePath });
|
|
90
|
+
console.log('[UpdateFlow] OTA path saved:', absolutePath);
|
|
107
91
|
await filesystem_1.Filesystem.deleteFile({
|
|
108
|
-
path: `
|
|
92
|
+
path: `update_${newVersion}.zip`,
|
|
109
93
|
directory: filesystem_1.Directory.Data
|
|
110
|
-
})
|
|
94
|
+
});
|
|
95
|
+
this.currentVersion = newVersion;
|
|
111
96
|
if (this.config.showAlerts) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
97
|
+
if (isCritical) {
|
|
98
|
+
alert('Zaruri update install ho gaya hai! App ab restart hogi.');
|
|
99
|
+
window.location.reload();
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
alert('Naya update install ho gaya hai. Agli baar app kholne par apply hoga.');
|
|
103
|
+
}
|
|
115
104
|
}
|
|
116
105
|
}
|
|
117
106
|
else {
|
|
118
|
-
console.error('[UpdateFlow]
|
|
107
|
+
console.error('[UpdateFlow] Unzip failed! Result code:', result);
|
|
119
108
|
}
|
|
120
109
|
});
|
|
121
110
|
}
|
|
122
|
-
catch (
|
|
123
|
-
console.error('[UpdateFlow] Error:',
|
|
111
|
+
catch (error) {
|
|
112
|
+
console.error('[UpdateFlow] OTA Error:', error);
|
|
124
113
|
}
|
|
125
114
|
}
|
|
126
|
-
/** Current version return karta hai */
|
|
127
115
|
getVersion() { return this.currentVersion; }
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (this.currentVersion)
|
|
131
|
-
this.checkForUpdate();
|
|
132
|
-
}
|
|
133
|
-
log(msg) {
|
|
134
|
-
var _a;
|
|
135
|
-
if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.debug)
|
|
136
|
-
console.log('[UpdateFlow]', msg);
|
|
137
|
-
}
|
|
116
|
+
checkNow() { if (this.currentVersion)
|
|
117
|
+
this.checkServerForUpdate(); }
|
|
138
118
|
};
|
|
139
119
|
exports.UpdateFlowService = UpdateFlowService;
|
|
140
120
|
exports.UpdateFlowService = UpdateFlowService = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updateflow.service.js","sourceRoot":"","sources":["../src/updateflow.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,wCAA2C;AAC3C,+CAAkD;AAClD,sDAA8D;AAC9D,wDAAqD;AACrD,4CAA0C;AAC1C,wCAAqC;
|
|
1
|
+
{"version":3,"file":"updateflow.service.js","sourceRoot":"","sources":["../src/updateflow.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,12 +11,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
|
11
11
|
let defaults = UserDefaults.standard
|
|
12
12
|
let fileManager = FileManager.default
|
|
13
13
|
|
|
14
|
-
guard let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
|
|
15
|
-
return true
|
|
16
|
-
}
|
|
17
|
-
|
|
14
|
+
guard let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { return true }
|
|
18
15
|
let updatesFolderURL = documentsURL.appendingPathComponent("updates", isDirectory: true)
|
|
19
16
|
|
|
17
|
+
print("🛠 DEBUG: Full Scan Path -> \(updatesFolderURL.path)")
|
|
18
|
+
|
|
20
19
|
var bestPath: String? = nil
|
|
21
20
|
var maxVer: Double = 0.0
|
|
22
21
|
|
|
@@ -27,38 +26,45 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
|
27
26
|
includingPropertiesForKeys: nil,
|
|
28
27
|
options: [.skipsHiddenFiles]
|
|
29
28
|
)
|
|
29
|
+
print("📦 DEBUG: Version folders found: \(folders.map { $0.lastPathComponent })")
|
|
30
30
|
|
|
31
31
|
for folderURL in folders {
|
|
32
|
-
let
|
|
33
|
-
|
|
34
|
-
.replacingOccurrences(of: "v", with: "")
|
|
32
|
+
let folderName = folderURL.lastPathComponent
|
|
33
|
+
let versionStr = folderName.lowercased().replacingOccurrences(of: "v", with: "")
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
if let vDouble = Double(versionStr), vDouble >= maxVer {
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
let wwwIndexURL = folderURL.appendingPathComponent("www/index.html")
|
|
38
|
+
let rootIndexURL = folderURL.appendingPathComponent("index.html")
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
if fileManager.fileExists(atPath: wwwIndexURL.path) {
|
|
41
|
+
print("✅ DEBUG: FOUND index.html inside WWW for version \(vDouble)")
|
|
42
|
+
maxVer = vDouble
|
|
43
|
+
bestPath = folderURL.appendingPathComponent("www").path
|
|
44
|
+
|
|
45
|
+
} else if fileManager.fileExists(atPath: rootIndexURL.path) {
|
|
46
|
+
print("✅ DEBUG: FOUND index.html at ROOT for version \(vDouble)")
|
|
47
|
+
maxVer = vDouble
|
|
48
|
+
bestPath = folderURL.path
|
|
49
|
+
}
|
|
47
50
|
}
|
|
48
51
|
}
|
|
52
|
+
|
|
49
53
|
} catch {
|
|
50
|
-
print("
|
|
54
|
+
print("❌ DEBUG: Error reading updates: \(error)")
|
|
51
55
|
}
|
|
56
|
+
} else {
|
|
57
|
+
print("ℹ️ DEBUG: 'updates' folder not created yet.")
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
if let target = bestPath {
|
|
55
61
|
defaults.set(target, forKey: "serverBasePath")
|
|
56
62
|
defaults.synchronize()
|
|
57
|
-
print("
|
|
63
|
+
print("🔥 OTA SUCCESS: Version \(maxVer) is now LIVE from \(target)")
|
|
58
64
|
} else {
|
|
65
|
+
print("ℹ️ Standard Boot: No valid OTA found.")
|
|
59
66
|
defaults.removeObject(forKey: "serverBasePath")
|
|
60
67
|
defaults.synchronize()
|
|
61
|
-
print("[OTA] Standard boot — no update found.")
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
return true
|
|
@@ -72,9 +78,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
|
72
78
|
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
|
|
73
79
|
}
|
|
74
80
|
|
|
75
|
-
func applicationWillResignActive(_ application: UIApplication) {
|
|
76
|
-
func applicationDidEnterBackground(_ application: UIApplication) {
|
|
77
|
-
func applicationWillEnterForeground(_ application: UIApplication) {
|
|
78
|
-
func applicationDidBecomeActive(_ application: UIApplication) {
|
|
79
|
-
func applicationWillTerminate(_ application: UIApplication) {
|
|
81
|
+
func applicationWillResignActive(_ application: UIApplication) {}
|
|
82
|
+
func applicationDidEnterBackground(_ application: UIApplication) {}
|
|
83
|
+
func applicationWillEnterForeground(_ application: UIApplication) {}
|
|
84
|
+
func applicationDidBecomeActive(_ application: UIApplication) {}
|
|
85
|
+
func applicationWillTerminate(_ application: UIApplication) {}
|
|
80
86
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
|
9
9
|
</dependencies>
|
|
10
10
|
<scenes>
|
|
11
|
-
<!--
|
|
11
|
+
<!--Bridge View Controller-->
|
|
12
12
|
<scene sceneID="tne-QT-ifu">
|
|
13
13
|
<objects>
|
|
14
14
|
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="App" sceneMemberID="viewController"/>
|
|
@@ -12,13 +12,13 @@ class ViewController: CAPBridgeViewController {
|
|
|
12
12
|
|
|
13
13
|
if FileManager.default.fileExists(atPath: indexPath) {
|
|
14
14
|
self.setServerBasePath(path: otaPath)
|
|
15
|
-
print("
|
|
15
|
+
print("🔥 OTA path applied -> \(otaPath)")
|
|
16
16
|
} else {
|
|
17
17
|
UserDefaults.standard.removeObject(forKey: "serverBasePath")
|
|
18
|
-
print("
|
|
18
|
+
print("⚠️ index.html nahi mila, standard boot.")
|
|
19
19
|
}
|
|
20
20
|
} else {
|
|
21
|
-
print("
|
|
21
|
+
print("ℹ️ Standard boot — no OTA path.")
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "updateflow",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Live OTA updates for Ionic Capacitor apps — iOS & Android. No App Store needed.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -23,8 +23,6 @@
|
|
|
23
23
|
"ios",
|
|
24
24
|
"android",
|
|
25
25
|
"hot-update",
|
|
26
|
-
"app-update",
|
|
27
|
-
"over-the-air",
|
|
28
26
|
"updateflow"
|
|
29
27
|
],
|
|
30
28
|
"author": "CodeCartel <admin@codecartel.co.in> (https://codecartel.co.in)",
|
|
@@ -34,10 +32,6 @@
|
|
|
34
32
|
"type": "git",
|
|
35
33
|
"url": "https://github.com/codecartel-in/updateflow"
|
|
36
34
|
},
|
|
37
|
-
"bugs": {
|
|
38
|
-
"url": "https://github.com/codecartel-in/updateflow/issues",
|
|
39
|
-
"email": "admin@codecartel.co.in"
|
|
40
|
-
},
|
|
41
35
|
"peerDependencies": {
|
|
42
36
|
"@angular/common": ">=12.0.0",
|
|
43
37
|
"@angular/core": ">=12.0.0",
|