@capgo/capacitor-webview-crash 8.0.2 → 8.1.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/Package.swift +2 -2
- package/README.md +107 -30
- package/android/src/main/java/app/capgo/webviewcrash/WebViewCrash.java +231 -1
- package/android/src/main/java/app/capgo/webviewcrash/WebViewCrashPlugin.java +99 -18
- package/dist/docs.json +37 -17
- package/dist/esm/definitions.d.ts +71 -16
- package/dist/esm/definitions.js +1 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +5 -2
- package/dist/esm/web.js +28 -13
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +28 -13
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +28 -13
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/WebViewCrashPlugin/WebViewCrash.swift +256 -2
- package/ios/Sources/WebViewCrashPlugin/WebViewCrashPlugin.swift +101 -11
- package/package.json +5 -3
|
@@ -9,20 +9,31 @@ public class WebViewCrashPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
9
9
|
public let pluginMethods: [CAPPluginMethod] = [
|
|
10
10
|
CAPPluginMethod(name: "getPendingCrashInfo", returnType: CAPPluginReturnPromise),
|
|
11
11
|
CAPPluginMethod(name: "clearPendingCrashInfo", returnType: CAPPluginReturnPromise),
|
|
12
|
-
CAPPluginMethod(name: "simulateCrashRecovery", returnType: CAPPluginReturnPromise)
|
|
12
|
+
CAPPluginMethod(name: "simulateCrashRecovery", returnType: CAPPluginReturnPromise),
|
|
13
|
+
CAPPluginMethod(name: "restartWebView", returnType: CAPPluginReturnPromise)
|
|
13
14
|
]
|
|
14
15
|
|
|
15
|
-
private var
|
|
16
|
+
private var dispatchedPendingEvents = Set<String>()
|
|
17
|
+
private var restartOptions = WebViewCrashRestartOptions()
|
|
18
|
+
private var restartTimer: Timer?
|
|
16
19
|
|
|
17
20
|
override public func load() {
|
|
21
|
+
restartOptions = WebViewCrashRestartOptions(config: getConfig())
|
|
22
|
+
WebViewCrashRuntime.update(options: restartOptions)
|
|
18
23
|
WebViewCrashSwizzler.installIfNeeded()
|
|
24
|
+
schedulePeriodicRestart()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
deinit {
|
|
28
|
+
restartTimer?.invalidate()
|
|
19
29
|
}
|
|
20
30
|
|
|
21
31
|
@objc override public func addListener(_ call: CAPPluginCall) {
|
|
22
32
|
super.addListener(call)
|
|
23
33
|
|
|
24
|
-
if call.getString("eventName")
|
|
25
|
-
|
|
34
|
+
if let eventName = call.getString("eventName"),
|
|
35
|
+
eventName == WebViewCrashBridge.crashEventName || eventName == WebViewCrashBridge.restartEventName {
|
|
36
|
+
dispatchPendingCrashIfNeeded(eventName: eventName)
|
|
26
37
|
}
|
|
27
38
|
}
|
|
28
39
|
|
|
@@ -32,7 +43,7 @@ public class WebViewCrashPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
32
43
|
|
|
33
44
|
@objc func clearPendingCrashInfo(_ call: CAPPluginCall) {
|
|
34
45
|
WebViewCrashStore.clear()
|
|
35
|
-
|
|
46
|
+
dispatchedPendingEvents.removeAll()
|
|
36
47
|
call.resolve()
|
|
37
48
|
}
|
|
38
49
|
|
|
@@ -45,18 +56,97 @@ public class WebViewCrashPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
45
56
|
)
|
|
46
57
|
|
|
47
58
|
WebViewCrashStore.write(crashInfo)
|
|
48
|
-
|
|
49
|
-
dispatchPendingCrashIfNeeded()
|
|
59
|
+
dispatchedPendingEvents.removeAll()
|
|
60
|
+
dispatchPendingCrashIfNeeded(eventName: WebViewCrashBridge.crashEventName)
|
|
61
|
+
dispatchPendingCrashIfNeeded(eventName: WebViewCrashBridge.restartEventName)
|
|
50
62
|
|
|
51
63
|
call.resolve(WebViewCrashBridge.pendingResult(crashInfo))
|
|
52
64
|
}
|
|
53
65
|
|
|
54
|
-
|
|
55
|
-
guard
|
|
66
|
+
@objc func restartWebView(_ call: CAPPluginCall) {
|
|
67
|
+
guard bridge?.viewController is CAPBridgeViewController else {
|
|
68
|
+
call.reject("Unable to restart WebView because the bridge view controller is unavailable.")
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let restartInfo = WebViewCrashStore.buildCrashInfo(
|
|
73
|
+
platform: "ios",
|
|
74
|
+
reason: WebViewCrashBridge.manualRestartReason,
|
|
75
|
+
url: bridge?.webView?.url?.absoluteString,
|
|
76
|
+
appState: UIApplication.shared.applicationState.capgoWebViewCrashValue
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
WebViewCrashStore.write(restartInfo)
|
|
80
|
+
dispatchedPendingEvents.removeAll()
|
|
81
|
+
call.resolve(WebViewCrashBridge.pendingResult(restartInfo))
|
|
82
|
+
|
|
83
|
+
DispatchQueue.main.async { [weak self] in
|
|
84
|
+
_ = self?.recreateBridgeWebView()
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private func dispatchPendingCrashIfNeeded(eventName: String) {
|
|
89
|
+
guard !dispatchedPendingEvents.contains(eventName),
|
|
90
|
+
let crashInfo = WebViewCrashStore.read(),
|
|
91
|
+
WebViewCrashStore.shouldDispatch(eventName: eventName, crashInfo: crashInfo) else {
|
|
56
92
|
return
|
|
57
93
|
}
|
|
58
94
|
|
|
59
|
-
|
|
60
|
-
notifyListeners(
|
|
95
|
+
dispatchedPendingEvents.insert(eventName)
|
|
96
|
+
notifyListeners(eventName, data: crashInfo)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private func schedulePeriodicRestart() {
|
|
100
|
+
restartTimer?.invalidate()
|
|
101
|
+
|
|
102
|
+
guard let restartDelaySeconds = restartOptions.nextRestartDelaySeconds, restartDelaySeconds > 0 else {
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
DispatchQueue.main.async { [weak self] in
|
|
107
|
+
guard let self else {
|
|
108
|
+
return
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
restartTimer = Timer.scheduledTimer(withTimeInterval: restartDelaySeconds, repeats: false) { [weak self] _ in
|
|
112
|
+
self?.restartWebView(reason: WebViewCrashBridge.periodicRestartReason)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private func restartWebView(reason: String) {
|
|
118
|
+
DispatchQueue.main.async { [weak self] in
|
|
119
|
+
guard let self, let webView = bridge?.webView else {
|
|
120
|
+
return
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let restartInfo = WebViewCrashStore.buildCrashInfo(
|
|
124
|
+
platform: "ios",
|
|
125
|
+
reason: reason,
|
|
126
|
+
url: webView.url?.absoluteString,
|
|
127
|
+
appState: UIApplication.shared.applicationState.capgoWebViewCrashValue
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
WebViewCrashStore.write(restartInfo)
|
|
131
|
+
dispatchedPendingEvents.removeAll()
|
|
132
|
+
if !recreateBridgeWebView() {
|
|
133
|
+
webView.reload()
|
|
134
|
+
schedulePeriodicRestart()
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private func recreateBridgeWebView() -> Bool {
|
|
140
|
+
guard let viewController = bridge?.viewController as? CAPBridgeViewController else {
|
|
141
|
+
return false
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
restartTimer?.invalidate()
|
|
145
|
+
viewController.webView?.stopLoading()
|
|
146
|
+
viewController.webView?.navigationDelegate = nil
|
|
147
|
+
viewController.webView?.uiDelegate = nil
|
|
148
|
+
viewController.loadView()
|
|
149
|
+
viewController.loadWebView()
|
|
150
|
+
return true
|
|
61
151
|
}
|
|
62
152
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capgo/capacitor-webview-crash",
|
|
3
|
-
"version": "8.0
|
|
4
|
-
"description": "Capacitor plugin for detecting WebView crash recovery and
|
|
3
|
+
"version": "8.1.0",
|
|
4
|
+
"description": "Capacitor plugin for detecting WebView crash recovery and restarting long-running WebViews natively.",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
7
7
|
"types": "dist/esm/index.d.ts",
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
"capacitor",
|
|
30
30
|
"plugin",
|
|
31
31
|
"webview-crash",
|
|
32
|
+
"webview-restart",
|
|
33
|
+
"oom-recovery",
|
|
32
34
|
"crash-recovery",
|
|
33
35
|
"ios",
|
|
34
36
|
"android",
|
|
@@ -36,7 +38,7 @@
|
|
|
36
38
|
],
|
|
37
39
|
"scripts": {
|
|
38
40
|
"verify": "bun run verify:ios && bun run verify:android && bun run verify:web",
|
|
39
|
-
"verify:ios": "xcodebuild -scheme
|
|
41
|
+
"verify:ios": "xcodebuild -scheme CapgoCapacitorWebviewCrash -destination generic/platform=iOS",
|
|
40
42
|
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
41
43
|
"verify:web": "bun run build && bun test",
|
|
42
44
|
"test": "bun test",
|