@capacitor/ios 9.0.0-alpha.6 → 9.0.0-alpha.7
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/Capacitor.podspec +10 -4
- package/CapacitorCordova.podspec +6 -5
- package/{Capacitor → Sources}/Capacitor/CAPApplicationDelegateProxy.swift +1 -1
- package/{Capacitor → Sources}/Capacitor/CAPBridgeProtocol.swift +0 -57
- package/{Capacitor → Sources}/Capacitor/CAPInstanceConfiguration.swift +0 -15
- package/{Capacitor → Sources}/Capacitor/CAPNotifications.swift +8 -36
- package/Sources/Capacitor/CAPPlugin+Bridge.swift +108 -0
- package/{Capacitor → Sources}/Capacitor/CAPPluginCall.swift +0 -13
- package/Sources/Capacitor/CAPSceneDelegateProxy.swift +204 -0
- package/{Capacitor → Sources}/Capacitor/CapacitorBridge.swift +37 -78
- package/Sources/Capacitor/CapacitorObjCExports.swift +11 -0
- package/{Capacitor → Sources}/Capacitor/JS.swift +9 -20
- package/{Capacitor → Sources}/Capacitor/JSExport.swift +6 -2
- package/Sources/Capacitor/JSResultSerialization.swift +56 -0
- package/{Capacitor → Sources}/Capacitor/NotificationRouter.swift +9 -0
- package/Sources/Capacitor/PluginCallResult.swift +17 -0
- package/{Capacitor → Sources}/Capacitor/Plugins/CapacitorUrlRequest.swift +2 -11
- package/{Capacitor → Sources}/Capacitor/WebViewAssetHandler.swift +17 -5
- package/{Capacitor → Sources}/Capacitor/WebViewDelegationHandler.swift +7 -1
- package/{Capacitor → Sources}/Capacitor/assets/native-bridge.js +0 -6
- package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/CapacitorCordova}/Plugin.swift +5 -0
- package/{Capacitor/Capacitor → Sources/CapacitorObjC}/CAPInstanceConfiguration.m +9 -1
- package/{Capacitor/Capacitor → Sources/CapacitorObjC}/CAPInstanceDescriptor.m +0 -1
- package/Sources/CapacitorObjC/CAPPlugin.m +100 -0
- package/Sources/CapacitorObjC/CAPPluginCallResult.m +29 -0
- package/{Capacitor/Capacitor → Sources/CapacitorObjC}/CAPPluginMethod.m +0 -1
- package/{Capacitor → Sources/CapacitorObjC/include}/Capacitor/CAPPlugin.h +3 -20
- package/{Capacitor → Sources/CapacitorObjC/include}/Capacitor/CAPPluginCall.h +1 -2
- package/Sources/CapacitorObjC/include/Capacitor/CAPPluginCallResult.h +28 -0
- package/Sources/CapacitorObjCShims/include/Capacitor/Capacitor-Swift.h +9 -0
- package/{Capacitor → Sources/CapacitorObjCShims/include}/Capacitor/Capacitor.h +8 -0
- package/package.json +6 -7
- package/Capacitor/Capacitor/CAPBridge.swift +0 -25
- package/Capacitor/Capacitor/CAPFile.swift +0 -14
- package/Capacitor/Capacitor/CAPPlugin.m +0 -180
- package/Capacitor/Capacitor/Info.plist +0 -24
- package/Capacitor/Capacitor/PluginCallResult.swift +0 -106
- package/CapacitorCordova/CapacitorCordova/Info.plist +0 -26
- /package/{Capacitor → Sources}/Capacitor/AppUUID.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/Array+Capacitor.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/CAPBridgeDelegate.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/CAPBridgeViewController.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/CAPBridgedPlugin+getMethod.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/CAPInstanceDescriptor.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/CAPInstancePlugin.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/CAPLog.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/CAPPlugin+LoadInstance.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/CAPPluginMethod.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/CapacitorExtension.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/Codable/JSValueDecoder.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/Codable/JSValueEncoder.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/Data+Capacitor.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/DocLinks.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/JSTypes.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/KeyPath.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/KeyValueStore.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/NotificationHandlerProtocol.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/PluginConfig.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/Plugins/CapacitorCookieManager.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/Plugins/CapacitorCookies.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/Plugins/CapacitorHttp.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/Plugins/Console.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/Plugins/HttpRequestHandler.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/Plugins/SystemBars.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/Plugins/WebView.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/PrivacyInfo.xcprivacy +0 -0
- /package/{Capacitor → Sources}/Capacitor/Router.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/UIColor.swift +0 -0
- /package/{Capacitor → Sources}/Capacitor/WKWebView+Capacitor.swift +0 -0
- /package/{Capacitor/Capacitor → Sources/CapacitorObjC}/CAPPluginCall.m +0 -0
- /package/{Capacitor → Sources/CapacitorObjC/include}/Capacitor/CAPBridgedPlugin.h +0 -0
- /package/{Capacitor → Sources/CapacitorObjC/include}/Capacitor/CAPInstanceConfiguration.h +0 -0
- /package/{Capacitor → Sources/CapacitorObjC/include}/Capacitor/CAPInstanceDescriptor.h +0 -0
- /package/{Capacitor → Sources/CapacitorObjC/include}/Capacitor/CAPPluginMethod.h +0 -0
- /package/{Capacitor/Capacitor → Sources/CapacitorObjCShims}/CAPBridgedJSTypes.m +0 -0
- /package/{Capacitor/Capacitor → Sources/CapacitorObjCShims}/Capacitor.modulemap +0 -0
- /package/{Capacitor/Capacitor → Sources/CapacitorObjCShims}/UIStatusBarManager+CAPHandleTapAction.m +0 -0
- /package/{Capacitor/Capacitor → Sources/CapacitorObjCShims}/WKWebView+Capacitor.m +0 -0
- /package/{Capacitor → Sources/CapacitorObjCShims/include}/Capacitor/CAPBridgedJSTypes.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova}/AppDelegate.m +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova}/CDVCommandDelegateImpl.m +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova}/CDVConfigParser.m +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova}/CDVInvokedUrlCommand.m +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova}/CDVPlugin+Resources.m +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova}/CDVPlugin.m +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova}/CDVPluginManager.m +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova}/CDVPluginResult.m +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova}/CDVURLProtocol.m +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova}/CDVViewController.m +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova}/CDVWebViewProcessPoolFactory.m +0 -0
- /package/{CapacitorCordova/CapacitorCordova → Sources/Cordova}/CapacitorCordova.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova → Sources/Cordova}/CapacitorCordova.modulemap +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova}/NSDictionary+CordovaPreferences.m +0 -0
- /package/{CapacitorCordova/CapacitorCordova → Sources/Cordova}/PrivacyInfo.xcprivacy +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/AppDelegate.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDV.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVAvailability.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVAvailabilityDeprecated.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVCommandDelegate.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVCommandDelegateImpl.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVConfigParser.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVInvokedUrlCommand.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVPlugin+Resources.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVPlugin.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVPluginManager.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVPluginResult.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVScreenOrientationDelegate.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVURLProtocol.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVViewController.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/CDVWebViewProcessPoolFactory.h +0 -0
- /package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/Cordova/include/Cordova}/NSDictionary+CordovaPreferences.h +0 -0
|
@@ -95,8 +95,6 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
95
95
|
public static let capacitorSite = "https://capacitorjs.com/"
|
|
96
96
|
public static let fileStartIdentifier = "/_capacitor_file_"
|
|
97
97
|
public static let httpInterceptorStartIdentifier = "/_capacitor_http_interceptor_"
|
|
98
|
-
@available(*, deprecated, message: "`httpsInterceptorStartIdentifier` is no longer required. All proxied requests are handled via `httpInterceptorStartIdentifier` instead")
|
|
99
|
-
public static let httpsInterceptorStartIdentifier = "/_capacitor_https_interceptor_"
|
|
100
98
|
public static let httpInterceptorUrlParam = "u"
|
|
101
99
|
public static let defaultScheme = "capacitor"
|
|
102
100
|
|
|
@@ -125,47 +123,6 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
125
123
|
// Array of block based observers
|
|
126
124
|
var observers: [NSObjectProtocol] = []
|
|
127
125
|
|
|
128
|
-
// MARK: - CAPBridgeProtocol: Deprecated
|
|
129
|
-
|
|
130
|
-
public func getWebView() -> WKWebView? {
|
|
131
|
-
return webView
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
public func isSimulator() -> Bool {
|
|
135
|
-
return isSimEnvironment
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
public func isDevMode() -> Bool {
|
|
139
|
-
return isDevEnvironment
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
public func getStatusBarVisible() -> Bool {
|
|
143
|
-
return statusBarVisible
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
@nonobjc public func setStatusBarVisible(_ visible: Bool) {
|
|
147
|
-
statusBarVisible = visible
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
public func getStatusBarStyle() -> UIStatusBarStyle {
|
|
151
|
-
return statusBarStyle
|
|
152
|
-
}
|
|
153
|
-
@nonobjc public func setStatusBarStyle(_ style: UIStatusBarStyle) {
|
|
154
|
-
statusBarStyle = style
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
public func getUserInterfaceStyle() -> UIUserInterfaceStyle {
|
|
158
|
-
return userInterfaceStyle
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
public func getLocalUrl() -> String {
|
|
162
|
-
return config.localURL.absoluteString
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
@nonobjc public func setStatusBarAnimation(_ animation: UIStatusBarAnimation) {
|
|
166
|
-
statusBarAnimation = animation
|
|
167
|
-
}
|
|
168
|
-
|
|
169
126
|
public func setServerBasePath(_ path: String) {
|
|
170
127
|
let url = URL(fileURLWithPath: path, isDirectory: true)
|
|
171
128
|
guard FileManager.default.fileExists(atPath: url.path) else { return }
|
|
@@ -198,11 +155,6 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
198
155
|
|
|
199
156
|
// MARK: - Initialization
|
|
200
157
|
|
|
201
|
-
@available(*, deprecated, renamed: "init", message: "Use different init")
|
|
202
|
-
public convenience init(with configuration: InstanceConfiguration, delegate bridgeDelegate: CAPBridgeDelegate, cordovaConfiguration: Any, assetHandler: WebViewAssetHandler, delegationHandler: WebViewDelegationHandler, autoRegisterPlugins: Bool = true) {
|
|
203
|
-
self.init(with: configuration, delegate: bridgeDelegate, assetHandler: assetHandler, delegationHandler: delegationHandler, autoRegisterPlugins: autoRegisterPlugins)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
158
|
public init(with configuration: InstanceConfiguration, delegate bridgeDelegate: CAPBridgeDelegate, assetHandler: WebViewAssetHandler, delegationHandler: WebViewDelegationHandler, autoRegisterPlugins: Bool = true) {
|
|
207
159
|
|
|
208
160
|
self.bridgeDelegate = bridgeDelegate
|
|
@@ -215,6 +167,7 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
215
167
|
super.init()
|
|
216
168
|
|
|
217
169
|
self.webViewDelegationHandler.bridge = self
|
|
170
|
+
self.webViewAssetHandler.setConfiguration(configuration)
|
|
218
171
|
|
|
219
172
|
exportCoreJS(localUrl: configuration.localURL.absoluteString)
|
|
220
173
|
registerPlugins()
|
|
@@ -261,26 +214,50 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
261
214
|
if !cordovaIsPresent {
|
|
262
215
|
observers.append(
|
|
263
216
|
NotificationCenter.default.addObserver(
|
|
264
|
-
forName:
|
|
217
|
+
forName: UIScene.willEnterForegroundNotification,
|
|
265
218
|
object: nil,
|
|
266
219
|
queue: .main
|
|
267
|
-
) { [weak self]
|
|
268
|
-
self?.
|
|
220
|
+
) { [weak self] notification in
|
|
221
|
+
self?.triggerSceneLifecycleJSEvent("resume", for: notification)
|
|
269
222
|
}
|
|
270
223
|
)
|
|
271
224
|
|
|
272
225
|
observers.append(
|
|
273
226
|
NotificationCenter.default.addObserver(
|
|
274
|
-
forName:
|
|
227
|
+
forName: UIScene.didEnterBackgroundNotification,
|
|
275
228
|
object: nil,
|
|
276
229
|
queue: .main
|
|
277
|
-
) { [weak self]
|
|
278
|
-
self?.
|
|
230
|
+
) { [weak self] notification in
|
|
231
|
+
self?.triggerSceneLifecycleJSEvent("pause", for: notification)
|
|
279
232
|
}
|
|
280
233
|
)
|
|
281
234
|
}
|
|
282
235
|
}
|
|
283
236
|
|
|
237
|
+
/**
|
|
238
|
+
Forward a scene lifecycle transition to the page as a document event, but only once
|
|
239
|
+
the page exists to receive it.
|
|
240
|
+
|
|
241
|
+
On a cold start `UIScene.willEnterForegroundNotification` is posted while the initial
|
|
242
|
+
load is still in flight, before `window.Capacitor` has been defined. Evaluating
|
|
243
|
+
`triggerEvent` at that point throws inside the web view and surfaces as a
|
|
244
|
+
"JS Eval error" in the log. The same happens when the web content process was
|
|
245
|
+
terminated and the page is being reloaded. In both cases the page is about to load
|
|
246
|
+
from scratch, so there is nothing for it to resume or pause; the event is dropped
|
|
247
|
+
rather than deferred, because a "resume" delivered right after a fresh load would
|
|
248
|
+
make the page react to a transition it never went through.
|
|
249
|
+
*/
|
|
250
|
+
private func triggerSceneLifecycleJSEvent(_ eventName: String, for notification: Notification) {
|
|
251
|
+
guard let scene = notification.object as? UIWindowScene,
|
|
252
|
+
scene === viewController?.view.window?.windowScene else {
|
|
253
|
+
return
|
|
254
|
+
}
|
|
255
|
+
guard case .subsequentLoad = webViewDelegationHandler.webViewLoadingState, webView?.isLoading == false else {
|
|
256
|
+
return
|
|
257
|
+
}
|
|
258
|
+
triggerDocumentJSEvent(eventName: eventName)
|
|
259
|
+
}
|
|
260
|
+
|
|
284
261
|
/**
|
|
285
262
|
Reset the state of the bridge between navigations to avoid
|
|
286
263
|
sending data back to the page from a previous page.
|
|
@@ -403,16 +380,6 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
403
380
|
_ = storedCalls.withLock { $0.removeValue(forKey: withID) }
|
|
404
381
|
}
|
|
405
382
|
|
|
406
|
-
// MARK: - Deprecated Versions
|
|
407
|
-
|
|
408
|
-
@objc public func getSavedCall(_ callbackId: String) -> CAPPluginCall? {
|
|
409
|
-
return savedCall(withID: callbackId)
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
@objc public func releaseCall(callbackId: String) {
|
|
413
|
-
releaseCall(withID: callbackId)
|
|
414
|
-
}
|
|
415
|
-
|
|
416
383
|
// MARK: - Internal
|
|
417
384
|
|
|
418
385
|
func getDispatchQueue() -> DispatchQueue {
|
|
@@ -420,7 +387,7 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
420
387
|
}
|
|
421
388
|
|
|
422
389
|
func reload() {
|
|
423
|
-
self.
|
|
390
|
+
self.webView?.reload()
|
|
424
391
|
}
|
|
425
392
|
|
|
426
393
|
func docLink(_ url: String) -> String {
|
|
@@ -491,7 +458,7 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
491
458
|
if let result = result {
|
|
492
459
|
self?.toJs(result: JSResult(call: call, callResult: result), save: pluginCall?.keepAlive ?? false)
|
|
493
460
|
} else {
|
|
494
|
-
self?.toJs(result: JSResult(call: call,
|
|
461
|
+
self?.toJs(result: JSResult(call: call, data: [:]), save: pluginCall?.keepAlive ?? false)
|
|
495
462
|
}
|
|
496
463
|
}, error: {(error: CAPPluginCallError?) in
|
|
497
464
|
if let error = error {
|
|
@@ -501,7 +468,7 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
501
468
|
errorMessage: "",
|
|
502
469
|
errorDescription: "",
|
|
503
470
|
errorCode: nil,
|
|
504
|
-
|
|
471
|
+
data: [:]))
|
|
505
472
|
}
|
|
506
473
|
})
|
|
507
474
|
|
|
@@ -589,7 +556,7 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
589
556
|
"""
|
|
590
557
|
|
|
591
558
|
DispatchQueue.main.async {
|
|
592
|
-
self.
|
|
559
|
+
self.webView?.evaluateJavaScript(wrappedJs, completionHandler: { (_, error) in
|
|
593
560
|
if let error = error {
|
|
594
561
|
CAPLog.print("⚡️ JS Eval error", error.localizedDescription)
|
|
595
562
|
}
|
|
@@ -605,7 +572,7 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
605
572
|
// swiftlint:disable:next identifier_name
|
|
606
573
|
@objc public func eval(js: String) {
|
|
607
574
|
DispatchQueue.main.async {
|
|
608
|
-
self.
|
|
575
|
+
self.webView?.evaluateJavaScript(js, completionHandler: { (_, error) in
|
|
609
576
|
if let error = error {
|
|
610
577
|
CAPLog.print("⚡️ JS Eval error", error.localizedDescription)
|
|
611
578
|
}
|
|
@@ -639,7 +606,7 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
639
606
|
|
|
640
607
|
public func logToJs(_ message: String, _ level: String = "log") {
|
|
641
608
|
DispatchQueue.main.async {
|
|
642
|
-
self.
|
|
609
|
+
self.webView?.evaluateJavaScript("window.Capacitor.logJs('\(message)', '\(level)')") { (result, error) in
|
|
643
610
|
if error != nil, let result = result {
|
|
644
611
|
CAPLog.print(result)
|
|
645
612
|
}
|
|
@@ -695,12 +662,4 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
695
662
|
alert.addAction(UIAlertAction(title: buttonTitle, style: UIAlertAction.Style.default, handler: nil))
|
|
696
663
|
self.viewController?.present(alert, animated: true, completion: nil)
|
|
697
664
|
}
|
|
698
|
-
|
|
699
|
-
@objc open func presentVC(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
|
|
700
|
-
self.viewController?.present(viewControllerToPresent, animated: flag, completion: completion)
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
@objc open func dismissVC(animated flag: Bool, completion: (() -> Void)? = nil) {
|
|
704
|
-
self.viewController?.dismiss(animated: flag, completion: completion)
|
|
705
|
-
}
|
|
706
665
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// The Objective-C base classes (CAPPlugin, CAPPluginCall, CAPPluginMethod, CAPBridgedPlugin,
|
|
2
|
+
// CAPInstanceDescriptor, CAPInstanceConfiguration) live in the CapacitorObjC target so that they
|
|
3
|
+
// compile before the Swift module that subclasses and extends them. Re-export them so the rest of
|
|
4
|
+
// this module — and downstream `import Capacitor` consumers — keep seeing these symbols without an
|
|
5
|
+
// explicit `import CapacitorObjC`.
|
|
6
|
+
//
|
|
7
|
+
// Under CocoaPods all of these sources are compiled into a single Capacitor module, so there is no
|
|
8
|
+
// CapacitorObjC module to import and the re-export is unnecessary.
|
|
9
|
+
#if SWIFT_PACKAGE
|
|
10
|
+
@_exported import CapacitorObjC
|
|
11
|
+
#endif
|
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
|
|
3
|
-
public class JSDate {
|
|
4
|
-
@available(*, deprecated, message: "No longer needed. Dates will be mapped to strings during serialization.")
|
|
5
|
-
static func toString(_ date: Date) -> String {
|
|
6
|
-
let formatter = ISO8601DateFormatter()
|
|
7
|
-
return formatter.string(from: date)
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
@available(*, deprecated, renamed: "PluginCallResultData")
|
|
12
|
-
public typealias JSResultBody = [String: Any]
|
|
13
|
-
|
|
14
3
|
/**
|
|
15
4
|
* A call originating from JavaScript land
|
|
16
5
|
*/
|
|
@@ -55,17 +44,17 @@ private enum SerializationResult: String {
|
|
|
55
44
|
|
|
56
45
|
internal struct JSResult: JSResultProtocol {
|
|
57
46
|
let call: JSCall
|
|
58
|
-
let
|
|
47
|
+
let data: PluginCallResultData?
|
|
59
48
|
|
|
60
49
|
func jsonPayload() -> String {
|
|
61
|
-
guard let
|
|
50
|
+
guard let data = data else {
|
|
62
51
|
return SerializationResult.undefined.rawValue
|
|
63
52
|
}
|
|
64
53
|
do {
|
|
65
|
-
if let payload = try
|
|
54
|
+
if let payload = try JSResultSerialization.jsonRepresentation(of: data) {
|
|
66
55
|
return payload
|
|
67
56
|
}
|
|
68
|
-
} catch
|
|
57
|
+
} catch JSResultSerialization.SerializationError.invalidObject {
|
|
69
58
|
CAPLog.print("[Capacitor Plugin Error] - \(call.pluginId) - \(call.method) - Unable to serialize plugin response as JSON." +
|
|
70
59
|
"Ensure that all data passed to success callback from module method is JSON serializable!")
|
|
71
60
|
} catch {
|
|
@@ -78,7 +67,7 @@ internal struct JSResult: JSResultProtocol {
|
|
|
78
67
|
internal extension JSResult {
|
|
79
68
|
init(call: JSCall, callResult: CAPPluginCallResult) {
|
|
80
69
|
self.call = call
|
|
81
|
-
self.
|
|
70
|
+
self.data = callResult.data
|
|
82
71
|
}
|
|
83
72
|
}
|
|
84
73
|
|
|
@@ -87,7 +76,7 @@ internal struct JSResultError: JSResultProtocol {
|
|
|
87
76
|
let errorMessage: String
|
|
88
77
|
let errorDescription: String
|
|
89
78
|
let errorCode: String?
|
|
90
|
-
let
|
|
79
|
+
let data: PluginCallResultData
|
|
91
80
|
|
|
92
81
|
func jsonPayload() -> String {
|
|
93
82
|
var errorDictionary: [String: Any] = [
|
|
@@ -97,11 +86,11 @@ internal struct JSResultError: JSResultProtocol {
|
|
|
97
86
|
errorDictionary["code"] = self.errorCode
|
|
98
87
|
|
|
99
88
|
do {
|
|
100
|
-
if let payload = try
|
|
89
|
+
if let payload = try JSResultSerialization.jsonRepresentation(of: data, includingFields: errorDictionary) {
|
|
101
90
|
CAPLog.print("ERROR MESSAGE: ", payload.prefix(512))
|
|
102
91
|
return payload
|
|
103
92
|
}
|
|
104
|
-
} catch
|
|
93
|
+
} catch JSResultSerialization.SerializationError.invalidObject {
|
|
105
94
|
CAPLog.print("[Capacitor Plugin Error] - \(call.pluginId) - \(call.method) - Unable to serialize plugin response as JSON." +
|
|
106
95
|
"Ensure that all data passed to success callback from module method is JSON serializable!")
|
|
107
96
|
} catch {
|
|
@@ -117,6 +106,6 @@ internal extension JSResultError {
|
|
|
117
106
|
errorMessage = callError.message
|
|
118
107
|
errorDescription = callError.error?.localizedDescription ?? ""
|
|
119
108
|
errorCode = callError.code
|
|
120
|
-
|
|
109
|
+
data = callError.data ?? [:]
|
|
121
110
|
}
|
|
122
111
|
}
|
|
@@ -22,8 +22,12 @@ internal class JSExport {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
static func exportBridgeJS(userContentController: WKUserContentController) throws {
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
#if SWIFT_PACKAGE
|
|
26
|
+
let jsUrl = Bundle.module.url(forResource: "native-bridge", withExtension: "js", subdirectory: "assets")
|
|
27
|
+
#else
|
|
28
|
+
let jsUrl = Bundle(for: Self.self).url(forResource: "native-bridge", withExtension: "js")
|
|
29
|
+
#endif
|
|
30
|
+
guard let jsUrl else {
|
|
27
31
|
CAPLog.print("ERROR: Required native-bridge.js file in Capacitor not found. Bridge will not function!")
|
|
28
32
|
throw CapacitorBridgeError.errorExportingCoreJS
|
|
29
33
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public typealias PluginCallResultData = [String: Any]
|
|
4
|
+
|
|
5
|
+
/// Serializes a plugin call's result dictionary to the JSON string sent back across the bridge,
|
|
6
|
+
/// converting `Date` values to ISO8601 strings (recursively through nested dictionaries/arrays).
|
|
7
|
+
///
|
|
8
|
+
/// Carries the serialization logic that used to live on the `PluginCallResult` enum, which was
|
|
9
|
+
/// replaced by the Objective-C `CAPPluginCallResult`/`CAPPluginCallError` carriers. Those store
|
|
10
|
+
/// their payloads as plain dictionaries, so the logic no longer has an enum to hang off.
|
|
11
|
+
enum JSResultSerialization {
|
|
12
|
+
enum SerializationError: Error {
|
|
13
|
+
case invalidObject
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
private static let formatter = ISO8601DateFormatter()
|
|
17
|
+
|
|
18
|
+
static func jsonRepresentation(of dictionary: PluginCallResultData, includingFields: PluginCallResultData? = nil) throws -> String? {
|
|
19
|
+
var dictionary = dictionary
|
|
20
|
+
if let fields = includingFields {
|
|
21
|
+
dictionary.merge(fields) { (current, _) in current }
|
|
22
|
+
}
|
|
23
|
+
let prepared = prepare(dictionary: dictionary)
|
|
24
|
+
guard JSONSerialization.isValidJSONObject(prepared) else {
|
|
25
|
+
throw SerializationError.invalidObject
|
|
26
|
+
}
|
|
27
|
+
let data = try JSONSerialization.data(withJSONObject: prepared, options: [])
|
|
28
|
+
return String(data: data, encoding: .utf8)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private static func prepare(dictionary: PluginCallResultData) -> PluginCallResultData {
|
|
32
|
+
return dictionary.mapValues { (value) -> Any in
|
|
33
|
+
if let date = value as? Date {
|
|
34
|
+
return formatter.string(from: date)
|
|
35
|
+
} else if let aDictionary = value as? PluginCallResultData {
|
|
36
|
+
return prepare(dictionary: aDictionary)
|
|
37
|
+
} else if let anArray = value as? [Any] {
|
|
38
|
+
return prepare(array: anArray)
|
|
39
|
+
}
|
|
40
|
+
return value
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private static func prepare(array: [Any]) -> [Any] {
|
|
45
|
+
return array.map { (value) -> Any in
|
|
46
|
+
if let date = value as? Date {
|
|
47
|
+
return formatter.string(from: date)
|
|
48
|
+
} else if let aDictionary = value as? PluginCallResultData {
|
|
49
|
+
return prepare(dictionary: aDictionary)
|
|
50
|
+
} else if let anArray = value as? [Any] {
|
|
51
|
+
return prepare(array: anArray)
|
|
52
|
+
}
|
|
53
|
+
return value
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
|
|
3
3
|
@objc(CAPNotificationRouter) public class NotificationRouter: NSObject, UNUserNotificationCenterDelegate {
|
|
4
|
+
// UNUserNotificationCenter.current() raises when the process has no application bundle, which
|
|
5
|
+
// is the case in a host-less unit test runner and some extension contexts. There is no
|
|
6
|
+
// notification center to register with there, so treat it as unavailable rather than trapping.
|
|
7
|
+
private static var isNotificationCenterAvailable: Bool {
|
|
8
|
+
return ["app", "appex"].contains(Bundle.main.bundleURL.pathExtension)
|
|
9
|
+
}
|
|
10
|
+
|
|
4
11
|
var handleApplicationNotifications: Bool {
|
|
5
12
|
get {
|
|
13
|
+
guard Self.isNotificationCenterAvailable else { return false }
|
|
6
14
|
return UNUserNotificationCenter.current().delegate === self
|
|
7
15
|
}
|
|
8
16
|
set {
|
|
17
|
+
guard Self.isNotificationCenterAvailable else { return }
|
|
9
18
|
let center = UNUserNotificationCenter.current()
|
|
10
19
|
|
|
11
20
|
if newValue {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public enum PluginCallResult {
|
|
4
|
+
case dictionary(PluginCallResultData)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
public extension CAPPluginCallResult {
|
|
8
|
+
var resultData: PluginCallResult? {
|
|
9
|
+
return data.map { .dictionary($0) }
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public extension CAPPluginCallError {
|
|
14
|
+
var resultData: PluginCallResult? {
|
|
15
|
+
return data.map { .dictionary($0) }
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -12,8 +12,8 @@ open class CapacitorUrlRequest: NSObject, URLSessionTaskDelegate {
|
|
|
12
12
|
request = URLRequest(url: url)
|
|
13
13
|
request.httpMethod = method
|
|
14
14
|
headers = [:]
|
|
15
|
-
if let lang = Locale.autoupdatingCurrent.languageCode {
|
|
16
|
-
if let country = Locale.autoupdatingCurrent.
|
|
15
|
+
if let lang = Locale.autoupdatingCurrent.language.languageCode?.identifier {
|
|
16
|
+
if let country = Locale.autoupdatingCurrent.region?.identifier {
|
|
17
17
|
headers["Accept-Language"] = "\(lang)-\(country),\(lang);q=0.5"
|
|
18
18
|
} else {
|
|
19
19
|
headers["Accept-Language"] = "\(lang);q=0.5"
|
|
@@ -195,15 +195,6 @@ open class CapacitorUrlRequest: NSObject, URLSessionTaskDelegate {
|
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
@available(*, deprecated, message: "Use newer function with passed headers of type [String: Any]")
|
|
199
|
-
public func setRequestHeaders(_ headers: [String: String]) {
|
|
200
|
-
headers.keys.forEach { (key: String) in
|
|
201
|
-
let value = headers[key]
|
|
202
|
-
request.addValue(value!, forHTTPHeaderField: key)
|
|
203
|
-
self.headers[key] = value
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
198
|
public func setRequestHeaders(_ headers: [String: Any]) {
|
|
208
199
|
headers.keys.forEach { (key: String) in
|
|
209
200
|
let value = headers[key]
|
|
@@ -6,6 +6,7 @@ import UniformTypeIdentifiers
|
|
|
6
6
|
open class WebViewAssetHandler: NSObject, WKURLSchemeHandler {
|
|
7
7
|
private var router: Router
|
|
8
8
|
private var serverUrl: URL?
|
|
9
|
+
private var configuration: InstanceConfiguration?
|
|
9
10
|
|
|
10
11
|
public init(router: Router) {
|
|
11
12
|
self.router = router
|
|
@@ -20,6 +21,10 @@ open class WebViewAssetHandler: NSObject, WKURLSchemeHandler {
|
|
|
20
21
|
self.serverUrl = serverUrl
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
open func setConfiguration(_ configuration: InstanceConfiguration?) {
|
|
25
|
+
self.configuration = configuration
|
|
26
|
+
}
|
|
27
|
+
|
|
23
28
|
private func isUsingLiveReload(_ localUrl: URL) -> Bool {
|
|
24
29
|
return self.serverUrl != nil && self.serverUrl?.scheme != localUrl.scheme
|
|
25
30
|
}
|
|
@@ -31,7 +36,13 @@ open class WebViewAssetHandler: NSObject, WKURLSchemeHandler {
|
|
|
31
36
|
let localUrl = URL.init(string: url.absoluteString)!
|
|
32
37
|
|
|
33
38
|
if url.path.starts(with: CapacitorBridge.httpInterceptorStartIdentifier) {
|
|
34
|
-
|
|
39
|
+
// Only serve the proxy when CapacitorHttp is on. A scheme task can't tell a document from
|
|
40
|
+
// a subresource, so keeping documents out relies on the check in decidePolicyFor.
|
|
41
|
+
if configuration?.getPluginConfig("CapacitorHttp").getBoolean("enabled", false) == true {
|
|
42
|
+
handleCapacitorHttpRequest(urlSchemeTask, localUrl, false)
|
|
43
|
+
} else {
|
|
44
|
+
urlSchemeTask.didFailWithError(URLError(.unsupportedURL))
|
|
45
|
+
}
|
|
35
46
|
return
|
|
36
47
|
}
|
|
37
48
|
|
|
@@ -152,12 +163,13 @@ open class WebViewAssetHandler: NSObject, WKURLSchemeHandler {
|
|
|
152
163
|
let existingHeaders = response.allHeaderFields
|
|
153
164
|
var newHeaders: [AnyHashable: Any] = [:]
|
|
154
165
|
|
|
166
|
+
// Nothing should render this. If anything does, sandbox keeps it inert.
|
|
167
|
+
newHeaders["Content-Security-Policy"] = "sandbox; frame-ancestors 'none'"
|
|
168
|
+
|
|
155
169
|
// if using live reload, then set CORS headers
|
|
156
170
|
if self.isUsingLiveReload(url) {
|
|
157
|
-
newHeaders =
|
|
158
|
-
|
|
159
|
-
"Access-Control-Allow-Methods": "GET, HEAD, OPTIONS, TRACE"
|
|
160
|
-
]
|
|
171
|
+
newHeaders["Access-Control-Allow-Origin"] = self.serverUrl?.absoluteString ?? ""
|
|
172
|
+
newHeaders["Access-Control-Allow-Methods"] = "GET, HEAD, OPTIONS, TRACE"
|
|
161
173
|
}
|
|
162
174
|
|
|
163
175
|
if let mergedHeaders = existingHeaders.merging(newHeaders, uniquingKeysWith: { (_, newHeaders) in newHeaders }) as? [String: String] {
|
|
@@ -74,6 +74,12 @@ open class WebViewDelegationHandler: NSObject, WKNavigationDelegate, WKUIDelegat
|
|
|
74
74
|
return
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
// The proxy returns a remote body at the app origin, so block it before plugins can allow it.
|
|
78
|
+
if navURL.path.starts(with: CapacitorBridge.httpInterceptorStartIdentifier) {
|
|
79
|
+
decisionHandler(.cancel)
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
77
83
|
// first, give plugins the chance to handle the decision
|
|
78
84
|
for pluginObject in bridge.plugins {
|
|
79
85
|
let plugin = pluginObject.value
|
|
@@ -107,7 +113,7 @@ open class WebViewDelegationHandler: NSObject, WKNavigationDelegate, WKUIDelegat
|
|
|
107
113
|
|
|
108
114
|
if !isApplicationNavigation, toplevelNavigation {
|
|
109
115
|
// disallow and let the system handle it
|
|
110
|
-
if
|
|
116
|
+
if webView.window?.windowScene?.activationState == .foregroundActive {
|
|
111
117
|
UIApplication.shared.open(navURL, options: [:], completionHandler: nil)
|
|
112
118
|
}
|
|
113
119
|
decisionHandler(.cancel)
|
|
@@ -367,12 +367,6 @@ var nativeBridge = (function (exports) {
|
|
|
367
367
|
}
|
|
368
368
|
};
|
|
369
369
|
const platform = getPlatformId(win);
|
|
370
|
-
if (platform == 'android' && typeof win.CapacitorSystemBarsAndroidInterface !== 'undefined') {
|
|
371
|
-
// add DOM ready listener for System Bars
|
|
372
|
-
document.addEventListener('DOMContentLoaded', function () {
|
|
373
|
-
win.CapacitorSystemBarsAndroidInterface.onDOMReady();
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
370
|
if (platform == 'android' || platform == 'ios') {
|
|
377
371
|
// patch document.cookie on Android/iOS
|
|
378
372
|
win.CapacitorCookiesDescriptor =
|
package/{CapacitorCordova/CapacitorCordova/Classes/Public → Sources/CapacitorCordova}/Plugin.swift
RENAMED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import Capacitor
|
|
2
|
+
// Under CocoaPods this file is compiled into the Cordova module itself, so importing it would be a
|
|
3
|
+
// self-import. Under SPM the Swift and Objective-C halves are separate targets.
|
|
4
|
+
#if SWIFT_PACKAGE
|
|
5
|
+
import Cordova
|
|
6
|
+
#endif
|
|
2
7
|
|
|
3
8
|
@objc(CordovaPlugin)
|
|
4
9
|
public class CordovaPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
#import "CAPInstanceConfiguration.h"
|
|
2
|
-
#import
|
|
2
|
+
#import "CAPInstanceDescriptor.h"
|
|
3
|
+
|
|
4
|
+
// Implemented in Swift (CAPInstanceDescriptor.swift), which can't be imported here without a
|
|
5
|
+
// circular dependency. Declared locally rather than in the header so Swift doesn't see a
|
|
6
|
+
// redeclaration.
|
|
7
|
+
@interface CAPInstanceDescriptor (SwiftVended)
|
|
8
|
+
@property (nonatomic, readonly) BOOL cordovaDeployDisabled;
|
|
9
|
+
- (void)normalize;
|
|
10
|
+
@end
|
|
3
11
|
|
|
4
12
|
@interface CAPInstanceConfiguration (Internal)
|
|
5
13
|
- (instancetype)initWithConfiguration:(CAPInstanceConfiguration*)configuration andLocation:(NSURL*)location;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#import "CAPPlugin.h"
|
|
2
|
+
#import "CAPPluginCall.h"
|
|
3
|
+
#import <Foundation/Foundation.h>
|
|
4
|
+
|
|
5
|
+
// Implemented in Swift (CAPPlugin+Bridge.swift), which can't be imported here without a circular
|
|
6
|
+
// dependency. Declared locally rather than in the header so Swift doesn't see a redeclaration.
|
|
7
|
+
@interface CAPPlugin (SwiftVended)
|
|
8
|
+
- (void)notifyListeners:(NSString* _Nonnull)eventName data:(NSDictionary<NSString *, id>* _Nullable)data;
|
|
9
|
+
@end
|
|
10
|
+
|
|
11
|
+
@implementation CAPPlugin
|
|
12
|
+
|
|
13
|
+
- (instancetype)init {
|
|
14
|
+
if ((self = [super init])) {
|
|
15
|
+
_pluginId = @"";
|
|
16
|
+
_pluginName = @"";
|
|
17
|
+
_eventListeners = [[NSMutableDictionary alloc] init];
|
|
18
|
+
_retainedEventArguments = [[NSMutableDictionary alloc] init];
|
|
19
|
+
_shouldStringifyDatesInCalls = YES;
|
|
20
|
+
}
|
|
21
|
+
return self;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
-(NSString *) getId {
|
|
25
|
+
return self.pluginName;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
-(void)load {}
|
|
29
|
+
|
|
30
|
+
- (void)addEventListener:(NSString *)eventName listener:(CAPPluginCall *)listener {
|
|
31
|
+
NSMutableArray *listenersForEvent = [self.eventListeners objectForKey:eventName];
|
|
32
|
+
if(listenersForEvent == nil || [listenersForEvent count] == 0) {
|
|
33
|
+
listenersForEvent = [[NSMutableArray alloc] initWithObjects:listener, nil];
|
|
34
|
+
[self.eventListeners setValue:listenersForEvent forKey:eventName];
|
|
35
|
+
|
|
36
|
+
[self sendRetainedArgumentsForEvent:eventName];
|
|
37
|
+
} else {
|
|
38
|
+
[listenersForEvent addObject:listener];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
- (void)sendRetainedArgumentsForEvent:(NSString *)eventName {
|
|
43
|
+
// copy retained args and null source to prevent potential race conditions
|
|
44
|
+
NSMutableArray *retained = [self.retainedEventArguments objectForKey:eventName];
|
|
45
|
+
if (retained == nil) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
[self.retainedEventArguments removeObjectForKey:eventName];
|
|
50
|
+
|
|
51
|
+
for(id data in retained) {
|
|
52
|
+
[self notifyListeners:eventName data:data];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
- (void)removeEventListener:(NSString *)eventName listener:(CAPPluginCall *)listener {
|
|
57
|
+
NSMutableArray *listenersForEvent = [self.eventListeners objectForKey:eventName];
|
|
58
|
+
if(!listenersForEvent) { return; }
|
|
59
|
+
NSUInteger listenerIndex = [listenersForEvent indexOfObject:listener];
|
|
60
|
+
if(listenerIndex == NSNotFound) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
[listenersForEvent removeObjectAtIndex:listenerIndex];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
- (void)addListener:(CAPPluginCall *)call {
|
|
67
|
+
NSString *eventName = [call.options objectForKey:@"eventName"];
|
|
68
|
+
[call setKeepAlive:TRUE];
|
|
69
|
+
[self addEventListener:eventName listener:call];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
- (NSArray<CAPPluginCall *>*)getListeners:(NSString *)eventName {
|
|
73
|
+
NSArray<CAPPluginCall *>* listeners = [self.eventListeners objectForKey:eventName];
|
|
74
|
+
return listeners;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
- (BOOL)hasListeners:(NSString *)eventName {
|
|
78
|
+
NSArray<CAPPluginCall *>* listeners = [self.eventListeners objectForKey:eventName];
|
|
79
|
+
|
|
80
|
+
if (listeners == nil) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return [listeners count] > 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
-(BOOL)supportsPopover {
|
|
87
|
+
return YES;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
- (NSNumber*)shouldOverrideLoad:(WKNavigationAction*)navigationAction {
|
|
91
|
+
return nil;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
- (BOOL)handleWKWebViewURLAuthenticationChallenge:(NSURLAuthenticationChallenge* _Nonnull)challenge completionHandler:(void (^_Nonnull)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
|
|
95
|
+
return NO;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@end
|
|
100
|
+
|