From ea98112a21d912669163b34d9fc238de586c1dc2 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Sat, 14 Oct 2023 13:17:14 +0200 Subject: [PATCH] fix: Fix basic Orientation on iOS (#2000) * fix: Fix basic Orientation on iOS * ci: Use macOS 13 runner for latest Xcode 15 * chore: Remove Xcode 15 checks * Format --- .github/workflows/build-ios.yml | 4 +-- .github/workflows/validate-ios.yml | 2 +- package/ios/CameraDevicesManager.swift | 15 ++++------ .../Extensions/AVCaptureOutput+mirror.swift | 27 +++++++++--------- package/ios/Types/Orientation.swift | 28 +++++++++++-------- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/workflows/build-ios.yml b/.github/workflows/build-ios.yml index 71ebaa0..58c878c 100644 --- a/.github/workflows/build-ios.yml +++ b/.github/workflows/build-ios.yml @@ -21,7 +21,7 @@ on: jobs: build: name: Build iOS Example App - runs-on: macOS-latest + runs-on: macOS-13 defaults: run: working-directory: package/example/ios @@ -80,7 +80,7 @@ jobs: build-no-frame-processors: name: Build iOS Example App without Frame Processors - runs-on: macOS-latest + runs-on: macOS-13 defaults: run: working-directory: package/example/ios diff --git a/.github/workflows/validate-ios.yml b/.github/workflows/validate-ios.yml index e4870c7..65366df 100644 --- a/.github/workflows/validate-ios.yml +++ b/.github/workflows/validate-ios.yml @@ -27,7 +27,7 @@ jobs: env: WORKING_DIRECTORY: ios SwiftFormat: - runs-on: macOS-latest + runs-on: macOS-13 defaults: run: working-directory: ./package/ios diff --git a/package/ios/CameraDevicesManager.swift b/package/ios/CameraDevicesManager.swift index 6537d57..a65bcaf 100644 --- a/package/ios/CameraDevicesManager.swift +++ b/package/ios/CameraDevicesManager.swift @@ -39,17 +39,12 @@ class CameraDevicesManager: RCTEventEmitter { override func constantsToExport() -> [AnyHashable: Any]! { let devices = getDevicesJson() let preferredDevice: [String: Any]? - // TODO: Remove this #if once Xcode 15 is rolled out - #if swift(>=5.9) - if #available(iOS 17.0, *), - let userPreferred = AVCaptureDevice.userPreferredCamera { - preferredDevice = userPreferred.toDictionary() - } else { - preferredDevice = devices.first - } - #else + if #available(iOS 17.0, *), + let userPreferred = AVCaptureDevice.userPreferredCamera { + preferredDevice = userPreferred.toDictionary() + } else { preferredDevice = devices.first - #endif + } return [ "availableCameraDevices": devices, diff --git a/package/ios/Extensions/AVCaptureOutput+mirror.swift b/package/ios/Extensions/AVCaptureOutput+mirror.swift index a808f53..fa0a8e5 100644 --- a/package/ios/Extensions/AVCaptureOutput+mirror.swift +++ b/package/ios/Extensions/AVCaptureOutput+mirror.swift @@ -30,23 +30,22 @@ extension AVCaptureOutput { - For Videos, the buffers are physically rotated if available, since we use an AVCaptureVideoDataOutput instead of an AVCaptureMovieFileOutput. */ func setOrientation(_ orientation: Orientation) { - // Camera Sensors are always in 90deg rotation. - // We are setting the target rotation here, so we need to rotate by 90deg once. - let cameraOrientation = orientation.rotateRight() - // Set orientation for each connection connections.forEach { connection in - // TODO: Use this once Xcode 15 is rolled out - // if #available(iOS 17.0, *) { - // let degrees = cameraOrientation.toDegrees() - // if connection.isVideoRotationAngleSupported(degrees) { - // connection.videoRotationAngle = degrees - // } - // } else { - if connection.isVideoOrientationSupported { - connection.videoOrientation = cameraOrientation.toAVCaptureVideoOrientation() + if #available(iOS 17.0, *) { + // Camera Sensors are always in landscape rotation (90deg). + // We are setting the target rotation here, so we need to rotate by landscape once. + let cameraOrientation = orientation.rotateBy(orientation: .landscapeLeft) + let degrees = cameraOrientation.toDegrees() + + if connection.isVideoRotationAngleSupported(degrees) { + connection.videoRotationAngle = degrees + } + } else { + if connection.isVideoOrientationSupported { + connection.videoOrientation = orientation.toAVCaptureVideoOrientation() + } } - // } } } } diff --git a/package/ios/Types/Orientation.swift b/package/ios/Types/Orientation.swift index f6a9958..3f8fbb4 100644 --- a/package/ios/Types/Orientation.swift +++ b/package/ios/Types/Orientation.swift @@ -38,6 +38,19 @@ enum Orientation: String, JSUnionValue { } } + init(degrees: Double) { + switch degrees { + case 45 ..< 135: + self = .landscapeLeft + case 135 ..< 225: + self = .portraitUpsideDown + case 225 ..< 315: + self = .landscapeRight + default: + self = .portrait + } + } + var jsValue: String { return rawValue } @@ -68,16 +81,9 @@ enum Orientation: String, JSUnionValue { } } - func rotateRight() -> Orientation { - switch self { - case .portrait: - return .landscapeLeft - case .landscapeLeft: - return .portraitUpsideDown - case .portraitUpsideDown: - return .landscapeRight - case .landscapeRight: - return .portrait - } + func rotateBy(orientation: Orientation) -> Orientation { + let added = toDegrees() + orientation.toDegrees() + let degress = added.truncatingRemainder(dividingBy: 360) + return Orientation(degrees: degress) } }