@capacitor/ios 2.2.1 → 2.4.2

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.
@@ -24,6 +24,13 @@ public class CAPBridgeViewController: UIViewController, CAPBridgeDelegate, WKScr
24
24
  private var basePath: String = ""
25
25
  private let assetsFolder = "public"
26
26
 
27
+ private enum WebViewLoadingState {
28
+ case unloaded
29
+ case initialLoad(isOpaque: Bool)
30
+ case subsequentLoad
31
+ }
32
+ private var webViewLoadingState = WebViewLoadingState.unloaded
33
+
27
34
  private var isStatusBarVisible = true
28
35
  private var statusBarStyle: UIStatusBarStyle = .default
29
36
  private var statusBarAnimation: UIStatusBarAnimation = .slide
@@ -97,7 +104,12 @@ public class CAPBridgeViewController: UIViewController, CAPBridgeDelegate, WKScr
97
104
  if let backgroundColor = (bridge!.config.getValue("ios.backgroundColor") as? String) ?? (bridge!.config.getValue("backgroundColor") as? String) {
98
105
  webView?.backgroundColor = UIColor(fromHex: backgroundColor)
99
106
  webView?.scrollView.backgroundColor = UIColor(fromHex: backgroundColor)
107
+ } else if #available(iOS 13, *) {
108
+ // Use the system background colors if background is not set by user
109
+ webView?.backgroundColor = UIColor.systemBackground
110
+ webView?.scrollView.backgroundColor = UIColor.systemBackground
100
111
  }
112
+
101
113
  if let overrideUserAgent = (bridge!.config.getValue("ios.overrideUserAgent") as? String) ?? (bridge!.config.getValue("overrideUserAgent") as? String) {
102
114
  webView?.customUserAgent = overrideUserAgent
103
115
  }
@@ -173,6 +185,16 @@ public class CAPBridgeViewController: UIViewController, CAPBridgeDelegate, WKScr
173
185
  }
174
186
 
175
187
  func loadWebView() {
188
+ // Set the webview to be not opaque on the inital load. This prevents
189
+ // the webview from showing a white background, which is its default
190
+ // loading display, as that can appear as a screen flash. This might
191
+ // have already been set by something else, like a plugin, so we want
192
+ // to save the current value to reset it on success or failure.
193
+ if let webView = webView, case .unloaded = webViewLoadingState {
194
+ webViewLoadingState = .initialLoad(isOpaque: webView.isOpaque)
195
+ webView.isOpaque = false
196
+ }
197
+
176
198
  let fullStartPath = URL(fileURLWithPath: assetsFolder).appendingPathComponent(startDir).appendingPathComponent("index")
177
199
  if Bundle.main.path(forResource: fullStartPath.relativePath, ofType: "html") == nil {
178
200
  fatalLoadError()
@@ -289,7 +311,9 @@ public class CAPBridgeViewController: UIViewController, CAPBridgeDelegate, WKScr
289
311
  }
290
312
 
291
313
  if navUrl.absoluteString.range(of: hostname!) == nil && (navigationAction.targetFrame == nil || (navigationAction.targetFrame?.isMainFrame)!) {
292
- UIApplication.shared.open(navUrl, options: [:], completionHandler: nil)
314
+ if UIApplication.shared.applicationState == .active {
315
+ UIApplication.shared.open(navUrl, options: [:], completionHandler: nil)
316
+ }
293
317
  decisionHandler(.cancel)
294
318
  return
295
319
  }
@@ -298,10 +322,18 @@ public class CAPBridgeViewController: UIViewController, CAPBridgeDelegate, WKScr
298
322
  }
299
323
 
300
324
  public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
325
+ if case .initialLoad(let isOpaque) = webViewLoadingState {
326
+ webView.isOpaque = isOpaque
327
+ webViewLoadingState = .subsequentLoad
328
+ }
301
329
  CAPLog.print("⚡️ WebView loaded")
302
330
  }
303
331
 
304
332
  public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
333
+ if case .initialLoad(let isOpaque) = webViewLoadingState {
334
+ webView.isOpaque = isOpaque
335
+ webViewLoadingState = .subsequentLoad
336
+ }
305
337
  CAPLog.print("⚡️ WebView failed to load")
