@capacitor/camera 8.1.0-test.20260330 → 8.1.0-test.20260331

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.
@@ -9,10 +9,10 @@ Pod::Spec.new do |s|
9
9
  s.license = package['license']
10
10
  s.homepage = 'https://capacitorjs.com'
11
11
  s.author = package['author']
12
- s.source = { :git => 'https://github.com/ionic-team/capacitor-plugins.git', :tag => package['name'] + '@' + package['version'] }
13
- s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}', 'camera/ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
12
+ s.source = { :git => 'https://github.com/ionic-team/capacitor-camera.git', :tag => "v#{s.version}" }
13
+ s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}',
14
14
  s.ios.deployment_target = '15.0'
15
15
  s.dependency 'Capacitor'
16
- s.dependency 'IONCameraLib', spec='~> 1.0.0'
16
+ s.dependency 'IONCameraLib', spec='~> 0.1.0'
17
17
  s.swift_version = '5.1'
18
18
  end
@@ -89,5 +89,5 @@ dependencies {
89
89
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
90
90
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
91
91
  implementation 'com.google.code.gson:gson:2.10.1'
92
- implementation 'io.ionic.libs:ioncamera-android:0.1.0'
92
+ implementation 'io.ionic.libs:ioncamera-android:0.1.0@aar'
93
93
  }
