commit
cb7619bbbd
@ -28,15 +28,35 @@ import Foundation
|
||||
|
||||
@objc public static func checkDeviceCameraAuthorizationStatus(_ resolve: @escaping RCTPromiseResolveBlock,
|
||||
reject: @escaping RCTPromiseRejectBlock) {
|
||||
switch AVCaptureDevice.authorizationStatus(for: .video) {
|
||||
case .authorized: resolve(true)
|
||||
case .notDetermined: resolve(-1)
|
||||
default: resolve(false)
|
||||
#if targetEnvironment(macCatalyst)
|
||||
if #available(macCatalyst 14.0, *) {
|
||||
switch AVCaptureDevice.authorizationStatus(for: .video) {
|
||||
case .authorized: resolve(true)
|
||||
case .notDetermined: resolve(-1)
|
||||
default: resolve(false)
|
||||
}
|
||||
} else {
|
||||
resolve(false)
|
||||
}
|
||||
#else
|
||||
switch AVCaptureDevice.authorizationStatus(for: .video) {
|
||||
case .authorized: resolve(true)
|
||||
case .notDetermined: resolve(-1)
|
||||
default: resolve(false)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@objc public static func requestDeviceCameraAuthorization(_ resolve: @escaping RCTPromiseResolveBlock,
|
||||
reject: @escaping RCTPromiseRejectBlock) {
|
||||
#if targetEnvironment(macCatalyst)
|
||||
if #available(macCatalyst 14.0, *) {
|
||||
AVCaptureDevice.requestAccess(for: .video, completionHandler: { resolve($0) })
|
||||
} else {
|
||||
resolve(false)
|
||||
}
|
||||
#else
|
||||
AVCaptureDevice.requestAccess(for: .video, completionHandler: { resolve($0) })
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,7 +80,12 @@ public class CameraView: UIView {
|
||||
private func setupCamera() {
|
||||
if hasPropBeenSetup && hasPermissionBeenGranted && !hasCameraBeenSetup {
|
||||
hasCameraBeenSetup = true
|
||||
#if targetEnvironment(macCatalyst)
|
||||
// Force front camera on Mac Catalyst during initial setup
|
||||
camera.setup(cameraType: .front, supportedBarcodeType: scanBarcode && onReadCode != nil ? supportedBarcodeType : [])
|
||||
#else
|
||||
camera.setup(cameraType: cameraType, supportedBarcodeType: scanBarcode && onReadCode != nil ? supportedBarcodeType : [])
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,6 +129,7 @@ public class CameraView: UIView {
|
||||
}
|
||||
|
||||
private func configureHardwareInteraction() {
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
// Create a new capture event interaction with a handler that captures a photo.
|
||||
if #available(iOS 17.2, *) {
|
||||
let interaction = AVCaptureEventInteraction { event in
|
||||
@ -138,6 +144,7 @@ public class CameraView: UIView {
|
||||
self.addInteraction(interaction)
|
||||
eventInteraction = interaction
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
override public func removeFromSuperview() {
|
||||
@ -177,7 +184,12 @@ public class CameraView: UIView {
|
||||
|
||||
// Camera settings
|
||||
if changedProps.contains("cameraType") {
|
||||
#if targetEnvironment(macCatalyst)
|
||||
// Force front camera on Mac Catalyst regardless of what's passed
|
||||
camera.update(cameraType: .front)
|
||||
#else
|
||||
camera.update(cameraType: cameraType)
|
||||
#endif
|
||||
}
|
||||
if changedProps.contains("flashMode") {
|
||||
camera.update(flashMode: flashMode)
|
||||
@ -314,6 +326,26 @@ public class CameraView: UIView {
|
||||
}
|
||||
|
||||
private func handleCameraPermission() {
|
||||
#if targetEnvironment(macCatalyst)
|
||||
// On macOS, camera permissions are handled differently
|
||||
if #available(macCatalyst 14.0, *) {
|
||||
switch AVCaptureDevice.authorizationStatus(for: .video) {
|
||||
case .authorized:
|
||||
hasPermissionBeenGranted = true
|
||||
case .notDetermined:
|
||||
AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in
|
||||
if granted {
|
||||
DispatchQueue.main.async {
|
||||
self?.hasPermissionBeenGranted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
#else
|
||||
// iOS permission handling
|
||||
switch AVCaptureDevice.authorizationStatus(for: .video) {
|
||||
case .authorized:
|
||||
// The user has previously granted access to the camera.
|
||||
@ -329,6 +361,7 @@ public class CameraView: UIView {
|
||||
// The user has previously denied access.
|
||||
break
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private func writeCaptured(imageData: Data,
|
||||
|
||||
@ -55,6 +55,7 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
@ -68,6 +69,12 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
|
||||
queue: nil,
|
||||
using: { _ in self.setVideoOrientationToInterfaceOrientation() })
|
||||
}
|
||||
#else
|
||||
override init() {
|
||||
super.init()
|
||||
// Mac Catalyst doesn't support device orientation notifications
|
||||
}
|
||||
#endif
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
@ -82,11 +89,13 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
|
||||
}
|
||||
}
|
||||
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
motionManager?.stopAccelerometerUpdates()
|
||||
|
||||
NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: UIDevice.current)
|
||||
|
||||
UIDevice.current.endGeneratingDeviceOrientationNotifications()
|
||||
#endif
|
||||
}
|
||||
|
||||
deinit {
|
||||
@ -591,6 +600,7 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
|
||||
// MARK: - Private device orientation from accelerometer
|
||||
|
||||
private func initializeMotionManager() {
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
motionManager = CMMotionManager()
|
||||
motionManager?.accelerometerUpdateInterval = 0.2
|
||||
motionManager?.gyroUpdateInterval = 0.2
|
||||
@ -612,6 +622,7 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
|
||||
self.deviceOrientation = newOrientation
|
||||
self.onOrientationChange?(["orientation": Orientation.init(from: newOrientation)!.rawValue])
|
||||
})
|
||||
#endif
|
||||
}
|
||||
|
||||
private func deviceOrientation(from acceleration: CMAcceleration) -> UIDeviceOrientation? {
|
||||
@ -678,6 +689,7 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
|
||||
}
|
||||
|
||||
private func setVideoOrientationToInterfaceOrientation() {
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
var interfaceOrientation: UIInterfaceOrientation
|
||||
if #available(iOS 13.0, *) {
|
||||
interfaceOrientation = self.previewView.window?.windowScene?.interfaceOrientation ?? .portrait
|
||||
@ -685,6 +697,10 @@ class RealCamera: NSObject, CameraProtocol, AVCaptureMetadataOutputObjectsDelega
|
||||
interfaceOrientation = UIApplication.shared.statusBarOrientation
|
||||
}
|
||||
self.cameraPreview.previewLayer.connection?.videoOrientation = self.videoOrientation(from: interfaceOrientation)
|
||||
#else
|
||||
// Mac Catalyst always uses landscape orientation
|
||||
self.cameraPreview.previewLayer.connection?.videoOrientation = .landscapeRight
|
||||
#endif
|
||||
}
|
||||
|
||||
private func sessionRuntimeError(notification: Notification) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user