306
338
  CAPLog.print("⚡️ Error: " + error.localizedDescription)
307
339
  }
@@ -99,10 +99,13 @@
99
99
  }
100
100
  return;
101
101
  }
102
-
103
- for(CAPPluginCall *call in listenersForEvent) {
104
- CAPPluginCallResult *result = [[CAPPluginCallResult alloc] init:data];
105
- call.successHandler(result, call);
102
+
103
+ for (int i=0; i < listenersForEvent.count; i++) {
104
+ CAPPluginCall *call = listenersForEvent[i];
105
+ if (call != nil) {
106
+ CAPPluginCallResult *result = [[CAPPluginCallResult alloc] init:data];
107
+ call.successHandler(result, call);
108
+ }
106
109
  }
107
110
  }
108
111
 
@@ -29,6 +29,7 @@ struct CameraSettings {
29
29
  var height: Float = 0
30
30
  var resultType = "base64"
31
31
  var saveToGallery = false
32
+ var preserveAspectRatio = false
32
33
  }
33
34
 
34
35
  @objc(CAPCameraPlugin)
@@ -72,7 +73,8 @@ public class CAPCameraPlugin : CAPPlugin, UIImagePickerControllerDelegate, UINav
72
73
  settings.direction = CameraDirection(rawValue: call.getString("direction") ?? DEFAULT_DIRECTION.rawValue) ?? DEFAULT_DIRECTION
73
74
  settings.resultType = call.get("resultType", String.self, "base64")!
74
75
  settings.saveToGallery = call.get("saveToGallery", Bool.self, false)!
75
-
76
+ settings.preserveAspectRatio = call.get("preserveAspectRatio", Bool.self, false)!
77
+
76
78
  // Get the new image dimensions if provided
77
79
  settings.width = Float(call.get("width", Int.self, 0)!)
78
80
  settings.height = Float(call.get("height", Int.self, 0)!)
@@ -229,7 +231,7 @@ public class CAPCameraPlugin : CAPPlugin, UIImagePickerControllerDelegate, UINav
229
231
  }
230
232
 