@@ -731,18 +731,17 @@ class IonCameraFlow(
731
731
  ret.put("webPath", FileUtils.getPortablePath(context, bridge.localUrl, uri))
732
732
  ret.put("saved", mediaResult.saved)
733
733
 
734
- val metadata = JSObject()
735
734
  mediaResult.metadata?.let {
735
+ val metadata = JSObject()
736
736
  metadata.put("duration", it.duration)
737
737
  metadata.put("size", it.size)
738
738
  metadata.put("format", it.format)
739
739
  metadata.put("resolution", it.resolution)
740
740
  metadata.put("creationDate", it.creationDate)
741
741
  metadata.put("exif", exif.toJson())
742
+ ret.put("metadata", metadata)
742
743
  }
743
744
 
744
- ret.put("metadata", metadata)
745
-
746
745
  currentCall?.resolve(ret)
747
746
  currentCall = null
748
747
  lastEditUri = null
@@ -759,17 +758,16 @@ class IonCameraFlow(
759
758
  ret.put("webPath", FileUtils.getPortablePath(context, bridge.localUrl, uri))
760
759
  ret.put("saved", mediaResult.saved)
761
760
 
762
- val metadata = JSObject()
763
761
  mediaResult.metadata?.let {
762
+ val metadata = JSObject()
764
763
  metadata.put("duration", it.duration)
765
764
  metadata.put("size", it.size)
766
765
  metadata.put("format", it.format)
767
766
  metadata.put("resolution", it.resolution)
768
767
  metadata.put("creationDate", it.creationDate)
768
+ ret.put("metadata", metadata)
769
769
  }
770
770
 
771
- ret.put("metadata", metadata)
772
-
773
771
  currentCall?.resolve(ret)
774
772
  currentCall = null
775
773
  }
@@ -790,27 +788,27 @@ class IonCameraFlow(
790
788
  FileUtils.getPortablePath(context, bridge.localUrl, uri)
791
789
  )
792
790
 
793
- val metadata = JSObject()
794
791
  mediaResult.metadata?.let {
792
+ val metadata = JSObject()
795
793
  metadata.put("duration", it.duration)
796
794
  metadata.put("size", it.size)
797
795
  metadata.put("format", it.format)
798
796
  metadata.put("resolution", it.resolution)
799
797
  metadata.put("creationDate", it.creationDate)
800
- }
801
798
 
802
- if (mediaResult.type == IONCAMRMediaType.PICTURE.type) {
803
- val bitmap = BitmapFactory.decodeFile(mediaResult.uri)
804
- if (bitmap == null) {
805
- sendError(IONCAMRError.PROCESS_IMAGE_ERROR)
806
- return
799
+ if (mediaResult.type == IONCAMRMediaType.PICTURE.type) {
800
+ val bitmap = BitmapFactory.decodeFile(mediaResult.uri)
801
+ if (bitmap == null) {
802
+ sendError(IONCAMRError.PROCESS_IMAGE_ERROR)
803
+ return
804
+ }
805
+
806
+ val exif = ImageUtils.getExifData(context, bitmap, uri)
807
+ metadata.put("exif", exif.toJson())
807
808
  }
808
809
 
809
- val exif = ImageUtils.getExifData(context, bitmap, uri)
810
- metadata.put("exif", exif.toJson())
810
+ ret.put("metadata", metadata)
811
811
  }
812
-
813
- ret.put("metadata", metadata)
814
812
  photos.put(ret)
815
813
  }
816
814
 
@@ -3,6 +3,7 @@ import IONCameraLib
3
3
  import Capacitor
4
4
  import Photos
5
5
  import PhotosUI
6
+ import ImageIO
6
7
 
7
8
  @objc(CAPCameraPlugin)
8
9
  public class CameraPlugin: CAPPlugin, CAPBridgedPlugin {
@@ -27,14 +28,14 @@ public class CameraPlugin: CAPPlugin, CAPBridgedPlugin {
27
28
  private let defaultSource = CameraSource.prompt
28
29
  private let defaultDirection = CameraDirection.rear
29
30
  private var multiple = false
30
-
31
+
31
32
  private lazy var cameraManager = IONCAMRFactory.createCameraManagerWrapper(withDelegate: self, and: self.bridge?.viewController ?? UIViewController())
32
33
  private lazy var galleryManager = IONCAMRFactory.createGalleryManagerWrapper(withDelegate: self, and: self.bridge?.viewController ?? UIViewController())
33
34
  private lazy var editManager = IONCAMRFactory.createEditManagerWrapper(withDelegate: self, and: self.bridge?.viewController ?? UIViewController())
34
35
  private lazy var videoManager = IONCAMRFactory.createVideoManagerWrapper(withDelegate: self, and: self.bridge?.viewController ?? UIViewController())
35
36
 
36
37
  private var imageCounter = 0
37
-
38
+
38
39
  private func decodeParameters<T: Decodable>(from call: CAPPluginCall) -> T? {
39
40
  guard let dict = call.options as? [String: Any],
40
41
  let data = try? JSONSerialization.data(withJSONObject: dict)
@@ -64,31 +65,31 @@ public class CameraPlugin: CAPPlugin, CAPBridgedPlugin {
64
65
  self.cameraManager.takePhoto(with: options)
65
66
  }
66
67
  }
67
-
68
+
68
69
  @objc func chooseFromGallery(_ call: CAPPluginCall) {
69
70
  handleCall(call, error: .chooseMultimediaIssue) { (options: IONCAMRGalleryOptions) in
70
71
  self.galleryManager.chooseFromGallery(with: options)
71
72
  }
72
73
  }
73
-
74
+
74
75
  @objc func editURIPhoto(_ call: CAPPluginCall) {
75
76
  handleCall(call, error: .editPictureIssue) { (options: IONCAMRPhotoEditOptions) in
76
77
  self.editManager.editPhoto(with: options)
77
78
  }
78
79
  }
79
-
80
+
80
81
  @objc func editPhoto(_ call: CAPPluginCall) {
81
82
  handleCall(call, error: .editPictureIssue) { (options: IONCAMRPhotoEditOptions) in
82
83
  self.editManager.editPhoto(with: options)
83
84
  }
84
85
  }
85
-
86
+
86
87
  @objc func recordVideo(_ call: CAPPluginCall) {
87
88
  handleCall(call, error: .captureVideoIssue) { (options: IONCAMRRecordVideoOptions) in
88
89
  self.cameraManager.recordVideo(with: options)
89
90
  }
90
91
  }
91
-
92
+
92
93
  @objc func playVideo(_ call: CAPPluginCall) {
93
94
  handleCall(call, error: .playVideoIssue) { (options: IONCAMRPlayVideoOptions) in
94
95
  Task {
@@ -104,7 +105,6 @@ public class CameraPlugin: CAPPlugin, CAPBridgedPlugin {
104
105
  }
105
106
  }
106
107
 
107
-
108
108
  @objc override public func checkPermissions(_ call: CAPPluginCall) {
109
109
  var result: [String: Any] = [:]
110
110
  for permission in CameraPermissionType.allCases {
@@ -637,45 +637,32 @@ private extension CameraPlugin {
637
637
  }
638
638
 
639
639
  extension CameraPlugin: IONCAMRCallbackDelegate {
640
-
640
+
641
641
  public func callback(error: IONCAMRError) {
642
642
  sendError(error)
643
643
  }
644
-
644
+
645
645
  public func callback(result: IONCAMRMediaResult) {
646
646
  resolve(result)
647
647
  }
648
-
648
+
649
649
  public func callback(result: [IONCAMRMediaResult]) {
650
650
  resolve(["results": result])
651
651
  }
652
-
652
+
653
653
  private func resolve<T: Encodable>(_ value: T) {
654
654
  do {
655
- let data = try JSONEncoder().encode(value)
655
+ let encoder = JSONEncoder()
656
+ encoder.dateEncodingStrategy = .iso8601
657
+ let data = try encoder.encode(value)
656
658
  var json = try JSONSerialization.jsonObject(with: data)
657
659
 
658
- // Add webPath to results
659
660
  if var dict = json as? [String: Any] {
660
- // Handle single result
661
- if let uri = dict["uri"] as? String,
662
- let webPath = resolveWebPath(from: uri) {
663
- dict["webPath"] = webPath
661
+ if dict["uri"] != nil {
662
+ dict = resolveMediaResult(dict)
663
+ } else if let results = dict["results"] as? [[String: Any]] {
664
+ dict["results"] = results.map(resolveMediaResult)
664
665
  }
665
-
666
- // Handle array of results
667
- if var results = dict["results"] as? [[String: Any]] {
668
- results = results.map { item in
669
- var newItem = item
670
- if let uri = item["uri"] as? String,
671
- let webPath = resolveWebPath(from: uri) {
672
- newItem["webPath"] = webPath
673
- }
674
- return newItem
675
- }
676
- dict["results"] = results
677
- }
678
-
679
666
  json = dict
680
667
  }
681
668
 
@@ -687,6 +674,17 @@ extension CameraPlugin: IONCAMRCallbackDelegate {
687
674
  }
688
675
  }
689
676
 
677
+ private func resolveMediaResult(_ item: [String: Any]) -> [String: Any] {
678
+ guard let uri = item["uri"] as? String else { return item }
679
+ var result = item
680
+ result["webPath"] = resolveWebPath(from: uri)
681
+ if var metadata = result["metadata"] as? [String: Any] {
682
+ metadata["exif"] = resolveExif(from: uri)
683
+ result["metadata"] = metadata
684
+ }
685
+ return result
686
+ }
687
+
690
688
  private func resolveWebPath(from uri: String) -> String? {
691
689
  guard !uri.isEmpty,
692
690
  let fileURL = URL(string: uri),
@@ -695,4 +693,17 @@ extension CameraPlugin: IONCAMRCallbackDelegate {
695
693
  }
696
694
  return webURL.absoluteString
697
695
  }
696
+
697
+ private func resolveExif(from uri: String) -> [String: Any]? {
698
+ guard !uri.isEmpty,
699
+ let fileURL = URL(string: uri),
700
+ let imageSource = CGImageSourceCreateWithURL(fileURL as CFURL, nil),
701
+ let properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [String: Any] else {
702
+ return nil
703
+ }
704
+ var exif = properties[kCGImagePropertyExifDictionary as String] as? [String: Any] ?? [:]
705
+ exif["Orientation"] = properties[kCGImagePropertyOrientation as String]
706
+ exif["GPS"] = properties[kCGImagePropertyGPSDictionary as String]
707
+ return exif.isEmpty ? nil : exif
708
+ }
698
709
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/camera",
3
- "version": "8.1.0-test.20260330",
3
+ "version": "8.1.0-test.20260331",
4
4
  "description": "The Camera API provides the ability to take a photo with the camera or choose an existing one from the photo album.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -19,10 +19,10 @@
19
19
  "license": "MIT",
20
20
  "repository": {
21
21
  "type": "git",
22
- "url": "git+https://github.com/ionic-team/capacitor-plugins.git"
22
+ "url": "git+https://github.com/ionic-team/capacitor-camera.git"
23
23
  },
24
24
  "bugs": {
25
- "url": "https://github.com/ionic-team/capacitor-plugins/issues"
25
+ "url": "https://github.com/ionic-team/capacitor-camera/issues"
26
26
  },
27
27
  "keywords": [
28
28
  "capacitor",