capacitor-camera-module 0.0.63 → 0.0.65

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.
@@ -5,29 +5,26 @@ import UIKit
5
5
  import Photos
6
6
 
7
7
  @objc(CameraModule)
8
- public class CameraModulePlugin: CAPPlugin,CAPBridgedPlugin,AVCaptureVideoDataOutputSampleBufferDelegate {
9
-
10
-
11
- public let identifier = "CameraModule"
12
- public let jsName = "CameraModule"
13
- public let pluginMethods: [CAPPluginMethod] = [
14
- CAPPluginMethod(name: "checkPermission", returnType: CAPPluginReturnPromise),
15
- CAPPluginMethod(name: "requestPermission", returnType: CAPPluginReturnPromise),
16
- CAPPluginMethod(name: "checkGalleryPermission", returnType: CAPPluginReturnPromise),
17
- CAPPluginMethod(name: "requestGalleryPermission", returnType: CAPPluginReturnPromise),
18
- CAPPluginMethod(name: "checkAndRequestGalleryPermission", returnType: CAPPluginReturnPromise),
19
- CAPPluginMethod(name: "pickImageBase64", returnType: CAPPluginReturnPromise),
20
- CAPPluginMethod(name: "startPreview", returnType: CAPPluginReturnPromise),
21
- CAPPluginMethod(name: "stopPreview", returnType: CAPPluginReturnPromise),
22
- CAPPluginMethod(name: "toggleFlash", returnType: CAPPluginReturnPromise),
23
- CAPPluginMethod(name: "hasFlash", returnType: CAPPluginReturnPromise),
24
- CAPPluginMethod(name: "takePhotoBase64", returnType: CAPPluginReturnPromise),
25
- CAPPluginMethod(name: "startBarcodeScan", returnType: CAPPluginReturnPromise),
26
- CAPPluginMethod(name: "stopBarcodeScan", returnType: CAPPluginReturnPromise),
27
- CAPPluginMethod(name: "getLastGalleryImage", returnType: CAPPluginReturnPromise)
28
-
29
- ]
30
-
8
+ public class CameraModulePlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureVideoDataOutputSampleBufferDelegate {
9
+
10
+ public let identifier = "CameraModule"
11
+ public let jsName = "CameraModule"
12
+ public let pluginMethods: [CAPPluginMethod] = [
13
+ CAPPluginMethod(name: "checkPermission", returnType: CAPPluginReturnPromise),
14
+ CAPPluginMethod(name: "requestPermission", returnType: CAPPluginReturnPromise),
15
+ CAPPluginMethod(name: "checkGalleryPermission", returnType: CAPPluginReturnPromise),
16
+ CAPPluginMethod(name: "requestGalleryPermission", returnType: CAPPluginReturnPromise),
17
+ CAPPluginMethod(name: "checkAndRequestGalleryPermission", returnType: CAPPluginReturnPromise),
18
+ CAPPluginMethod(name: "pickImageBase64", returnType: CAPPluginReturnPromise),
19
+ CAPPluginMethod(name: "startPreview", returnType: CAPPluginReturnPromise),
20
+ CAPPluginMethod(name: "stopPreview", returnType: CAPPluginReturnPromise),
21
+ CAPPluginMethod(name: "toggleFlash", returnType: CAPPluginReturnPromise),
22
+ CAPPluginMethod(name: "hasFlash", returnType: CAPPluginReturnPromise),
23
+ CAPPluginMethod(name: "takePhotoBase64", returnType: CAPPluginReturnPromise),
24
+ CAPPluginMethod(name: "startBarcodeScan", returnType: CAPPluginReturnPromise),
25
+ CAPPluginMethod(name: "stopBarcodeScan", returnType: CAPPluginReturnPromise),
26
+ CAPPluginMethod(name: "getLastGalleryImage", returnType: CAPPluginReturnPromise)
27
+ ]
31
28
 
32
29
  private var previewView: UIView?
33
30
  private var captureSession: AVCaptureSession?
@@ -36,7 +33,6 @@ public class CameraModulePlugin: CAPPlugin,CAPBridgedPlugin,AVCaptureVideoDataOu
36
33
  private var photoDelegate: PhotoDelegate?
37
34
 
38
35
  // MARK: - Barcode
39
-
40
36
  private var isScanning = false
41
37
  private var scanCall: CAPPluginCall?
42
38
  private var barcodeRequest: VNDetectBarcodesRequest?
@@ -46,22 +42,14 @@ public class CameraModulePlugin: CAPPlugin,CAPBridgedPlugin,AVCaptureVideoDataOu
46
42
  private let scanDebounceInterval: TimeInterval = 0.5
47
43
 
48
44
  // MARK: - Gallery
49
-
50
45
  private var galleryCall: CAPPluginCall?
51
46
 
52
47
  // MARK: - Lifecycle
53
48
  public override func load() {
54
- guard let webView = bridge?.webView else { return }
55
-
56
- webView.isOpaque = true
57
- webView.backgroundColor = .black
58
- webView.scrollView.backgroundColor = .black
49
+ print("📱 CameraModulePlugin cargado")
59
50
  }
60
51
 
61
-
62
-
63
52
  // MARK: - Camera Permission
64
-
65
53
  @objc func checkPermission(_ call: CAPPluginCall) {
66
54
  let status = AVCaptureDevice.authorizationStatus(for: .video)
67
55
  call.resolve([
@@ -82,10 +70,8 @@ public class CameraModulePlugin: CAPPlugin,CAPBridgedPlugin,AVCaptureVideoDataOu
82
70
  }
83
71
 
84
72
  // MARK: - Gallery Permission
85
-
86
73
  @objc func checkGalleryPermission(_ call: CAPPluginCall) {
87
74
  let status = PHPhotoLibrary.authorizationStatus(for: .readWrite)
88
-
89
75
  switch status {
90
76
  case .authorized, .limited:
91
77
  call.resolve(["granted": true, "status": "granted"])
@@ -118,7 +104,6 @@ public class CameraModulePlugin: CAPPlugin,CAPBridgedPlugin,AVCaptureVideoDataOu
118
104
  }
119
105
 
120
106
  // MARK: - Pick Image
121
-
122
107
  @objc func pickImageBase64(_ call: CAPPluginCall) {
123
108
  let status = PHPhotoLibrary.authorizationStatus(for: .readWrite)
124
109
  guard status == .authorized || status == .limited else {
@@ -143,7 +128,6 @@ public class CameraModulePlugin: CAPPlugin,CAPBridgedPlugin,AVCaptureVideoDataOu
143
128
  }
144
129
 
145
130
  // MARK: - Camera Preview
146
-
147
131
  @objc func startPreview(_ call: CAPPluginCall) {
148
132
  DispatchQueue.main.async {
149
133
  if self.previewView != nil {
@@ -177,41 +161,42 @@ public class CameraModulePlugin: CAPPlugin,CAPBridgedPlugin,AVCaptureVideoDataOu
177
161
  return
178
162
  }
179
163
 
180
- // 1. Cambia isUserInteractionEnabled a true
181
- let previewView = UIView()
182
- previewView.translatesAutoresizingMaskIntoConstraints = false
183
- previewView.backgroundColor = .black
184
- previewView.isUserInteractionEnabled = true // CAMBIO IMPORTANTE
185
-
186
-
187
- previewView.backgroundColor = .red // Para ver si la vista se muestra
188
-
189
-
190
- // Agrega esto después de crear la vista
191
- print("PreviewView frame: \(previewView.frame)")
192
- print("Superview: \(previewView.superview)")
193
-
194
- guard let webView = self.bridge?.webView else {
164
+ guard let webView = self.bridge?.webView as? WKWebView else {
195
165
  call.reject("No webView")
196
166
  return
197
167
  }
198
168
 
199
- // 2. Inserta la previewView sobre el webView temporalmente para debug
200
- container.addSubview(previewView)
169
+ // Hacer el webView transparente
170
+ webView.isOpaque = false
171
+ webView.backgroundColor = .clear
172
+ webView.scrollView.backgroundColor = .clear
173
+ webView.scrollView.isOpaque = false
174
+
175
+ // Crear previewView
176
+ let previewView = UIView()
177
+ previewView.translatesAutoresizingMaskIntoConstraints = false
178
+ previewView.backgroundColor = .clear
179
+ previewView.isUserInteractionEnabled = false
201
180
 
202
- // 3. Configura constraints
203
- let safeArea = container.safeAreaLayoutGuide
181
+ // Insertar previewView DETRÁS de todo
182
+ container.insertSubview(previewView, at: 0)
183
+
184
+ // Configurar constraints para toda la pantalla
204
185
  NSLayoutConstraint.activate([
205
- previewView.topAnchor.constraint(equalTo: safeArea.topAnchor), // NO container.topAnchor
206
- previewView.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor, constant: -180),
186
+ previewView.topAnchor.constraint(equalTo: container.topAnchor),
187
+ previewView.bottomAnchor.constraint(equalTo: container.bottomAnchor),
207
188
  previewView.leadingAnchor.constraint(equalTo: container.leadingAnchor),
208
189
  previewView.trailingAnchor.constraint(equalTo: container.trailingAnchor)
209
190
  ])
210
191
 
211
- // 4. FORZA el layout inmediatamente
192
+ // Asegurar orden de capas
193
+ previewView.layer.zPosition = -1
194
+ webView.layer.zPosition = 0
195
+
196
+ // Forzar layout
212
197
  container.layoutIfNeeded()
213
198
 
214
- // 5. Crea el previewLayer después de tener el tamaño correcto
199
+ // Crear previewLayer
215
200
  let previewLayer = AVCaptureVideoPreviewLayer(session: session)
216
201
  previewLayer.videoGravity = .resizeAspectFill
217
202
  previewLayer.frame = previewView.bounds
@@ -219,50 +204,52 @@ public class CameraModulePlugin: CAPPlugin,CAPBridgedPlugin,AVCaptureVideoDataOu
219
204
 
220
205
  previewView.layer.insertSublayer(previewLayer, at: 0)
221
206
 
222
- // 6. Guarda referencias
207
+ // Guardar referencias
223
208
  self.previewView = previewView
224
209
  self.videoPreviewLayer = previewLayer
225
210
  self.captureSession = session
226
211
 
227
- // 7. Configura la sesión ANTES de iniciarla
212
+ // Configurar sesión
228
213
  session.sessionPreset = .photo
229
214
 
230
- // 8. Inicia la sesión en background
215
+ // Iniciar sesión en background
231
216
  DispatchQueue.global(qos: .userInitiated).async {
232
217
  session.startRunning()
233
-
234
- // 9. Vuelve al main thread para verificar que se esté mostrando
235
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
236
- print("Preview frame: \(previewView.frame)")
237
- print("Preview layer frame: \(previewLayer.frame)")
238
- print("Preview visible: \(previewView.window != nil)")
239
- }
240
218
  }
241
219
 
242
- call.resolve()
220
+ call.resolve([
221
+ "success": true,
222
+ "message": "Preview de cámara iniciado"
223
+ ])
243
224
  }
244
225
  }
245
226
 
246
-
247
227
  @objc func stopPreview(_ call: CAPPluginCall) {
248
228
  DispatchQueue.main.async {
229
+ // Detener cámara
249
230
  self.captureSession?.stopRunning()
250
231
  self.captureSession = nil
232
+
233
+ // Remover preview
251
234
  self.videoPreviewLayer?.removeFromSuperlayer()
252
235
  self.previewView?.removeFromSuperview()
253
236
  self.videoPreviewLayer?.session = nil
254
-
255
237
  self.videoPreviewLayer = nil
256
-
257
238
  self.previewView = nil
239
+
240
+ // Restaurar webView a estado normal
241
+ if let webView = self.bridge?.webView as? WKWebView {
242
+ webView.isOpaque = true
243
+ webView.backgroundColor = .white
244
+ webView.scrollView.backgroundColor = .white
245
+ webView.scrollView.isOpaque = true
246
+ }
247
+
258
248
  call.resolve()
259
249
  }
260
250
  }
261
251
 
262
-
263
-
264
252
  // MARK: - Flash
265
-
266
253
  @objc func toggleFlash(_ call: CAPPluginCall) {
267
254
  guard let enable = call.getBool("enable"),
268
255
  let device = AVCaptureDevice.default(for: .video),
@@ -288,53 +275,50 @@ public class CameraModulePlugin: CAPPlugin,CAPBridgedPlugin,AVCaptureVideoDataOu
288
275
  }
289
276
 
290
277
  @objc func getLastGalleryImage(_ call: CAPPluginCall) {
278
+ let status = PHPhotoLibrary.authorizationStatus(for: .readWrite)
291
279
 
292
- let status = PHPhotoLibrary.authorizationStatus(for: .readWrite)
280
+ guard status == .authorized || status == .limited else {
281
+ call.reject("Gallery permission not granted")
282
+ return
283
+ }
293
284
 
294
- guard status == .authorized || status == .limited else {
295
- call.reject("Gallery permission not granted")
296
- return
297
- }
285
+ let fetchOptions = PHFetchOptions()
286
+ fetchOptions.sortDescriptors = [
287
+ NSSortDescriptor(key: "creationDate", ascending: false)
288
+ ]
289
+ fetchOptions.fetchLimit = 1
298
290
 
299
- let fetchOptions = PHFetchOptions()
300
- fetchOptions.sortDescriptors = [
301
- NSSortDescriptor(key: "creationDate", ascending: false)
302
- ]
303
- fetchOptions.fetchLimit = 1
291
+ let assets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
304
292
 
305
- let assets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
293
+ guard let asset = assets.firstObject else {
294
+ call.reject("No images found")
295
+ return
296
+ }
306
297
 
307
- guard let asset = assets.firstObject else {
308
- call.reject("No images found")
298
+ let imageManager = PHImageManager.default()
299
+ let options = PHImageRequestOptions()
300
+ options.isSynchronous = true
301
+ options.deliveryMode = .highQualityFormat
302
+ options.resizeMode = .none
303
+
304
+ imageManager.requestImageDataAndOrientation(
305
+ for: asset,
306
+ options: options
307
+ ) { data, _, _, _ in
308
+ guard let imageData = data else {
309
+ call.reject("Error fetching last image")
309
310
  return
310
311
  }
311
312
 
312
- let imageManager = PHImageManager.default()
313
- let options = PHImageRequestOptions()
314
- options.isSynchronous = true
315
- options.deliveryMode = .highQualityFormat
316
- options.resizeMode = .none
317
-
318
- imageManager.requestImageDataAndOrientation(
319
- for: asset,
320
- options: options
321
- ) { data, _, _, _ in
313
+ let base64 = imageData.base64EncodedString()
322
314
 
323
- guard let imageData = data else {
324
- call.reject("Error fetching last image")
325
- return
326
- }
327
-
328
- let base64 = imageData.base64EncodedString()
329
-
330
- var ret = JSObject()
331
- ret["base64"] = base64
332
- call.resolve(ret)
333
- }
315
+ var ret = JSObject()
316
+ ret["base64"] = base64
317
+ call.resolve(ret)
334
318
  }
319
+ }
335
320
 
336
321
  // MARK: - Photo Capture
337
-
338
322
  @objc func takePhotoBase64(_ call: CAPPluginCall) {
339
323
  guard captureSession?.isRunning == true else {
340
324
  call.reject("Camera not started")
@@ -356,7 +340,6 @@ public class CameraModulePlugin: CAPPlugin,CAPBridgedPlugin,AVCaptureVideoDataOu
356
340
  }
357
341
 
358
342
  // MARK: - Barcode Scan
359
-
360
343
  @objc func startBarcodeScan(_ call: CAPPluginCall) {
361
344
  guard let session = captureSession else {
362
345
  call.reject("Preview not started")
@@ -433,8 +416,7 @@ public class CameraModulePlugin: CAPPlugin,CAPBridgedPlugin,AVCaptureVideoDataOu
433
416
 
434
417
  let handler = VNImageRequestHandler(
435
418
  cvPixelBuffer: pixelBuffer,
436
- orientation: CGImagePropertyOrientation.right
437
- ,
419
+ orientation: CGImagePropertyOrientation.right,
438
420
  options: [:]
439
421
  )
440
422
 
@@ -443,12 +425,10 @@ public class CameraModulePlugin: CAPPlugin,CAPBridgedPlugin,AVCaptureVideoDataOu
443
425
  }
444
426
 
445
427
  // MARK: - UIImagePicker Delegate
446
-
447
428
  extension CameraModulePlugin: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
448
429
 
449
430
  public func imagePickerController(_ picker: UIImagePickerController,
450
431
  didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
451
-
452
432
  picker.dismiss(animated: true)
453
433
 
454
434
  guard let image = info[.originalImage] as? UIImage,
@@ -474,7 +454,6 @@ extension CameraModulePlugin: UIImagePickerControllerDelegate, UINavigationContr
474
454
  }
475
455
 
476
456
  // MARK: - UIImage Resize
477
-
478
457
  extension UIImage {
479
458
  func resized(maxSize: CGFloat) -> UIImage? {
480
459
  let maxSide = max(size.width, size.height)
@@ -489,6 +468,23 @@ extension UIImage {
489
468
  UIGraphicsEndImageContext()
490
469
  return img
491
470
  }
471
+ }
492
472
 
473
+ // MARK: - Photo Delegate (si necesitas esta clase)
474
+ class PhotoDelegate: NSObject, AVCapturePhotoCaptureDelegate {
475
+ private let completion: (String) -> Void
493
476
 
494
- }
477
+ init(completion: @escaping (String) -> Void) {
478
+ self.completion = completion
479
+ }
480
+
481
+ func photoOutput(_ output: AVCapturePhotoOutput,
482
+ didFinishProcessingPhoto photo: AVCapturePhoto,
483
+ error: Error?) {
484
+ guard let data = photo.fileDataRepresentation(),
485
+ let base64 = data.base64EncodedString() else {
486
+ return
487
+ }
488
+ completion(base64)
489
+ }
490
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-camera-module",
3
- "version": "0.0.63",
3
+ "version": "0.0.65",
4
4
  "description": "Plugin to request permissiones view camera take phots",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",