231
233
  if settings.shouldResize {
232
- guard let convertedImage = resizeImage(image!) else {
234
+ guard let convertedImage = resizeImage(image!, settings.preserveAspectRatio) else {
233
235
  self.call?.error("Error resizing image")
234
236
  return
235
237
  }
@@ -312,7 +314,14 @@ public class CAPCameraPlugin : CAPPlugin, UIImagePickerControllerDelegate, UINav
312
314
  return meta
313
315
  }
314
316
 
315
- func resizeImage(_ image: UIImage) -> UIImage? {
317
+ func resizeImage(_ image: UIImage, _ preserveAspectRatio: Bool) -> UIImage? {
318
+ if preserveAspectRatio {
319
+ return resizeImagePreservingAspectRatio(image)
320
+ }
321
+ return resizeImageWithoutPreservingAspectRatio(image)
322
+ }
323
+
324
+ func resizeImageWithoutPreservingAspectRatio(_ image: UIImage) -> UIImage? {
316
325
  let isAspectScale = settings.width > 0 && settings.height == 0 || settings.height > 0 && settings.width == 0
317
326
  let aspect = Float(image.size.width / image.size.height);
318
327
 
@@ -333,6 +342,31 @@ public class CAPCameraPlugin : CAPPlugin, UIImagePickerControllerDelegate, UINav
333
342
  return scaledImage
334
343
  }
335
344
 
345
+ func resizeImagePreservingAspectRatio(_ image: UIImage) -> UIImage? {
346
+ let imageHeight = Float(image.size.height)
347
+ let imageWidth = Float(image.size.width)
348
+
349
+ // 0 is treated as 'no restriction'
350
+ let maxHeight = settings.height == 0 ? imageHeight : settings.height
351
+ let maxWidth = settings.width == 0 ? imageWidth : settings.width
352
+
353
+ // resize with preserved aspect ratio
354
+ var newWidth = min(imageWidth, maxWidth)
355
+ var newHeight = (imageHeight * newWidth) / imageWidth
356
+ if newHeight > maxHeight {
357
+ newWidth = (imageWidth * maxHeight) / imageHeight
358
+ newHeight = maxHeight
359
+ }
360
+ let size = CGSize.init(width: Int(newWidth), height: Int(newHeight))
361
+
362
+ UIGraphicsBeginImageContextWithOptions(size, false, 1.0)
363
+ image.draw(in: CGRect(origin: CGPoint.zero, size: size))
364
+
365
+ let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
366
+ UIGraphicsEndImageContext()
367
+ return scaledImage
368
+ }
369
+
336
370
  func makeExif(_ exif: [AnyHashable:Any]?) -> [AnyHashable:Any]? {
337
371
  return exif?["{Exif}"] as? [AnyHashable:Any]
338
372
  }
@@ -26,6 +26,8 @@ public class CAPDevicePlugin: CAPPlugin {
26
26
  "osVersion": UIDevice.current.systemVersion,
27
27
  "appVersion": Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "",
28
28
  "appBuild": Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "",
29
+ "appId": Bundle.main.infoDictionary?["CFBundleIdentifier"] as? String ?? "",
30
+ "appName": Bundle.main.infoDictionary?["CFBundleDisplayName"] as? String ?? "",
29
31
  "platform": "ios",
30
32
  "manufacturer": "Apple",
31
33
  "uuid": UIDevice.current.identifierForVendor!.uuidString,
@@ -0,0 +1,39 @@
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
+ #import <UIKit/UIKit.h>
21
+ #import "CDVPlugin.h"
22
+
23
+ @interface CDVPlugin (CDVPluginResources)
24
+
25
+ /*
26
+ This will return the localized string for a key in a .bundle that is named the same as your class
27
+ For example, if your plugin class was called Foo, and you have a Spanish localized strings file, it will
28
+ try to load the desired key from Foo.bundle/es.lproj/Localizable.strings
29
+ */
30
+ - (NSString*)pluginLocalizedString:(NSString*)key;
31
+
32
+ /*
33
+ This will return the image for a name in a .bundle that is named the same as your class
34
+ For example, if your plugin class was called Foo, and you have an image called "bar",
35
+ it will try to load the image from Foo.bundle/bar.png (and appropriately named retina versions)
36
+ */
37
+ - (UIImage*)pluginImageResource:(NSString*)name;
38
+
39
+ @end
@@ -0,0 +1,38 @@
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
+ #import "CDVPlugin+Resources.h"
21
+
22
+ @implementation CDVPlugin (CDVPluginResources)
23
+
24
+ - (NSString*)pluginLocalizedString:(NSString*)key
25
+ {
26
+ NSBundle* bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:NSStringFromClass([self class]) ofType:@"bundle"]];
27
+
28
+ return [bundle localizedStringForKey:(key) value:nil table:nil];
29
+ }
30
+
31
+ - (UIImage*)pluginImageResource:(NSString*)name
32
+ {
33
+ NSString* resourceIdentifier = [NSString stringWithFormat:@"%@.bundle/%@", NSStringFromClass([self class]), name];
34
+
35
+ return [UIImage imageNamed:resourceIdentifier];
36
+ }
37
+
38
+ @end
@@ -25,6 +25,8 @@
25
25
  2F856C00203DEB320047344A /* CDVViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F856BFE203DEB320047344A /* CDVViewController.m */; };
26
26
  2F8AC283217F3A20008C2C33 /* CDVURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F8AC281217F3A20008C2C33 /* CDVURLProtocol.m */; };
27
27
  2F8AC284217F3A20008C2C33 /* CDVURLProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 2F8AC282217F3A20008C2C33 /* CDVURLProtocol.h */; };
28
+ 2F92AB5224D9ABA000954A4A /* CDVPlugin+Resources.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F92AB5024D9ABA000954A4A /* CDVPlugin+Resources.m */; };
29
+ 2F92AB5324D9ABA000954A4A /* CDVPlugin+Resources.h in Headers */ = {isa = PBXBuildFile; fileRef = 2F92AB5124D9ABA000954A4A /* CDVPlugin+Resources.h */; };
28
30
  2FAD9772203C77B9000D30F8 /* CDVConfigParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 2FAD9770203C77B8000D30F8 /* CDVConfigParser.h */; };
