diff --git a/Package.swift b/Package.swift index 027f42be..3e1ccba5 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.7 +// swift-tools-version:5.8 import PackageDescription diff --git a/Source/AssetManager.swift b/Source/AssetManager.swift index ae630aba..42a952c9 100644 --- a/Source/AssetManager.swift +++ b/Source/AssetManager.swift @@ -22,11 +22,15 @@ open class AssetManager { public static func fetch(withConfiguration configuration: ImagePickerConfiguration, _ completion: @escaping (_ assets: [PHAsset]) -> Void) { guard PHPhotoLibrary.authorizationStatus() == .authorized else { return } + + let options = PHFetchOptions() + options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)] + DispatchQueue.global(qos: .background).async { let fetchResult = configuration.allowVideoSelection - ? PHAsset.fetchAssets(with: PHFetchOptions()) - : PHAsset.fetchAssets(with: .image, options: PHFetchOptions()) + ? PHAsset.fetchAssets(with: options) + : PHAsset.fetchAssets(with: .image, options: options) if fetchResult.count > 0 { var assets = [PHAsset]() diff --git a/Source/CameraView/CameraMan.swift b/Source/CameraView/CameraMan.swift index 846d0875..6dfb8b3c 100644 --- a/Source/CameraView/CameraMan.swift +++ b/Source/CameraView/CameraMan.swift @@ -19,6 +19,8 @@ class CameraMan { var stillImageOutput: AVCaptureStillImageOutput? var startOnFrontCamera: Bool = false + private let captureOrientation = CaptureOrientation() + deinit { stop() } @@ -154,7 +156,7 @@ class CameraMan { func takePhoto(_ previewLayer: AVCaptureVideoPreviewLayer, location: CLLocation?, completion: (() -> Void)? = nil) { guard let connection = stillImageOutput?.connection(with: AVMediaType.video) else { return } - connection.videoOrientation = Helper.videoOrientation() + connection.videoOrientation = captureOrientation.current queue.async { self.stillImageOutput?.captureStillImageAsynchronously(from: connection) { buffer, error in diff --git a/Source/CameraView/CaptureOrientation.swift b/Source/CameraView/CaptureOrientation.swift index 014de7d3..8b75972b 100644 --- a/Source/CameraView/CaptureOrientation.swift +++ b/Source/CameraView/CaptureOrientation.swift @@ -1,8 +1,64 @@ +// CaptureOrientation.swift // -// File.swift -// // -// Created by Phillip Avelar on 1/15/24. +// Created by Spencer Whyte on 2023-05-28. // import Foundation +import AVFoundation +import CoreMotion + +class CaptureOrientation { + + private (set) var current = AVCaptureVideoOrientation.portrait + + private let motionManager = CMMotionManager() + + init() { + motionManager.accelerometerUpdateInterval = 0.1 + motionManager.startAccelerometerUpdates(to: .main) { [weak self] data, error in + self?.updateOrientation(data: data) + } + } + + private func updateOrientation(data: CMAccelerometerData?) { + if let data = data { + current = data.orientation ?? current + } + } + + deinit { + motionManager.stopAccelerometerUpdates() + } +} + +private extension CMAccelerometerData { + + var orientation: AVCaptureVideoOrientation? { + if acceleration.z < -0.75 || acceleration.z > 0.75 { + return nil + } + + let denominator = abs(acceleration.x) + abs(acceleration.y) + guard denominator != 0 else { + return nil + } + let scale = 1.0 / denominator + + let x = acceleration.x * scale + let y = acceleration.y * scale + if x < -0.5 { + return .landscapeRight + } + if x > 0.5 { + return .landscapeLeft + } + if y < -0.5 { + return .portrait + } + if y > 0.5 { + return .portraitUpsideDown + } + return nil + } +} diff --git a/Source/Helper.swift b/Source/Helper.swift index 780950f9..681b5622 100644 --- a/Source/Helper.swift +++ b/Source/Helper.swift @@ -18,22 +18,22 @@ struct Helper { } } - static func getVideoOrientation(fromDeviceOrientation orientation: UIDeviceOrientation) -> AVCaptureVideoOrientation { - switch orientation { - case .landscapeLeft: - return .landscapeRight - case .landscapeRight: - return .landscapeLeft - case .portraitUpsideDown: - return .portraitUpsideDown - default: - return .portrait - } - } - - static func videoOrientation() -> AVCaptureVideoOrientation { - return getVideoOrientation(fromDeviceOrientation: previousOrientation) - } +// static func getVideoOrientation(fromDeviceOrientation orientation: UIDeviceOrientation) -> AVCaptureVideoOrientation { +// switch orientation { +// case .landscapeLeft: +// return .landscapeRight +// case .landscapeRight: +// return .landscapeLeft +// case .portraitUpsideDown: +// return .portraitUpsideDown +// default: +// return .portrait +// } +// } +// +// static func videoOrientation() -> AVCaptureVideoOrientation { +// return getVideoOrientation(fromDeviceOrientation: previousOrientation) +// } static func screenSizeForOrientation() -> CGSize { switch UIDevice.current.orientation {