@capacitor-plus/ios 8.0.0-beta.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.
Files changed (106) hide show
  1. package/Capacitor/Capacitor/AppUUID.swift +51 -0
  2. package/Capacitor/Capacitor/Array+Capacitor.swift +31 -0
  3. package/Capacitor/Capacitor/CAPApplicationDelegateProxy.swift +32 -0
  4. package/Capacitor/Capacitor/CAPBridge.swift +25 -0
  5. package/Capacitor/Capacitor/CAPBridgeDelegate.swift +6 -0
  6. package/Capacitor/Capacitor/CAPBridgeProtocol.swift +148 -0
  7. package/Capacitor/Capacitor/CAPBridgeViewController+CDVScreenOrientationDelegate.h +6 -0
  8. package/Capacitor/Capacitor/CAPBridgeViewController+CDVScreenOrientationDelegate.m +5 -0
  9. package/Capacitor/Capacitor/CAPBridgeViewController.swift +384 -0
  10. package/Capacitor/Capacitor/CAPBridgedJSTypes.h +18 -0
  11. package/Capacitor/Capacitor/CAPBridgedJSTypes.m +43 -0
  12. package/Capacitor/Capacitor/CAPBridgedPlugin+getMethod.swift +13 -0
  13. package/Capacitor/Capacitor/CAPBridgedPlugin.h +41 -0
  14. package/Capacitor/Capacitor/CAPFile.swift +14 -0
  15. package/Capacitor/Capacitor/CAPInstanceConfiguration.h +38 -0
  16. package/Capacitor/Capacitor/CAPInstanceConfiguration.m +93 -0
  17. package/Capacitor/Capacitor/CAPInstanceConfiguration.swift +78 -0
  18. package/Capacitor/Capacitor/CAPInstanceDescriptor.h +167 -0
  19. package/Capacitor/Capacitor/CAPInstanceDescriptor.m +56 -0
  20. package/Capacitor/Capacitor/CAPInstanceDescriptor.swift +198 -0
  21. package/Capacitor/Capacitor/CAPInstancePlugin.swift +10 -0
  22. package/Capacitor/Capacitor/CAPLog.swift +11 -0
  23. package/Capacitor/Capacitor/CAPNotifications.swift +69 -0
  24. package/Capacitor/Capacitor/CAPPlugin+LoadInstance.swift +20 -0
  25. package/Capacitor/Capacitor/CAPPlugin.h +60 -0
  26. package/Capacitor/Capacitor/CAPPlugin.m +180 -0
  27. package/Capacitor/Capacitor/CAPPluginCall.h +25 -0
  28. package/Capacitor/Capacitor/CAPPluginCall.m +36 -0
  29. package/Capacitor/Capacitor/CAPPluginCall.swift +97 -0
  30. package/Capacitor/Capacitor/CAPPluginMethod.h +36 -0
  31. package/Capacitor/Capacitor/CAPPluginMethod.m +44 -0
  32. package/Capacitor/Capacitor/CAPPluginMethod.swift +17 -0
  33. package/Capacitor/Capacitor/Capacitor.h +15 -0
  34. package/Capacitor/Capacitor/Capacitor.modulemap +8 -0
  35. package/Capacitor/Capacitor/CapacitorBridge.swift +768 -0
  36. package/Capacitor/Capacitor/CapacitorExtension.swift +24 -0
  37. package/Capacitor/Capacitor/Codable/JSValueDecoder.swift +479 -0
  38. package/Capacitor/Capacitor/Codable/JSValueEncoder.swift +671 -0
  39. package/Capacitor/Capacitor/Data+Capacitor.swift +22 -0
  40. package/Capacitor/Capacitor/DocLinks.swift +8 -0
  41. package/Capacitor/Capacitor/Info.plist +24 -0
  42. package/Capacitor/Capacitor/JS.swift +122 -0
  43. package/Capacitor/Capacitor/JSExport.swift +218 -0
  44. package/Capacitor/Capacitor/JSTypes.swift +254 -0
  45. package/Capacitor/Capacitor/KeyPath.swift +60 -0
  46. package/Capacitor/Capacitor/KeyValueStore.swift +303 -0
  47. package/Capacitor/Capacitor/NotificationHandlerProtocol.swift +6 -0
  48. package/Capacitor/Capacitor/NotificationRouter.swift +60 -0
  49. package/Capacitor/Capacitor/PluginCallResult.swift +106 -0
  50. package/Capacitor/Capacitor/PluginConfig.swift +56 -0
  51. package/Capacitor/Capacitor/Plugins/CapacitorCookieManager.swift +141 -0
  52. package/Capacitor/Capacitor/Plugins/CapacitorCookies.swift +57 -0
  53. package/Capacitor/Capacitor/Plugins/CapacitorHttp.swift +57 -0
  54. package/Capacitor/Capacitor/Plugins/CapacitorUrlRequest.swift +225 -0
  55. package/Capacitor/Capacitor/Plugins/Console.swift +16 -0
  56. package/Capacitor/Capacitor/Plugins/HttpRequestHandler.swift +236 -0
  57. package/Capacitor/Capacitor/Plugins/SystemBars.swift +133 -0
  58. package/Capacitor/Capacitor/Plugins/WebView.swift +44 -0
  59. package/Capacitor/Capacitor/PrivacyInfo.xcprivacy +14 -0
  60. package/Capacitor/Capacitor/Router.swift +29 -0
  61. package/Capacitor/Capacitor/TmpViewController.swift +8 -0
  62. package/Capacitor/Capacitor/UIColor.swift +55 -0
  63. package/Capacitor/Capacitor/UIStatusBarManager+CAPHandleTapAction.m +37 -0
  64. package/Capacitor/Capacitor/WKWebView+Capacitor.m +15 -0
  65. package/Capacitor/Capacitor/WKWebView+Capacitor.swift +80 -0
  66. package/Capacitor/Capacitor/WebViewAssetHandler.swift +550 -0
  67. package/Capacitor/Capacitor/WebViewDelegationHandler.swift +361 -0
  68. package/Capacitor/Capacitor/assets/native-bridge.js +1029 -0
  69. package/Capacitor.podspec +23 -0
  70. package/CapacitorCordova/CapacitorCordova/CapacitorCordova.h +25 -0
  71. package/CapacitorCordova/CapacitorCordova/CapacitorCordova.modulemap +6 -0
  72. package/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.h +8 -0
  73. package/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.m +5 -0
  74. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDV.h +28 -0
  75. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVAvailability.h +109 -0
  76. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVAvailabilityDeprecated.h +21 -0
  77. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegate.h +49 -0
  78. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.h +39 -0
  79. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.m +149 -0
  80. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.h +31 -0
  81. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.m +81 -0
  82. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.h +52 -0
  83. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.m +116 -0
  84. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin+Resources.h +39 -0
  85. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin+Resources.m +38 -0
  86. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.h +76 -0
  87. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.m +136 -0
  88. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.h +25 -0
  89. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.m +77 -0
  90. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.h +82 -0
  91. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.m +216 -0
  92. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVScreenOrientationDelegate.h +33 -0
  93. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.h +27 -0
  94. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.m +74 -0
  95. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.h +30 -0
  96. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.m +37 -0
  97. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVWebViewProcessPoolFactory.h +34 -0
  98. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVWebViewProcessPoolFactory.m +55 -0
  99. package/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.h +35 -0
  100. package/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.m +63 -0
  101. package/CapacitorCordova/CapacitorCordova/Info.plist +26 -0
  102. package/CapacitorCordova/CapacitorCordova/PrivacyInfo.xcprivacy +14 -0
  103. package/CapacitorCordova.podspec +26 -0
  104. package/LICENSE +21 -0
  105. package/package.json +33 -0
  106. package/scripts/pods_helpers.rb +12 -0
