@capacitor/ios 3.6.0 → 4.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,24 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [4.0.0-beta.0](https://github.com/ionic-team/capacitor/compare/3.6.0...4.0.0-beta.0) (2022-06-17)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **ios:** make removeAllListeners return a promise ([#5526](https://github.com/ionic-team/capacitor/issues/5526)) ([815f71b](https://github.com/ionic-team/capacitor/commit/815f71b6b62f6c4d5f66e6a36c190bb00a96fdcc))
12
+
13
+
14
+ ### Features
15
+
16
+ * **ios:** add getConfig to CAPPlugin ([#5495](https://github.com/ionic-team/capacitor/issues/5495)) ([224a9d0](https://github.com/ionic-team/capacitor/commit/224a9d075629d9c9da9ddc658eb282617fc46d09))
17
+ * **ios:** Add preferredContentMode configuration option ([#5583](https://github.com/ionic-team/capacitor/issues/5583)) ([5b6dfa3](https://github.com/ionic-team/capacitor/commit/5b6dfa3fe29c85632546b299f03cc04a77cf7475))
18
+ * **ios:** Support of range requests on WebViewAssetHandler ([#5659](https://github.com/ionic-team/capacitor/issues/5659)) ([348c08d](https://github.com/ionic-team/capacitor/commit/348c08d511e9d57a1b2ecedc3290c65fa9ba3924))
19
+
20
+
21
+
22
+
23
+
6
24
  # [3.6.0](https://github.com/ionic-team/capacitor/compare/3.5.1...3.6.0) (2022-06-17)
7
25
 
8
26
 
@@ -19,6 +37,24 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
19
37
 
20
38
 
21
39
 
40
+ # [4.0.0-alpha.2](https://github.com/ionic-team/capacitor/compare/3.4.1...4.0.0-alpha.2) (2022-05-12)
41
+
42
+
43
+ ### Bug Fixes
44
+
45
+ * **ios:** make removeAllListeners return a promise ([#5526](https://github.com/ionic-team/capacitor/issues/5526)) ([815f71b](https://github.com/ionic-team/capacitor/commit/815f71b6b62f6c4d5f66e6a36c190bb00a96fdcc))
46
+
47
+
48
+ ### Features
49
+
50
+ * **ios:** add getConfig to CAPPlugin ([#5495](https://github.com/ionic-team/capacitor/issues/5495)) ([224a9d0](https://github.com/ionic-team/capacitor/commit/224a9d075629d9c9da9ddc658eb282617fc46d09))
51
+ * **ios:** Add preferredContentMode configuration option ([#5583](https://github.com/ionic-team/capacitor/issues/5583)) ([5b6dfa3](https://github.com/ionic-team/capacitor/commit/5b6dfa3fe29c85632546b299f03cc04a77cf7475))
52
+
53
+
54
+
55
+
56
+
57
+
22
58
  ## [3.5.1](https://github.com/ionic-team/capacitor/compare/3.5.0...3.5.1) (2022-05-04)
23
59
 
24
60
  **Note:** Version bump only for package @capacitor/ios
@@ -38,6 +74,17 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
38
74
 
39
75
 
40
76
 
77
+ # [4.0.0-alpha.1](https://github.com/ionic-team/capacitor/compare/3.4.1...4.0.0-alpha.1) (2022-03-25)
78
+
79
+
80
+ ### Features
81
+
82
+ * **ios:** add getConfig to CAPPlugin ([#5495](https://github.com/ionic-team/capacitor/issues/5495)) ([224a9d0](https://github.com/ionic-team/capacitor/commit/224a9d075629d9c9da9ddc658eb282617fc46d09))
83
+
84
+
85
+
86
+
87
+
41
88
  ## [3.4.3](https://github.com/ionic-team/capacitor/compare/3.4.2...3.4.3) (2022-03-04)
42
89
 
43
90
  **Note:** Version bump only for package @capacitor/ios
@@ -53,7 +100,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
53
100
 
54
101
 
55
102
 
56
-
57
103
  ## [3.4.1](https://github.com/ionic-team/capacitor/compare/3.4.0...3.4.1) (2022-02-09)
58
104
 
59
105
 
@@ -119,6 +119,15 @@ import Cordova
119
119
  webViewConfiguration.applicationNameForUserAgent = appendUserAgent
120
120
  }
121
121
  }
122
+ if let preferredContentMode = instanceConfiguration.preferredContentMode {
123
+ var mode = WKWebpagePreferences.ContentMode.recommended
124
+ if preferredContentMode == "mobile" {
125
+ mode = WKWebpagePreferences.ContentMode.mobile
126
+ } else if preferredContentMode == "desktop" {
127
+ mode = WKWebpagePreferences.ContentMode.desktop
128
+ }
129
+ webViewConfiguration.defaultWebpagePreferences.preferredContentMode = mode
130
+ }
122
131
  return webViewConfiguration
123
132
  }
124
133
 
@@ -23,6 +23,7 @@ NS_SWIFT_NAME(InstanceConfiguration)
23
23
  @property (nonatomic, readonly, nonnull) NSURL *appLocation;
24
24
  @property (nonatomic, readonly, nullable) NSString *appStartPath;
25
25
  @property (nonatomic, readonly) BOOL limitsNavigationsToAppBoundDomains;
26
+ @property (nonatomic, readonly, nullable) NSString *preferredContentMode;
26
27
 
27
28
  @property (nonatomic, readonly, nonnull) NSDictionary *legacyConfig DEPRECATED_MSG_ATTRIBUTE("Use direct properties instead");
28
29
 
@@ -35,6 +35,7 @@
35
35
  _appLocation = descriptor.appLocation;
36
36
  _appStartPath = descriptor.appStartPath;
37
37
  _limitsNavigationsToAppBoundDomains = descriptor.limitsNavigationsToAppBoundDomains;
38
+ _preferredContentMode = descriptor.preferredContentMode;
38
39
  _pluginConfigurations = descriptor.pluginConfigurations;
39
40
  _legacyConfig = descriptor.legacyConfig;
40
41
  // construct the necessary URLs
@@ -15,10 +15,18 @@ extension InstanceConfiguration {
15
15
  return serverURL
16
16
  }
17
17
 
18
+ @available(*, deprecated, message: "Use getPluginConfig")
18
19
  @objc public func getPluginConfigValue(_ pluginId: String, _ configKey: String) -> Any? {
19
20
  return (pluginConfigurations as? JSObject)?[keyPath: KeyPath("\(pluginId).\(configKey)")]
20
21
  }
21
22
 
23
+ @objc public func getPluginConfig(_ pluginId: String) -> PluginConfig {
24
+ if let cfg = (pluginConfigurations as? JSObject)?[keyPath: KeyPath("\(pluginId)")] as? JSObject {
25
+ return PluginConfig(config: cfg)
26
+ }
27
+ return PluginConfig(config: JSObject())
28
+ }
29
+
22
30
  @objc public func shouldAllowNavigation(to host: String) -> Bool {
23
31
  for hostname in allowedNavigationHostnames {
24
32
  if doesHost(host, match: hostname) {
@@ -108,6 +108,11 @@ NS_SWIFT_NAME(InstanceDescriptor)
108
108
  @discussion Defaults to @c false. Set by @c ios.limitsNavigationsToAppBoundDomains in the configuration file. Required to be @c true for plugins to work if the app includes @c WKAppBoundDomains in the Info.plist.
109
109
  */
110
110
  @property (nonatomic, assign) BOOL limitsNavigationsToAppBoundDomains;
111
+ /**
112
+ @brief The content mode for the web view to use when it loads and renders web content.
113
+ @discussion Defaults to @c recommended. Set by @c ios.preferredContentMode in the configuration file.
114
+ */
115
+ @property (nonatomic, copy, nullable) NSString *preferredContentMode;
111
116
  /**
112
117
  @brief The parser used to load the cofiguration for Cordova plugins.
113
118
  */
@@ -125,6 +125,9 @@ internal extension InstanceDescriptor {
125
125
  if let limitsNavigations = config[keyPath: "ios.limitsNavigationsToAppBoundDomains"] as? Bool {
126
126
  limitsNavigationsToAppBoundDomains = limitsNavigations
127
127
  }
128
+ if let preferredMode = (config[keyPath: "ios.preferredContentMode"] as? String) {
129
+ preferredContentMode = preferredMode
130
+ }
128
131
  }
129
132
  }
130
133
  // swiftlint:enable cyclomatic_complexity
@@ -4,6 +4,8 @@
4
4
  @protocol CAPBridgeProtocol;
5
5
  @class CAPPluginCall;
6
6
 
7
+ @class PluginConfig;
8
+
7
9
  @interface CAPPlugin : NSObject
8
10
 
9
11
  @property (nonatomic, weak, nullable) WKWebView *webView;
@@ -44,8 +46,9 @@
44
46
  -(NSString* _Nonnull)getId;
45
47
  -(BOOL)getBool:(CAPPluginCall* _Nonnull) call field:(NSString* _Nonnull)field defaultValue:(BOOL)defaultValue DEPRECATED_MSG_ATTRIBUTE("Use accessors on CAPPluginCall instead. See CAPBridgedJSTypes.h for Obj-C implementations.");
46
48
  -(NSString* _Nullable)getString:(CAPPluginCall* _Nonnull)call field:(NSString* _Nonnull)field defaultValue:(NSString* _Nonnull)defaultValue DEPRECATED_MSG_ATTRIBUTE("Use accessors on CAPPluginCall instead. See CAPBridgedJSTypes.h for Obj-C implementations.");
47
- -(id _Nullable)getConfigValue:(NSString* _Nonnull)key;
49
+ -(id _Nullable)getConfigValue:(NSString* _Nonnull)key __deprecated_msg("use getConfig() and access config values using the methods available depending on the type.");
50
+ -(PluginConfig* _Nonnull)getConfig;
48
51
  -(void)setCenteredPopover:(UIViewController* _Nonnull)vc;
49
- -(BOOL)supportsPopover;
52
+ -(BOOL)supportsPopover DEPRECATED_MSG_ATTRIBUTE("All iOS 13+ devices support popover");
50
53
 
51
54
  @end
@@ -29,10 +29,14 @@
29
29
  return [call getString:field defaultValue:defaultValue];
30
30
  }
31
31
 
32
- -(id)getConfigValue:(NSString *)key {
32
+ -(id)getConfigValue:(NSString *)key __deprecated {
33
33
  return [self.bridge.config getPluginConfigValue:self.pluginName :key];
34
34
  }
35
35
 
36
+ -(PluginConfig*)getConfig {
37
+ return [self.bridge.config getPluginConfig:self.pluginName];
38
+ }
39
+
36
40
  -(void)load {}
37
41
 
38
42
  - (void)addEventListener:(NSString *)eventName listener:(CAPPluginCall *)listener {
@@ -105,6 +109,7 @@
105
109
 
106
110
  - (void)removeAllListeners:(CAPPluginCall *)call {
107
111
  [self.eventListeners removeAllObjects];
112
+ [call resolve];
108
113
  }
109
114
 
110
115
  - (NSArray<CAPPluginCall *>*)getListeners:(NSString *)eventName {
@@ -141,11 +146,7 @@
141
146
  }
142
147
 
143
148
  -(BOOL)supportsPopover {
144
- if (@available(iOS 13, *)) {
145
149
  return YES;
146
- } else {
147
- return UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
148
- }
149
150
  }
150
151
 
151
152
  - (NSNumber*)shouldOverrideLoad:(WKNavigationAction*)navigationAction {
@@ -97,7 +97,7 @@ internal class JSExport {
97
97
  let methods = [
98
98
  PluginHeaderMethod(name: "addListener", rtype: nil),
99
99
  PluginHeaderMethod(name: "removeListener", rtype: nil),
100
- PluginHeaderMethod(name: "removeAllListeners", rtype: nil),
100
+ PluginHeaderMethod(name: "removeAllListeners", rtype: "promise"),
101
101
  PluginHeaderMethod(name: "checkPermissions", rtype: "promise"),
102
102
  PluginHeaderMethod(name: "requestPermissions", rtype: "promise")
103
103
  ]
@@ -0,0 +1,56 @@
1
+ import Foundation
2
+
3
+ @objc public class PluginConfig: NSObject {
4
+
5
+ // The object containing the plugin config values
6
+ private var config: JSObject
7
+
8
+ init(config: JSObject) {
9
+ self.config = config
10
+ }
11
+
12
+ @objc public func getString(_ configKey: String, _ defaultValue: String? = nil) -> String? {
13
+ if let val = (self.config)[keyPath: KeyPath(configKey)] as? String {
14
+ return val
15
+ }
16
+ return defaultValue
17
+ }
18
+
19
+ @objc public func getBoolean(_ configKey: String, _ defaultValue: Bool) -> Bool {
20
+ if let val = (self.config)[keyPath: KeyPath(configKey)] as? Bool {
21
+ return val
22
+ }
23
+ return defaultValue
24
+ }
25
+
26
+ @objc public func getInt(_ configKey: String, _ defaultValue: Int) -> Int {
27
+ if let val = (self.config)[keyPath: KeyPath(configKey)] as? Int {
28
+ return val
29
+ }
30
+ return defaultValue
31
+ }
32
+
33
+ public func getArray(_ configKey: String, _ defaultValue: JSArray? = nil) -> JSArray? {
34
+ if let val = (self.config)[keyPath: KeyPath(configKey)] as? JSArray {
35
+ return val
36
+ }
37
+ return defaultValue
38
+ }
39
+
40
+ public func getObject(_ configKey: String) -> JSObject? {
41
+ return (self.config)[keyPath: KeyPath(configKey)] as? JSObject
42
+ }
43
+
44
+ @objc public func isEmpty() -> Bool {
45
+ return self.config.isEmpty
46
+ }
47
+
48
+ /**
49
+ * Gets the JSObject containing the config of the the provided plugin ID.
50
+ *
51
+ * @return The config for that plugin
52
+ */
53
+ public func getConfigJSON() -> JSObject {
54
+ return self.config
55
+ }
56
+ }
@@ -26,14 +26,14 @@ public extension CapacitorExtensionTypeWrapper where T: UIColor {
26
26
  with: ""
27
27
  )
28
28
 
29
- var argb: UInt32 = 0
29
+ var argb: UInt64 = 0
30
30
 
31
31
  var red: CGFloat = 0.0
32
32
  var green: CGFloat = 0.0
33
33
  var blue: CGFloat = 0.0
34
34
  var alpha: CGFloat = 1.0
35
35
 
36
- guard Scanner(string: hexString).scanHexInt32(&argb) else { return nil }
36
+ guard Scanner(string: hexString).scanHexInt64(&argb) else { return nil }
37
37
 
38
38
  if hexString.count == 6 {
39
39
  red = CGFloat((argb & 0xFF0000) >> 16) / 255.0
@@ -30,25 +30,46 @@ internal class WebViewAssetHandler: NSObject, WKURLSchemeHandler {
30
30
 
31
31
  do {
32
32
  var data = Data()
33
- if !stringToLoad.contains("cordova.js") {
34
- if isMediaExtension(pathExtension: url.pathExtension) {
35
- data = try Data(contentsOf: fileUrl, options: Data.ReadingOptions.mappedIfSafe)
36
- } else {
37
- data = try Data(contentsOf: fileUrl)
38
- }
39
- }
40
33
  let mimeType = mimeTypeForExtension(pathExtension: url.pathExtension)
41
- let expectedContentLength = data.count
42
- let headers = [
34
+ var headers = [
43
35
  "Content-Type": mimeType,
44
36
  "Cache-Control": "no-cache"
45
37
  ]
46
- let urlResponse = URLResponse(url: localUrl, mimeType: mimeType, expectedContentLength: expectedContentLength, textEncodingName: nil)
47
- let httpResponse = HTTPURLResponse(url: localUrl, statusCode: 200, httpVersion: nil, headerFields: headers)
48
- if isMediaExtension(pathExtension: url.pathExtension) {
49
- urlSchemeTask.didReceive(urlResponse)
38
+ if let rangeString = urlSchemeTask.request.value(forHTTPHeaderField: "Range"),
39
+ let totalSize = try fileUrl.resourceValues(forKeys: [.fileSizeKey]).fileSize,
40
+ isMediaExtension(pathExtension: url.pathExtension) {
41
+ let fileHandle = try FileHandle(forReadingFrom: fileUrl)
42
+ let parts = rangeString.components(separatedBy: "=")
43
+ let streamParts = parts[1].components(separatedBy: "-")
44
+ let fromRange = Int(streamParts[0]) ?? 0
45
+ var toRange = totalSize - 1
46
+ if streamParts.count > 1 {
47
+ toRange = Int(streamParts[1]) ?? toRange
48
+ }
49
+ let rangeLength = toRange - fromRange + 1
50
+ try fileHandle.seek(toOffset: UInt64(fromRange))
51
+ data = fileHandle.readData(ofLength: rangeLength)
52
+ headers["Accept-Ranges"] = "bytes"
53
+ headers["Content-Range"] = "bytes \(fromRange)-\(toRange)/\(totalSize)"
54
+ headers["Content-Length"] = String(data.count)
55
+ let response = HTTPURLResponse(url: localUrl, statusCode: 206, httpVersion: nil, headerFields: headers)
56
+ urlSchemeTask.didReceive(response!)
57
+ try fileHandle.close()
50
58
  } else {
51
- urlSchemeTask.didReceive(httpResponse!)
59
+ if !stringToLoad.contains("cordova.js") {
60
+ if isMediaExtension(pathExtension: url.pathExtension) {
61
+ data = try Data(contentsOf: fileUrl, options: Data.ReadingOptions.mappedIfSafe)
62
+ } else {
63
+ data = try Data(contentsOf: fileUrl)
64
+ }
65
+ }
66
+ let urlResponse = URLResponse(url: localUrl, mimeType: mimeType, expectedContentLength: data.count, textEncodingName: nil)
67
+ let httpResponse = HTTPURLResponse(url: localUrl, statusCode: 200, httpVersion: nil, headerFields: headers)
68
+ if isMediaExtension(pathExtension: url.pathExtension) {
69
+ urlSchemeTask.didReceive(urlResponse)
70
+ } else {
71
+ urlSchemeTask.didReceive(httpResponse!)
72
+ }
52
73
  }
53
74
  urlSchemeTask.didReceive(data)
54
75
  } catch let error as NSError {
@@ -47,8 +47,6 @@ internal class WebViewDelegationHandler: NSObject, WKNavigationDelegate, WKUIDel
47
47
  bridge?.reset()
48
48
  }
49
49
 
50
- // TODO: remove once Xcode 12 support is dropped
51
- #if compiler(>=5.5)
52
50
  @available(iOS 15, *)
53
51
  func webView(
54
52
  _ webView: WKWebView,
@@ -67,7 +65,6 @@ internal class WebViewDelegationHandler: NSObject, WKNavigationDelegate, WKUIDel
67
65
  decisionHandler: @escaping (WKPermissionDecision) -> Void) {
68
66
  decisionHandler(.grant)
69
67
  }
70
- #endif
71
68
 
72
69
  public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
73
70
  // post a notification for any listeners
package/Capacitor.podspec CHANGED
@@ -7,7 +7,7 @@ Pod::Spec.new do |s|
7
7
  s.social_media_url = 'https://twitter.com/capacitorjs'
8
8
  s.license = 'MIT'
9
9
  s.homepage = 'https://capacitorjs.com/'
10
- s.ios.deployment_target = '12.0'
10
+ s.ios.deployment_target = '13.0'
11
11
  s.authors = { 'Ionic Team' => 'hi@ionicframework.com' }
12
12
  s.source = { :git => 'https://github.com/ionic-team/capacitor.git', :branch => "portals-dev" }
13
13
  s.source_files = 'Capacitor/Capacitor/*.{swift,h,m}', 'Capacitor/Capacitor/Plugins/*.{swift,h,m}', 'Capacitor/Capacitor/Plugins/**/*.{swift,h,m}'
@@ -9,7 +9,7 @@ Pod::Spec.new do |s|
9
9
  s.license = 'MIT'
10
10
  s.authors = { 'Ionic Team' => 'hi@ionicframework.com' }
11
11
  s.source = { :git => 'https://github.com/ionic-team/capacitor', :tag => s.version.to_s }
12
- s.platform = :ios, 12.0
12
+ s.platform = :ios, 13.0
13
13
  s.source_files = 'CapacitorCordova/CapacitorCordova/**/*.{h,m}'
14
14
  s.public_header_files = 'CapacitorCordova/CapacitorCordova/Classes/Public/*.h', 'CapacitorCordova/CapacitorCordova/CapacitorCordova.h'
15
15
  s.module_map = 'CapacitorCordova/CapacitorCordova/CapacitorCordova.modulemap'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/ios",
3
- "version": "3.6.0",
3
+ "version": "4.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)",
@@ -29,5 +29,5 @@
29
29
  "publishConfig": {
30
30
  "access": "public"
31
31
  },
32
- "gitHead": "1e06a199a44bb5321f0fb48b5fbca961cc1dbb50"
32
+ "gitHead": "d9e553f76fac74df6ab0f2bf5c3da18e51b2282b"
33
33
  }