@capacitor/ios 8.0.0-alpha.2 → 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.
@@ -27,19 +27,7 @@ import Cordova
27
27
  return false
28
28
  }()
29
29
 
30
- // TODO: Remove in Capacitor 8 after moving status bar plugin extensions code
31
- @objc func handleViewDidAppear() {
32
- if bridge?.config.hasInitialFocus ?? true {
33
- self.webView?.becomeFirstResponder()
34
- }
35
- }
36
-
37
- deinit {
38
- NotificationCenter.default.removeObserver(self)
39
- }
40
-
41
30
  override public final func loadView() {
42
- NotificationCenter.default.addObserver(self, selector: #selector(self.handleViewDidAppear), name: Notification.Name(rawValue: "CapacitorViewDidAppear"), object: nil)
43
31
  // load the configuration and set the logging flag
44
32
  let configDescriptor = instanceDescriptor()
45
33
  let configuration = InstanceConfiguration(with: configDescriptor, isDebug: CapacitorBridge.isDevEnvironment)
@@ -76,11 +64,17 @@ import Cordova
76
64
 
77
65
  override open func viewDidAppear(_ animated: Bool) {
78
66
  super.viewDidAppear(animated)
67
+ NotificationCenter.default.post(Notification(name: .capacitorViewDidAppear))
79
68
  if bridge?.config.hasInitialFocus ?? true {
80
69
  self.webView?.becomeFirstResponder()
81
70
  }
82
71
  }
83
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
+
84
78
  override open func canPerformUnwindSegueAction(_ action: Selector, from fromViewController: UIViewController, withSender sender: Any) -> Bool {
85
79
  return false
86
80
  }
@@ -135,7 +129,7 @@ import Cordova
135
129
  }
136
130
  if let appendUserAgent = instanceConfiguration.appendedUserAgentString {
137
131
  if let appName = webViewConfiguration.applicationNameForUserAgent {
138
- webViewConfiguration.applicationNameForUserAgent = "\(appName) \(appendUserAgent)"
132
+ webViewConfiguration.applicationNameForUserAgent = "\(appName) \(appendUserAgent)"
139
133
  } else {
140
134
  webViewConfiguration.applicationNameForUserAgent = appendUserAgent
141
135
  }
@@ -16,6 +16,8 @@ extension Notification.Name {
16
16
  public static let capacitorDecidePolicyForNavigationAction =
17
17
  Notification.Name(rawValue: "CapacitorDecidePolicyForNavigationActionNotification")
18
18
  public static let capacitorStatusBarTapped = Notification.Name(rawValue: "CapacitorStatusBarTappedNotification")
19
+ public static let capacitorViewDidAppear = Notification.Name(rawValue: "CapacitorViewDidAppear")
20
+ public static let capacitorViewWillTransition = Notification.Name(rawValue: "CapacitorViewWillTransition")
19
21
  }
20
22
 
21
23
  @objc extension NSNotification {
@@ -26,6 +28,8 @@ extension Notification.Name {
26
28
  public static let capacitorDidFailToRegisterForRemoteNotifications = Notification.Name.capacitorDidFailToRegisterForRemoteNotifications
27
29
  public static let capacitorDecidePolicyForNavigationAction = Notification.Name.capacitorDecidePolicyForNavigationAction
28
30
  public static let capacitorStatusBarTapped = Notification.Name.capacitorStatusBarTapped
31
+ public static let capacitorViewDidAppear = Notification.Name.capacitorViewDidAppear
32
+ public static let capacitorViewWillTransition = Notification.Name.capacitorViewWillTransition
29
33
  }
30
34
 
31
35
  /**
@@ -38,6 +38,11 @@
38
38
  * Returning nil will defer to the default Capacitor policy
39
39
  */
40
40
  - (NSNumber* _Nullable)shouldOverrideLoad:(WKNavigationAction* _Nonnull)navigationAction;
41
+ /**
42
+ * Allows plugins to hook into and respond to the WebView's URL authentication challenge.
43
+ * Returning false will defer to the default response of [.rejectProtectionSpace](https://developer.apple.com/documentation/Foundation/URLSession/AuthChallengeDisposition/rejectProtectionSpace).
44
+ */
45
+ - (BOOL)handleWKWebViewURLAuthenticationChallenge:(NSURLAuthenticationChallenge* _Nonnull)challenge completionHandler:(void (^_Nonnull)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;
41
46
 
42
47
  // Called after init if the plugin wants to do
43
48
  // some loading so the plugin author doesn't
@@ -171,5 +171,10 @@
171
171
  return nil;
172
172
  }
173
173
 
174
+ - (BOOL)handleWKWebViewURLAuthenticationChallenge:(NSURLAuthenticationChallenge* _Nonnull)challenge completionHandler:(void (^_Nonnull)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
175
+ return NO;
176
+ }
177
+
178
+
174
179
  @end
175
180
 
@@ -302,7 +302,7 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
302
302
  Register all plugins that have been declared
303
303
  */
304
304
  func registerPlugins() {
305
- var pluginList: [AnyClass] = [CAPHttpPlugin.self, CAPConsolePlugin.self, CAPWebViewPlugin.self, CAPCookiesPlugin.self]
305
+ var pluginList: [AnyClass] = [CAPHttpPlugin.self, CAPConsolePlugin.self, CAPWebViewPlugin.self, CAPCookiesPlugin.self, CAPSystemBarsPlugin.self]
306
306
 
307
307
  if autoRegisterPlugins {
308
308
  do {
@@ -0,0 +1,133 @@
1
+ import Foundation
2
+
3
+ @objc(CAPSystemBarsPlugin)
4
+ public class CAPSystemBarsPlugin: CAPPlugin, CAPBridgedPlugin {
5
+ public let identifier = "CAPSystemBarsPlugin"
6
+ public let jsName = "SystemBars"
7
+ public let pluginMethods: [CAPPluginMethod] = [
8
+ CAPPluginMethod(name: "setStyle", returnType: CAPPluginReturnPromise),
9
+ CAPPluginMethod(name: "setAnimation", returnType: CAPPluginReturnPromise),
10
+ CAPPluginMethod(name: "show", returnType: CAPPluginReturnPromise),
11
+ CAPPluginMethod(name: "hide", returnType: CAPPluginReturnPromise)
12
+ ]
13
+
14
+ public private(set) var hideHomeIndicator: Bool = false
15
+
16
+ enum Style: String {
17
+ case dark = "DARK"
18
+ case light = "LIGHT"
19
+ case defaultStyle = "DEFAULT"
20
+ }
21
+
22
+ @objc override public func load() {
23
+ let hidden = getConfig().getBoolean("hidden", false)
24
+
25
+ if let style = getConfig().getString("style", "DEFAULT") {
26
+ setStyle(style: style)
27
+ }
28
+
29
+ if let animation = getConfig().getString("animation") {
30
+ setAnimation(animation: animation)
31
+ }
32
+
33
+ setHidden(hidden: hidden)
34
+ }
35
+
36
+ @objc func setStyle(_ call: CAPPluginCall) {
37
+ setStyle(style: call.getString("style") ?? Style.defaultStyle.rawValue)
38
+ call.resolve()
39
+ }
40
+
41
+ @objc func show(_ call: CAPPluginCall) {
42
+ let bar = call.getString("bar")
43
+
44
+ if let animation = call.getString("animation") {
45
+ setAnimation(animation: animation)
46
+ }
47
+
48
+ DispatchQueue.main.async {
49
+ self.setHidden(hidden: false, bar: bar)
50
+ call.resolve()
51
+ }
52
+ }
53
+
54
+ @objc func hide(_ call: CAPPluginCall) {
55
+ let bar = call.getString("bar")
56
+
57
+ if let animation = call.getString("animation") {
58
+ setAnimation(animation: animation)
59
+ }
60
+
61
+ DispatchQueue.main.async {
62
+ self.setHidden(hidden: true, bar: bar)
63
+ call.resolve()
64
+ }
65
+ }
66
+
67
+ @objc func setAnimation(_ call: CAPPluginCall) {
68
+ let animation = call.getString("animation", "FADE")
69
+ setAnimation(animation: animation)
70
+
71
+ call.resolve()
72
+ }
73
+
74
+ func setStyle(style: String) {
75
+ var newStyle: UIStatusBarStyle = .default
76
+
77
+ if let style = Style(rawValue: style.uppercased()) {
78
+ switch style {
79
+ case .dark:
80
+ newStyle = .lightContent
81
+ case .light:
82
+ newStyle = .darkContent
83
+ case .defaultStyle:
84
+ newStyle = .default
85
+ }
86
+ }
87
+
88
+ bridge?.statusBarStyle = newStyle
89
+ }
90
+
91
+ func setHidden(hidden: Bool, bar: String? = nil) {
92
+ if hidden {
93
+ if bar == nil || bar?.isEmpty ?? true || bar == "StatusBar" {
94
+ bridge?.statusBarVisible = false
95
+ }
96
+
97
+ if bar == nil || bar?.isEmpty ?? true || bar == "NavigationBar" {
98
+ hideHomeIndicator = true
99
+ bridge?.viewController?.setNeedsUpdateOfHomeIndicatorAutoHidden()
100
+ }
101
+
102
+ return
103
+ }
104
+
105
+ if bar == nil || bar?.isEmpty ?? true || bar == "StatusBar" {
106
+ bridge?.statusBarVisible = true
107
+ }
108
+
109
+ if bar == nil || bar?.isEmpty ?? true || bar == "NavigationBar" {
110
+ hideHomeIndicator = false
111
+ bridge?.viewController?.setNeedsUpdateOfHomeIndicatorAutoHidden()
112
+ }
113
+
114
+ }
115
+
116
+ func setAnimation(animation: String) {
117
+ if animation.uppercased() == "NONE" {
118
+ bridge?.statusBarAnimation = .none
119
+ } else {
120
+ bridge?.statusBarAnimation = .fade
121
+ }
122
+ }
123
+ }
124
+
125
+ extension CAPBridgeViewController {
126
+ override public var prefersHomeIndicatorAutoHidden: Bool {
127
+ if let systemBarPlugin = self.bridge?.plugin(withName: "SystemBars") as? CAPSystemBarsPlugin {
128
+ return systemBarPlugin.hideHomeIndicator
129
+ }
130
+
131
+ return false
132
+ }
133
+ }
@@ -62,7 +62,6 @@ internal extension WKWebView {
62
62
  method_setImplementation(method, imp)
63
63
  }
64
64
 
65
- // iOS 13+
66
65
  let selectorMkIV: Selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:")
67
66
 
68
67
  if let method = class_getInstanceMethod(targetClass, selectorMkIV) {
@@ -1,5 +1,5 @@
1
1
  import Foundation
2
- import MobileCoreServices
2
+ import UniformTypeIdentifiers
3
3
 
4
4
  @objc(CAPWebViewAssetHandler)
5
5
  // swiftlint:disable type_body_length
@@ -106,12 +106,12 @@ open class WebViewAssetHandler: NSObject, WKURLSchemeHandler {
106
106
 
107
107
  open func mimeTypeForExtension(pathExtension: String) -> String {
108
108
  if !pathExtension.isEmpty {
109
- if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as NSString, nil)?.takeRetainedValue() {
110
- if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
111
- return mimetype as String
109
+ if let uti = UTType(filenameExtension: pathExtension) {
110
+ if let mimetype = uti.preferredMIMEType {
111
+ return mimetype
112
112
  }
113
113
  }
114
- // TODO: Remove in the future if Apple fixes the issue
114
+ // TODO: Remove when deployment target is set to iOS 17
115
115
  if let mimeType = mimeTypes[pathExtension] {
116
116
  return mimeType
117
117
  }
@@ -47,7 +47,6 @@ open class WebViewDelegationHandler: NSObject, WKNavigationDelegate, WKUIDelegat
47
47
  bridge?.reset()
48
48
  }
49
49
 
50
- @available(iOS 15, *)
51
50
  open func webView(
52
51
  _ webView: WKWebView,
53
52
  requestMediaCapturePermissionFor origin: WKSecurityOrigin,
@@ -58,7 +57,6 @@ open class WebViewDelegationHandler: NSObject, WKNavigationDelegate, WKUIDelegat
58
57
  decisionHandler(.grant)
59
58
  }
60
59
 
61
- @available(iOS 15, *)
62
60
  open func webView(_ webView: WKWebView,
63
61
  requestDeviceOrientationAndMotionPermissionFor origin: WKSecurityOrigin,
64
62
  initiatedByFrame frame: WKFrameInfo,
@@ -159,9 +157,30 @@ open class WebViewDelegationHandler: NSObject, WKNavigationDelegate, WKUIDelegat
159
157
 
160
158
  open func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
161
159
  CAPLog.print("⚡️ WebView process terminated")
160
+ bridge?.reset()
162
161
  webView.reload()
163
162
  }
164
163
 
164
+ open func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping @MainActor (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
165
+ guard let bridge = bridge else {
166
+ completionHandler(.rejectProtectionSpace, nil)
167
+ return
168
+ }
169
+
170
+ for pluginObject in bridge.plugins {
171
+ let plugin = pluginObject.value
172
+ let selector = NSSelectorFromString("handleWKWebViewURLAuthenticationChallenge:completionHandler:")
173
+ if plugin.responds(to: selector) {
174
+ if plugin.handleWKWebViewURLAuthenticationChallenge(challenge, completionHandler: completionHandler) {
175
+ return
176
+ }
177
+ }
178
+ }
179
+
180
+ completionHandler(.rejectProtectionSpace, nil)
181
+ return
182
+ }
183
+
165
184
  // MARK: - WKScriptMessageHandler
166
185
 
167
186
  open func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
@@ -326,7 +326,7 @@ var nativeBridge = (function (exports) {
326
326
  c.error(result.error);
327
327
  }
328
328
  else {
329
- c.dir(result.data);
329
+ c.dir(JSON.stringify(result.data));
330
330
  }
331
331
  c.groupEnd();
332
332
  }
@@ -9,6 +9,7 @@ FOUNDATION_EXPORT const unsigned char CapacitorCordovaVersionString[];
9
9
  #import <Cordova/AppDelegate.h>
10
10
  #import <Cordova/CDV.h>
11
11
  #import <Cordova/CDVAvailability.h>
12
+ #import <Cordova/CDVAvailabilityDeprecated.h>
12
13
  #import <Cordova/CDVCommandDelegate.h>
13
14
  #import <Cordova/CDVCommandDelegateImpl.h>
14
15
  #import <Cordova/CDVConfigParser.h>
@@ -0,0 +1,21 @@
1
+ /*
2
+ Licensed to the Apache Software Foundation (ASF) under one
3
+ or more contributor license agreements. See the NOTICE file
4
+ distributed with this work for additional information
5
+ regarding copyright ownership. The ASF licenses this file
6
+ to you under the Apache License, Version 2.0 (the
7
+ "License"); you may not use this file except in compliance
8
+ with the License. You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing,
13
+ software distributed under the License is distributed on an
14
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ KIND, either express or implied. See the License for the
16
+ specific language governing permissions and limitations
17
+ under the License.
18
+ */
19
+
20
+ #define CDV_DEPRECATED(version, msg) __attribute__((deprecated("Deprecated in Cordova " #version ". " msg)))
21
+ #define CDV_DEPRECATED_WITH_REPLACEMENT(version, msg, repl) __attribute__((deprecated("Deprecated in Cordova " #version ". " msg, repl)))
@@ -24,12 +24,6 @@
24
24
  #import "CDVAvailability.h"
25
25
  #import <WebKit/WebKit.h>
26
26
 
27
- @interface UIView (org_apache_cordova_UIView_Extension)
28
-
29
- @property (nonatomic, weak) UIScrollView* scrollView;
30
-
31
- @end
32
-
33
27
  extern NSString* const CDVPageDidLoadNotification;
34
28
  extern NSString* const CDVPluginHandleOpenURLNotification;
35
29
  extern NSString* const CDVPluginHandleOpenURLWithAppSourceAndAnnotationNotification;
@@ -54,7 +48,7 @@ extern NSString* const CDVViewWillTransitionToSizeNotification;
54
48
  @interface CDVPlugin : NSObject {}
55
49
 
56
50
  - (instancetype)initWithWebViewEngine:(WKWebView *)theWebViewEngine;
57
- @property (nonatomic, weak) UIView* webView;
51
+ @property (nonatomic, weak) WKWebView* webView;
58
52
  @property (nonatomic, weak) WKWebView * webViewEngine;
59
53
  @property (nonatomic, strong) NSString * className;
60
54
 
@@ -18,24 +18,6 @@
18
18
  */
19
19
 
20
20
  #import "CDVPlugin.h"
21
- #include <objc/message.h>
22
-
23
- @implementation UIView (org_apache_cordova_UIView_Extension)
24
-
25
- @dynamic scrollView;
26
-
27
- - (UIScrollView*)scrollView
28
- {
29
- SEL scrollViewSelector = NSSelectorFromString(@"scrollView");
30
-
31
- if ([self respondsToSelector:scrollViewSelector]) {
32
- return ((id (*)(id, SEL))objc_msgSend)(self, scrollViewSelector);
33
- }
34
-
35
- return nil;
36
- }
37
-
38
- @end
39
21
 
40
22
  NSString* const CDVPageDidLoadNotification = @"CDVPageDidLoadNotification";
41
23
  NSString* const CDVPluginHandleOpenURLNotification = @"CDVPluginHandleOpenURLNotification";
@@ -18,7 +18,14 @@
18
18
  */
19
19
 
20
20
  #import <WebKit/WebKit.h>
21
+ #import <Cordova/CDVAvailabilityDeprecated.h>
21
22
 
23
+ /**
24
+ @Metadata {
25
+ @Available(Cordova, introduced: "6.2.0", deprecated: "8.0.0")
26
+ }
27
+ */
28
+ CDV_DEPRECATED(8.0.0, "WebKit WKProcessPool is deprecated in iOS")
22
29
  @interface CDVWebViewProcessPoolFactory : NSObject
23
30
  @property (nonatomic, retain) WKProcessPool* sharedPool;
24
31
 
@@ -21,6 +21,10 @@
21
21
  @import WebKit;
22
22
  #import <Cordova/CDVWebViewProcessPoolFactory.h>
23
23
 
24
+ #pragma clang diagnostic push
25
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
26
+ #pragma clang diagnostic ignored "-Wdeprecated-implementations"
27
+
24
28
  static CDVWebViewProcessPoolFactory *factory = nil;
25
29
 
26
30
  @implementation CDVWebViewProcessPoolFactory
@@ -47,3 +51,5 @@ static CDVWebViewProcessPoolFactory *factory = nil;
47
51
  return _sharedPool;
48
52
  }
49
53
  @end
54
+
55
+ #pragma clang diagnostic pop
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/ios",
3
- "version": "8.0.0-alpha.2",
3
+ "version": "8.0.0-beta.0",
4
4
  "description": "Capacitor: Cross-platform apps with JavaScript and the web",
5
5
  "homepage": "https://capacitorjs.com",
6
6
  "author": "Ionic Team <hi@ionic.io> (https://ionic.io)",
@@ -21,11 +21,11 @@
21
21
  ],
22
22
  "scripts": {
23
23
  "verify": "npm run xc:build:Capacitor && npm run xc:build:CapacitorCordova",
24
- "xc:build:Capacitor": "cd Capacitor && xcodebuild clean test -workspace Capacitor.xcworkspace -scheme Capacitor -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.0' && cd ..",
24
+ "xc:build:Capacitor": "cd Capacitor && xcodebuild clean test -workspace Capacitor.xcworkspace -scheme Capacitor -destination 'platform=iOS Simulator,name=iPhone 16,OS=26.0.1' && cd ..",
25
25
  "xc:build:CapacitorCordova": "cd CapacitorCordova && xcodebuild && cd .."
26
26
  },
27
27
  "peerDependencies": {
28
- "@capacitor/core": "^8.0.0-alpha.2"
28
+ "@capacitor/core": "^8.0.0-beta.0"
29
29
  },
30
30
  "publishConfig": {
31
31
  "access": "public"