29
31
  2FAD9773203C77B9000D30F8 /* CDVConfigParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FAD9771203C77B9000D30F8 /* CDVConfigParser.m */; };
30
32
  2FE19E2A20473160002A4E89 /* AppDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2FE19E2820473160002A4E89 /* AppDelegate.h */; };
@@ -52,6 +54,8 @@
52
54
  2F856BFE203DEB320047344A /* CDVViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDVViewController.m; sourceTree = "<group>"; };
53
55
  2F8AC281217F3A20008C2C33 /* CDVURLProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDVURLProtocol.m; sourceTree = "<group>"; };
54
56
  2F8AC282217F3A20008C2C33 /* CDVURLProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDVURLProtocol.h; sourceTree = "<group>"; };
57
+ 2F92AB5024D9ABA000954A4A /* CDVPlugin+Resources.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CDVPlugin+Resources.m"; sourceTree = "<group>"; };
58
+ 2F92AB5124D9ABA000954A4A /* CDVPlugin+Resources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CDVPlugin+Resources.h"; sourceTree = "<group>"; };
55
59
  2FAD9770203C77B8000D30F8 /* CDVConfigParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDVConfigParser.h; sourceTree = "<group>"; };
56
60
  2FAD9771203C77B9000D30F8 /* CDVConfigParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDVConfigParser.m; sourceTree = "<group>"; };
57
61
  2FE19E2820473160002A4E89 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
@@ -106,6 +110,8 @@
106
110
  2F5C86E81FE94861004B09C7 /* Public */ = {
107
111
  isa = PBXGroup;
108
112
  children = (
113
+ 2F92AB5124D9ABA000954A4A /* CDVPlugin+Resources.h */,
114
+ 2F92AB5024D9ABA000954A4A /* CDVPlugin+Resources.m */,
109
115
  2F8AC282217F3A20008C2C33 /* CDVURLProtocol.h */,
110
116
  2F8AC281217F3A20008C2C33 /* CDVURLProtocol.m */,
111
117
  2F4F657B2091F1FD00EAA994 /* NSDictionary+CordovaPreferences.h */,
@@ -147,6 +153,7 @@
147
153
  2F5C87271FE98418004B09C7 /* CDVPlugin.h in Headers */,
148
154
  2F856BFF203DEB320047344A /* CDVViewController.h in Headers */,
149
155
  2F5C87231FE98418004B09C7 /* CDVCommandDelegateImpl.h in Headers */,
156
+ 2F92AB5324D9ABA000954A4A /* CDVPlugin+Resources.h in Headers */,
150
157
  2F8AC284217F3A20008C2C33 /* CDVURLProtocol.h in Headers */,
151
158
  2F5C87241FE98418004B09C7 /* CDVInvokedUrlCommand.h in Headers */,
152
159
  2FE19E2A20473160002A4E89 /* AppDelegate.h in Headers */,
@@ -226,6 +233,7 @@
226
233
  2F5C871D1FE98418004B09C7 /* CDVPluginResult.m in Sources */,
227
234
  2F4F657C2091F1FD00EAA994 /* NSDictionary+CordovaPreferences.m in Sources */,
228
235
  2F5C87211FE98418004B09C7 /* CDVPlugin.m in Sources */,
236
+ 2F92AB5224D9ABA000954A4A /* CDVPlugin+Resources.m in Sources */,
229
237
  2FAD9773203C77B9000D30F8 /* CDVConfigParser.m in Sources */,
230
238
  2F856C00203DEB320047344A /* CDVViewController.m in Sources */,
231
239
  2F5C87201FE98418004B09C7 /* CDVInvokedUrlCommand.m in Sources */,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/ios",
3
- "version": "2.2.1",
3
+ "version": "2.4.2",
4
4
  "description": "Capacitor: cross-platform mobile apps with the web",
5
5
  "homepage": "https://capacitor.ionicframework.com/",
6
6
  "author": "Ionic Team <hi@ionic.io> (https://ionicframework.com) ",
@@ -16,6 +16,6 @@
16
16
  "access": "public"
17
17
  },
18
18
  "peerDependencies": {
19
- "@capacitor/core": "~2.2.0"
19
+ "@capacitor/core": "~2.4.0"
20
20
  }
21
21
  }