@@ -0,0 +1,384 @@
1
+ import UIKit
2
+ import WebKit
3
+ import Cordova
4
+
5
+ @objc open class CAPBridgeViewController: UIViewController {
6
+ private var capacitorBridge: CapacitorBridge?
7
+ public final var bridge: CAPBridgeProtocol? {
8
+ return capacitorBridge
9
+ }
10
+
11
+ public fileprivate(set) var webView: WKWebView?
12
+
13
+ public var isStatusBarVisible = true
14
+ public var statusBarStyle: UIStatusBarStyle = .default
15
+ public var statusBarAnimation: UIStatusBarAnimation = .fade
16
+ @objc public var supportedOrientations: [Int] = []
17
+
18
+ public lazy final var isNewBinary: Bool = {
19
+ if let curVersionCode = Bundle.main.infoDictionary?["CFBundleVersion"] as? String,
20
+ let curVersionName = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
21
+ if let lastVersionCode = KeyValueStore.standard["lastBinaryVersionCode", as: String.self],
22
+ let lastVersionName = KeyValueStore.standard["lastBinaryVersionName", as: String.self] {
23
+ return curVersionCode != lastVersionCode || curVersionName != lastVersionName
24
+ }
25
+ return true
26
+ }
27
+ return false
28
+ }()
29
+
30
+ override public final func loadView() {
31
+ // load the configuration and set the logging flag
32
+ let configDescriptor = instanceDescriptor()
33
+ let configuration = InstanceConfiguration(with: configDescriptor, isDebug: CapacitorBridge.isDevEnvironment)
34
+ CAPLog.enableLogging = configuration.loggingEnabled
35
+ logWarnings(for: configDescriptor)
36
+
37
+ setStatusBarDefaults()
38
+ setScreenOrientationDefaults()
39
+
40
+ // get the web view
41
+ let assetHandler = WebViewAssetHandler(router: router())
42
+ assetHandler.setAssetPath(configuration.appLocation.path)
43
+ assetHandler.setServerUrl(configuration.serverURL)
44
+ let delegationHandler = WebViewDelegationHandler()
45
+ prepareWebView(with: configuration, assetHandler: assetHandler, delegationHandler: delegationHandler)
46
+ view = webView
47
+ // create the bridge
48
+ capacitorBridge = CapacitorBridge(with: configuration,
49
+ delegate: self,
50
+ cordovaConfiguration: configDescriptor.cordovaConfiguration,
51
+ assetHandler: assetHandler,
52
+ delegationHandler: delegationHandler)
53
+ capacitorDidLoad()
54
+
55
+ if configDescriptor.instanceType == .fixed {
56
+ updateBinaryVersion()
57
+ }
58
+ }
59
+
60
+ override open func viewDidLoad() {
61
+ super.viewDidLoad()
62
+ loadWebView()
63
+ }
64
+
65
+ override open func viewDidAppear(_ animated: Bool) {
66
+ super.viewDidAppear(animated)
67
+ NotificationCenter.default.post(Notification(name: .capacitorViewDidAppear))
68
+ if bridge?.config.hasInitialFocus ?? true {
69
+ self.webView?.becomeFirstResponder()
70
+ }
71
+ }
72
+
73
+ override open func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
74
+ super.viewWillTransition(to: size, with: coordinator)
75
+ NotificationCenter.default.post(Notification(name: .capacitorViewWillTransition))
76
+ }
77
+
78
+ override open func canPerformUnwindSegueAction(_ action: Selector, from fromViewController: UIViewController, withSender sender: Any) -> Bool {
79
+ return false
80
+ }
81
+
82
+ // MARK: - Initialization
83
+
84
+ /**
85
+ The InstanceDescriptor that should be used for the Capacitor environment.
86
+
87
+ - Returns: `InstanceDescriptor`
88
+
89
+ - Note: This is called early in the View Controller's lifecycle. Not all properties will be set at invocation.
90
+ */
91
+ open func instanceDescriptor() -> InstanceDescriptor {
92
+ let descriptor = InstanceDescriptor.init()
93
+ if !isNewBinary && !descriptor.cordovaDeployDisabled {
94
+ if let persistedPath = KeyValueStore.standard["serverBasePath", as: String.self], !persistedPath.isEmpty {
95
+ if let libPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).first {
96
+ descriptor.appLocation = URL(fileURLWithPath: libPath, isDirectory: true)
97
+ .appendingPathComponent("NoCloud")
98
+ .appendingPathComponent("ionic_built_snapshots")
99
+ .appendingPathComponent(URL(fileURLWithPath: persistedPath, isDirectory: true).lastPathComponent)
100
+ }
101
+ }
102
+ }
103
+ return descriptor
104
+ }
105
+
106
+ open func router() -> Router {
107
+ return CapacitorRouter()
108
+ }
109
+
110
+ /**
111
+ The WKWebViewConfiguration to use for the webview.
112
+
113
+ - Parameter instanceConfiguration: the configuration that will define the capacitor environment.
114
+
115
+ - Returns: `WKWebViewConfiguration`
116
+
117
+ It is recommended to call super's implementation and modify the result, rather than creating a new object.
118
+ */
119
+ open func webViewConfiguration(for instanceConfiguration: InstanceConfiguration) -> WKWebViewConfiguration {
120
+ let webViewConfiguration = WKWebViewConfiguration()
121
+ webViewConfiguration.websiteDataStore.httpCookieStore.add(CapacitorWKCookieObserver())
122
+ webViewConfiguration.allowsInlineMediaPlayback = true
123
+ webViewConfiguration.suppressesIncrementalRendering = false
124
+ webViewConfiguration.allowsAirPlayForMediaPlayback = true
125
+ webViewConfiguration.mediaTypesRequiringUserActionForPlayback = []
126
+ webViewConfiguration.limitsNavigationsToAppBoundDomains = instanceConfiguration.limitsNavigationsToAppBoundDomains
127
+ if #available(iOS 15.4, *) {
128
+ webViewConfiguration.preferences.isElementFullscreenEnabled = true
129
+ }
130
+ if let appendUserAgent = instanceConfiguration.appendedUserAgentString {
131
+ if let appName = webViewConfiguration.applicationNameForUserAgent {
132
+ webViewConfiguration.applicationNameForUserAgent = "\(appName) \(appendUserAgent)"
133
+ } else {
134
+ webViewConfiguration.applicationNameForUserAgent = appendUserAgent
135
+ }
136
+ }
137
+ if let preferredContentMode = instanceConfiguration.preferredContentMode {
138
+ var mode = WKWebpagePreferences.ContentMode.recommended
139
+ if preferredContentMode == "mobile" {
140
+ mode = WKWebpagePreferences.ContentMode.mobile
141
+ } else if preferredContentMode == "desktop" {
142
+ mode = WKWebpagePreferences.ContentMode.desktop
143
+ }
144
+ webViewConfiguration.defaultWebpagePreferences.preferredContentMode = mode
145
+ }
146
+ return webViewConfiguration
147
+ }
148
+
149
+ /**
150
+ Returns a WKWebView initialized with the frame and configuration.
151
+
152
+ Subclasses can override this method to return a subclass of WKWebView if needed.
153
+ */
154
+ open func webView(with frame: CGRect, configuration: WKWebViewConfiguration) -> WKWebView {
155
+ return WKWebView(frame: frame, configuration: configuration)
156
+ }
157
+
158
+ /**
159
+ Allows any additional configuration to be performed. The `webView` and `bridge` properties will be set by this point.
160
+
161
+ - Note: This is called before the webview has been added to the view hierarchy. Not all operations may be possible at
162
+ this time.
163
+ */
164
+ open func capacitorDidLoad() {
165
+ }
166
+
167
+ public final func loadWebView() {
168
+ guard let bridge = capacitorBridge else {
169
+ return
170
+ }
171
+
172
+ guard FileManager.default.fileExists(atPath: bridge.config.appStartFileURL.path) else {
173
+ fatalLoadError()
174
+ }
175
+
176
+ let url = bridge.config.appStartServerURL
177
+ CAPLog.print("⚡️ Loading app at \(url.absoluteString)...")
178
+ bridge.webViewDelegationHandler.willLoadWebview(webView)
179
+ _ = webView?.load(URLRequest(url: url))
180
+ }
181
+
182
+ // MARK: - System Integration
183
+
184
+ open func setStatusBarDefaults() {
185
+ if let plist = Bundle.main.infoDictionary {
186
+ if let statusBarHidden = plist["UIStatusBarHidden"] as? Bool {
187
+ if statusBarHidden {
188
+ self.isStatusBarVisible = false
189
+ }
190
+ }
191
+ if let statusBarStyle = plist["UIStatusBarStyle"] as? String {
192
+ if statusBarStyle == "UIStatusBarStyleDarkContent" {
193
+ self.statusBarStyle = .darkContent
194
+ } else if statusBarStyle != "UIStatusBarStyleDefault" {
195
+ self.statusBarStyle = .lightContent
196
+ }
197
+ }
198
+ }
199
+ }
200
+
201
+ open func setScreenOrientationDefaults() {
202
+ if let plist = Bundle.main.infoDictionary {
203
+ if let orientations = plist["UISupportedInterfaceOrientations"] as? [String] {
204
+ for orientation in orientations {
205
+ if orientation == "UIInterfaceOrientationPortrait" {
206
+ self.supportedOrientations.append(UIInterfaceOrientation.portrait.rawValue)
207
+ }
208
+ if orientation == "UIInterfaceOrientationPortraitUpsideDown" {
209
+ self.supportedOrientations.append(UIInterfaceOrientation.portraitUpsideDown.rawValue)
210
+ }
211
+ if orientation == "UIInterfaceOrientationLandscapeLeft" {
212
+ self.supportedOrientations.append(UIInterfaceOrientation.landscapeLeft.rawValue)
213
+ }
214
+ if orientation == "UIInterfaceOrientationLandscapeRight" {
215
+ self.supportedOrientations.append(UIInterfaceOrientation.landscapeRight.rawValue)
216
+ }
217
+ }
218
+ if self.supportedOrientations.count == 0 {
219
+ self.supportedOrientations.append(UIInterfaceOrientation.portrait.rawValue)
220
+ }
221
+ }
222
+ }
223
+ }
224
+
225
+ override open var prefersStatusBarHidden: Bool {
226
+ return !isStatusBarVisible
227
+ }
228
+
229
+ override open var preferredStatusBarStyle: UIStatusBarStyle {
230
+ return statusBarStyle
231
+ }
232
+
233
+ override open var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
234
+ return statusBarAnimation
235
+ }
236
+
237
+ open func setStatusBarVisible(_ isStatusBarVisible: Bool) {
238
+ self.isStatusBarVisible = isStatusBarVisible
239
+ UIView.animate(withDuration: 0.2, animations: {
240
+ self.setNeedsStatusBarAppearanceUpdate()
241
+ })
242
+ }
243
+
244
+ open func setStatusBarStyle(_ statusBarStyle: UIStatusBarStyle) {
245
+ self.statusBarStyle = statusBarStyle
246
+ UIView.animate(withDuration: 0.2, animations: {
247
+ self.setNeedsStatusBarAppearanceUpdate()
248
+ })
249
+ }
250
+
251
+ open func setStatusBarAnimation(_ statusBarAnimation: UIStatusBarAnimation) {
252
+ self.statusBarAnimation = statusBarAnimation
253
+ }
254
+
255
+ override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
256
+ var ret = 0
257
+ if self.supportedOrientations.contains(UIInterfaceOrientation.portrait.rawValue) {
258
+ ret = ret | (1 << UIInterfaceOrientation.portrait.rawValue)
259
+ }
260
+ if self.supportedOrientations.contains(UIInterfaceOrientation.portraitUpsideDown.rawValue) {
261
+ ret = ret | (1 << UIInterfaceOrientation.portraitUpsideDown.rawValue)
262
+ }
263
+ if self.supportedOrientations.contains(UIInterfaceOrientation.landscapeRight.rawValue) {
264
+ ret = ret | (1 << UIInterfaceOrientation.landscapeRight.rawValue)
265
+ }
266
+ if self.supportedOrientations.contains(UIInterfaceOrientation.landscapeLeft.rawValue) {
267
+ ret = ret | (1 << UIInterfaceOrientation.landscapeLeft.rawValue)
268
+ }
269
+ return UIInterfaceOrientationMask.init(rawValue: UInt(ret))
270
+ }
271
+ }
272
+
273
+ // MARK: - Application Path
274
+
275
+ extension CAPBridgeViewController {
276
+ @objc public func getServerBasePath() -> String {
277
+ return bridge?.config.appLocation.path ?? ""
278
+ }
279
+
280
+ @objc public func setServerBasePath(path: String) {
281
+ guard let capBridge = capacitorBridge else { return }
282
+ capBridge.setServerBasePath(path)
283
+ DispatchQueue.main.async { [weak self] in
284
+ _ = self?.webView?.load(URLRequest(url: capBridge.config.serverURL))
285
+ }
286
+ }
287
+ }
288
+
289
+ // MARK: - Private
290
+
291
+ extension CAPBridgeViewController {
292
+ private func prepareWebView(with configuration: InstanceConfiguration, assetHandler: WebViewAssetHandler, delegationHandler: WebViewDelegationHandler) {
293
+ // set the cookie policy
294
+ HTTPCookieStorage.shared.cookieAcceptPolicy = HTTPCookie.AcceptPolicy.always
295
+ // setup the web view configuration
296
+ let webConfig = webViewConfiguration(for: configuration)
297
+ webConfig.setURLSchemeHandler(assetHandler, forURLScheme: configuration.localURL.scheme ?? InstanceDescriptorDefaults.scheme)
298
+ webConfig.userContentController = delegationHandler.contentController
299
+ // create the web view and set its properties
300
+ let aWebView = webView(with: .zero, configuration: webConfig)
301
+ aWebView.scrollView.bounces = false
302
+ aWebView.scrollView.contentInsetAdjustmentBehavior = configuration.contentInsetAdjustmentBehavior
303
+ aWebView.allowsLinkPreview = configuration.allowLinkPreviews
304
+ aWebView.scrollView.isScrollEnabled = configuration.scrollingEnabled
305
+ if let overrideUserAgent = configuration.overridenUserAgentString {
306
+ aWebView.customUserAgent = overrideUserAgent
307
+ }
308
+ if let backgroundColor = configuration.backgroundColor {
309
+ aWebView.backgroundColor = backgroundColor
310
+ aWebView.scrollView.backgroundColor = backgroundColor
311
+ } else {
312
+ // Use the system background colors if background is not set by user
313
+ aWebView.backgroundColor = UIColor.systemBackground
314
+ aWebView.scrollView.backgroundColor = UIColor.systemBackground
315
+ }
316
+ aWebView.capacitor.setKeyboardShouldRequireUserInteraction(false)
317
+ // set our ivar
318
+ webView = aWebView
319
+ // set our delegates
320
+ aWebView.uiDelegate = delegationHandler
321
+ aWebView.navigationDelegate = delegationHandler
322
+ if !configuration.zoomingEnabled {
323
+ aWebView.scrollView.delegate = delegationHandler
324
+ }
325
+ }
326
+
327
+ private func updateBinaryVersion() {
328
+ guard isNewBinary else {
329
+ return
330
+ }
331
+ guard let versionCode = Bundle.main.infoDictionary?["CFBundleVersion"] as? String,
332
+ let versionName = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else {
333
+ return
334
+ }
335
+ let store = KeyValueStore.standard
336
+ store["lastBinaryVersionCode"] = versionCode
337
+ store["lastBinaryVersionName"] = versionName
338
+ store["serverBasePath"] = nil as String?
339
+ }
340
+
341
+ private func logWarnings(for descriptor: InstanceDescriptor) {
342
+ if descriptor.warnings.contains(.missingAppDir) {
343
+ CAPLog.print("⚡️ ERROR: Unable to find application directory at: \"\(descriptor.appLocation.absoluteString)\"!")
344
+ }
345
+ if descriptor.instanceType == .fixed {
346
+ if descriptor.warnings.contains(.missingFile) {
347
+ CAPLog.print("Unable to find capacitor.config.json, make sure it exists and run npx cap copy.")
348
+ }
349
+ if descriptor.warnings.contains(.invalidFile) {
350
+ CAPLog.print("Unable to parse capacitor.config.json. Make sure it's valid JSON.")
351
+ }
352
+ if descriptor.warnings.contains(.missingCordovaFile) {
353
+ CAPLog.print("Unable to find config.xml, make sure it exists and run npx cap copy.")
354
+ }
355
+ if descriptor.warnings.contains(.invalidCordovaFile) {
356
+ CAPLog.print("Unable to parse config.xml. Make sure it's valid XML.")
357
+ }
358
+ }
359
+ }
360
+
361
+ private func printLoadError() {
362
+ let fullStartPath = bridge?.config.appStartFileURL.path ?? ""
363
+
364
+ CAPLog.print("⚡️ ERROR: Unable to load \(fullStartPath)")
365
+ CAPLog.print("⚡️ This file is the root of your web app and must exist before")
366
+ CAPLog.print("⚡️ Capacitor can run. Ensure you've run capacitor copy at least")
367
+ CAPLog.print("⚡️ or, if embedding, that this directory exists as a resource directory.")
368
+ }
369
+
370
+ private func fatalLoadError() -> Never {
371
+ printLoadError()
372
+ exit(1)
373
+ }
374
+ }
375
+
376
+ extension CAPBridgeViewController: CAPBridgeDelegate {
377
+ public var bridgedWebView: WKWebView? {
378
+ return webView
379
+ }
380
+
381
+ public var bridgedViewController: UIViewController? {
382
+ return self
383
+ }
384
+ }
@@ -0,0 +1,18 @@
1
+ // Convenience methods for bridging to/from JavaScript types. Deliberately hidden from
2
+ // Swift by omission (to avoid collisions with Swift protocols), use
3
+ // `#import <Capacitor/CAPBridgedJSTypes.h>` if working in Objective-C.
4
+
5
+ #import <Foundation/Foundation.h>
6
+ #import <Capacitor/Capacitor-Swift.h>
7
+
8
+ @protocol BridgedJSValueContainerImplementation <NSObject>
9
+ @required
10
+ - (NSString * _Nullable)getString:(NSString * _Nonnull)key defaultValue:(NSString * _Nullable)defaultValue;
11
+ - (NSDate * _Nullable)getDate:(NSString * _Nonnull)key defaultValue:(NSDate * _Nullable)defaultValue;
12
+ - (NSDictionary * _Nullable)getObject:(NSString * _Nonnull)key defaultValue:(NSDictionary * _Nullable)defaultValue;
13
+ - (NSNumber * _Nullable)getNumber:(NSString * _Nonnull)key defaultValue:(NSNumber * _Nullable)defaultValue;
14
+ - (BOOL)getBool:(NSString * _Nonnull)key defaultValue:(BOOL)defaultValue;
15
+ @end
16
+
17
+ @interface CAPPluginCall (BridgedJSProtocol) <BridgedJSValueContainerImplementation>
18
+ @end
@@ -0,0 +1,43 @@
1
+ #import <Foundation/Foundation.h>
2
+ #import "CAPBridgedJSTypes.h"
3
+
4
+ @implementation CAPPluginCall (BridgedJSProtocol)
5
+ - (NSString * _Nullable)getString:(NSString * _Nonnull)key defaultValue:(NSString * _Nullable)defaultValue {
6
+ id value = [[self dictionaryRepresentation] objectForKey:key];
7
+ if (value != nil && [value isKindOfClass:[NSString class]]) {
8
+ return value;
9
+ }
10
+ return defaultValue;
11
+ }
12
+
13
+ - (NSDate * _Nullable)getDate:(NSString * _Nonnull)key defaultValue:(NSDate * _Nullable)defaultValue {
14
+ id value = [[self dictionaryRepresentation] objectForKey:key];
15
+ if (value != nil && [value isKindOfClass:[NSDate class]]) {
16
+ return value;
17
+ }
18
+ else if (value != nil && [value isKindOfClass:[NSString class]]) {
19
+ return [[[self class] jsDateFormatter] dateFromString:value];
20
+ }
21
+ return defaultValue;
22
+ }
23
+
24
+ - (NSDictionary * _Nullable)getObject:(NSString * _Nonnull)key defaultValue:(NSDictionary * _Nullable)defaultValue {
25
+ id value = [[self dictionaryRepresentation] objectForKey:key];
26
+ if (value != nil && [value isKindOfClass:[NSDictionary class]]) {
27
+ return value;
28
+ }
29
+ return defaultValue;
30
+ }
31
+
32
+ - (NSNumber * _Nullable)getNumber:(NSString * _Nonnull)key defaultValue:(NSNumber * _Nullable)defaultValue {
33
+ id value = [[self dictionaryRepresentation] objectForKey:key];
34
+ if (value != nil && [value isKindOfClass:[NSNumber class]]) {
35
+ return value;
36
+ }
37
+ return defaultValue;
38
+ }
39
+
40
+ - (BOOL)getBool:(NSString * _Nonnull)key defaultValue:(BOOL)defaultValue {
41
+ return [[self getNumber:key defaultValue:[NSNumber numberWithBool:defaultValue]] boolValue];
42
+ }
43
+ @end
@@ -0,0 +1,13 @@
1
+ //
2
+ // CAPBridgedPlugin+getMethod.swift
3
+ // Capacitor
4
+ //
5
+ // Created by Steven Sherry on 3/1/23.
6
+ // Copyright © 2023 Drifty Co. All rights reserved.
7
+ //
8
+
9
+ extension CAPBridgedPlugin {
10
+ func getMethod(named name: String) -> CAPPluginMethod? {
11
+ pluginMethods.first { $0.name == name }
12
+ }
13
+ }
@@ -0,0 +1,41 @@
1
+ #import "CAPPluginMethod.h"
2
+
3
+ #if defined(__cplusplus)
4
+ #define CAP_EXTERN extern "C" __attribute__((visibility("default")))
5
+ #else
6
+ #define CAP_EXTERN extern __attribute__((visibility("default")))
7
+ #endif
8
+
9
+ #define CAPPluginReturnNone @"none"
10
+ #define CAPPluginReturnCallback @"callback"
11
+ #define CAPPluginReturnPromise @"promise"
12
+
13
+ @class CAPPluginCall;
14
+ @class CAPPlugin;
15
+
16
+ @protocol CAPBridgedPlugin <NSObject>
17
+ @property (nonnull, readonly) NSString *identifier;
18
+ @property (nonnull, readonly) NSString *jsName;
19
+ @property (nonnull, readonly) NSArray<CAPPluginMethod *> *pluginMethods;
20
+ @end
21
+
22
+ #define CAP_PLUGIN_CONFIG(plugin_id, js_name) \
23
+ - (NSString *)identifier { return @#plugin_id; } \
24
+ - (NSString *)jsName { return @js_name; }
25
+ #define CAP_PLUGIN_METHOD(method_name, method_return_type) \
26
+ [methods addObject:[[CAPPluginMethod alloc] initWithName:@#method_name returnType:method_return_type]]
27
+
28
+ #define CAP_PLUGIN(objc_name, js_name, methods_body) \
29
+ @interface objc_name : NSObject \
30
+ @end \
31
+ @interface objc_name (CAPPluginCategory) <CAPBridgedPlugin> \
32
+ @end \
33
+ @implementation objc_name (CAPPluginCategory) \
34
+ - (NSArray *)pluginMethods { \
35
+ NSMutableArray *methods = [NSMutableArray new]; \
36
+ methods_body \
37
+ return methods; \
38
+ } \
39
+ CAP_PLUGIN_CONFIG(objc_name, js_name) \
40
+ @end
41
+
@@ -0,0 +1,14 @@
1
+ /**
2
+ * CAPFileManager helps map file schemes to physical files, whether they are on
3
+ * disk, in a bundle, or in another location.
4
+ */
5
+ @objc public class CAPFileManager: NSObject {
6
+ @available(*, deprecated, message: "Use portablePath(fromLocalURL:) on the Bridge")
7
+ public static func getPortablePath(host: String, uri: URL?) -> String? {
8
+ if let uri = uri {
9
+ let uriWithoutFile = uri.absoluteString.replacingOccurrences(of: "file://", with: "")
10
+ return host + CapacitorBridge.fileStartIdentifier + uriWithoutFile
11
+ }
12
+ return nil
13
+ }
14
+ }
@@ -0,0 +1,38 @@
1
+ #ifndef CAPInstanceConfiguration_h
2
+ #define CAPInstanceConfiguration_h
3
+
4
+ @import UIKit;
5
+
6
+ @class CAPInstanceDescriptor;
7
+
8
+ NS_SWIFT_NAME(InstanceConfiguration)
9
+ @interface CAPInstanceConfiguration: NSObject
10
+ @property (nonatomic, readonly, nullable) NSString *appendedUserAgentString;
11
+ @property (nonatomic, readonly, nullable) NSString *overridenUserAgentString;
12
+ @property (nonatomic, readonly, nullable) UIColor *backgroundColor;
13
+ @property (nonatomic, readonly, nonnull) NSArray<NSString*> *allowedNavigationHostnames;
14
+ @property (nonatomic, readonly, nonnull) NSURL *localURL;
15
+ @property (nonatomic, readonly, nonnull) NSURL *serverURL;
16
+ @property (nonatomic, readonly, nullable) NSString *errorPath;
17
+ @property (nonatomic, readonly, nonnull) NSDictionary *pluginConfigurations;
18
+ @property (nonatomic, readonly) BOOL loggingEnabled;
19
+ @property (nonatomic, readonly) BOOL scrollingEnabled;
20
+ @property (nonatomic, readonly) BOOL zoomingEnabled;
21
+ @property (nonatomic, readonly) BOOL allowLinkPreviews;
22
+ @property (nonatomic, readonly) BOOL handleApplicationNotifications;
23
+ @property (nonatomic, readonly) BOOL isWebDebuggable;
24
+ @property (nonatomic, readonly) BOOL hasInitialFocus;
25
+ @property (nonatomic, readonly) BOOL cordovaDeployDisabled;
26
+ @property (nonatomic, readonly) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior;
27
+ @property (nonatomic, readonly, nonnull) NSURL *appLocation;
28
+ @property (nonatomic, readonly, nullable) NSString *appStartPath;
29
+ @property (nonatomic, readonly) BOOL limitsNavigationsToAppBoundDomains;
30
+ @property (nonatomic, readonly, nullable) NSString *preferredContentMode;
31
+
32
+ @property (nonatomic, readonly, nonnull) NSDictionary *legacyConfig DEPRECATED_MSG_ATTRIBUTE("Use direct properties instead");
33
+
34
+ - (instancetype _Nonnull)initWithDescriptor:(CAPInstanceDescriptor* _Nonnull)descriptor isDebug:(BOOL)debug NS_SWIFT_NAME(init(with:isDebug:));
35
+ - (instancetype _Nonnull)updatingAppLocation:(NSURL* _Nonnull)location NS_SWIFT_NAME(updatingAppLocation(_:));
36
+ @end
37
+
38
+ #endif /* CAPInstanceConfiguration_h */
@@ -0,0 +1,93 @@
1
+ #import "CAPInstanceConfiguration.h"
2
+ #import <Capacitor/Capacitor-Swift.h>
3
+
4
+ @interface CAPInstanceConfiguration (Internal)
5
+ - (instancetype)initWithConfiguration:(CAPInstanceConfiguration*)configuration andLocation:(NSURL*)location;
6
+ @end
7
+
8
+
9
+ @implementation CAPInstanceConfiguration
10
+
11
+ - (instancetype)initWithDescriptor:(CAPInstanceDescriptor *)descriptor isDebug:(BOOL)debug {
12
+ if (self = [super init]) {
13
+ // first, give the descriptor a chance to make itself internally consistent
14
+ [descriptor normalize];
15
+ // now copy the simple properties
16
+ _appendedUserAgentString = descriptor.appendedUserAgentString;
17
+ _overridenUserAgentString = descriptor.overridenUserAgentString;
18
+ _backgroundColor = descriptor.backgroundColor;
19
+ _allowedNavigationHostnames = descriptor.allowedNavigationHostnames;
20
+ switch (descriptor.loggingBehavior) {
21
+ case CAPInstanceLoggingBehaviorProduction:
22
+ _loggingEnabled = true;
23
+ break;
24
+ case CAPInstanceLoggingBehaviorDebug:
25
+ _loggingEnabled = debug;
26
+ break;
27
+ default:
28
+ _loggingEnabled = false;
29
+ break;
30
+ }
31
+ _scrollingEnabled = descriptor.scrollingEnabled;
32
+ _zoomingEnabled = descriptor.zoomingEnabled;
33
+ _allowLinkPreviews = descriptor.allowLinkPreviews;
34
+ _handleApplicationNotifications = descriptor.handleApplicationNotifications;
35
+ _contentInsetAdjustmentBehavior = descriptor.contentInsetAdjustmentBehavior;
36
+ _appLocation = descriptor.appLocation;
37
+ _appStartPath = descriptor.appStartPath;
38
+ _limitsNavigationsToAppBoundDomains = descriptor.limitsNavigationsToAppBoundDomains;
39
+ _preferredContentMode = descriptor.preferredContentMode;
40
+ _pluginConfigurations = descriptor.pluginConfigurations;
41
+ _isWebDebuggable = descriptor.isWebDebuggable;
42
+ _hasInitialFocus = descriptor.hasInitialFocus;
43
+ _legacyConfig = descriptor.legacyConfig;
44
+ // construct the necessary URLs
45
+ _localURL = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"%@://%@", descriptor.urlScheme, descriptor.urlHostname]];
46
+ if (descriptor.serverURL != nil) {
47
+ _serverURL = [[NSURL alloc] initWithString:(descriptor.serverURL)];
48
+ }
49
+ else {
50
+ _serverURL = _localURL;
51
+ }
52
+ _errorPath = descriptor.errorPath;
53
+ // extract the one value we care about from the cordova configuration
54
+ _cordovaDeployDisabled = [descriptor cordovaDeployDisabled];
55
+ }
56
+ return self;
57
+ }
58
+
59
+ - (instancetype)initWithConfiguration:(CAPInstanceConfiguration*)configuration andLocation:(NSURL*)location {
60
+ if (self = [super init]) {
61
+ _appendedUserAgentString = [[configuration appendedUserAgentString] copy];
62
+ _overridenUserAgentString = [[configuration overridenUserAgentString] copy];
63
+ _backgroundColor = configuration.backgroundColor;
64
+ _allowedNavigationHostnames = [[configuration allowedNavigationHostnames] copy];
65
+ _localURL = [[configuration localURL] copy];
66
+ _serverURL = [[configuration serverURL] copy];
67
+ _errorPath = [[configuration errorPath] copy];
68
+ _pluginConfigurations = [[configuration pluginConfigurations] copy];
69
+ _loggingEnabled = configuration.loggingEnabled;
70
+ _scrollingEnabled = configuration.scrollingEnabled;
71
+ _zoomingEnabled = configuration.zoomingEnabled;
72
+ _allowLinkPreviews = configuration.allowLinkPreviews;
73
+ _handleApplicationNotifications = configuration.handleApplicationNotifications;
74
+ _isWebDebuggable = configuration.isWebDebuggable;
75
+ _hasInitialFocus = configuration.hasInitialFocus;
76
+ _cordovaDeployDisabled = configuration.cordovaDeployDisabled;
77
+ _contentInsetAdjustmentBehavior = configuration.contentInsetAdjustmentBehavior;
78
+ // we don't care about internal usage of deprecated APIs and the framework should build cleanly
79
+ #pragma clang diagnostic push
80
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
81
+ _legacyConfig = [[configuration legacyConfig] copy];
82
+ #pragma clang diagnostic pop
83
+ _appStartPath = configuration.appStartPath;
84
+ _appLocation = [location copy];
85
+ }
86
+ return self;
87
+ }
88
+
89
+ - (instancetype)updatingAppLocation:(NSURL*)location {
90
+ return [[CAPInstanceConfiguration alloc] initWithConfiguration:self andLocation:location];
91
+ }
92
+
93
+ @end