From 596209be5eeaf2165e70caed6e0ead2aa6553150 Mon Sep 17 00:00:00 2001 From: tomokisun Date: Thu, 28 Dec 2023 02:35:59 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20video=20preview?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FlyCam/Sources/CameraFeature/Camera.swift | 10 +++++++++- .../Sources/CameraFeature/Localizable.xcstrings | 2 +- .../CameraResultFeature/CALayerView.swift | 16 ++++++++++++++++ .../CameraResultFeature/CameraResult.swift | 14 +------------- 4 files changed, 27 insertions(+), 15 deletions(-) create mode 100644 Packages/FlyCam/Sources/CameraResultFeature/CALayerView.swift diff --git a/Packages/FlyCam/Sources/CameraFeature/Camera.swift b/Packages/FlyCam/Sources/CameraFeature/Camera.swift index 3466005d..ad78cb23 100644 --- a/Packages/FlyCam/Sources/CameraFeature/Camera.swift +++ b/Packages/FlyCam/Sources/CameraFeature/Camera.swift @@ -2,6 +2,7 @@ import CameraRecordFeature import CameraResultFeature import ComposableArchitecture import FeedbackGeneratorClient +import Photos import SwiftUI @Reducer @@ -47,6 +48,13 @@ public struct CameraLogic { state.child = .result( CameraResultLogic.State(altitude: altitude, videoURL: videoURL) ) + PHPhotoLibrary.shared().performChanges({ + PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoURL) + }) { _, error in + if let error = error { + print("PHPhotoLibrary.shared().performChanges: \(error.localizedDescription)") + } + } return .none case .child(.result(.sendButtonTapped)): @@ -101,7 +109,7 @@ public struct CameraView: View { ) } } - .navigationTitle("Camera") + .navigationTitle("FlyCam") .navigationBarTitleDisplayMode(.inline) .task { await store.send(.onTask).finish() } .onAppear { store.send(.onAppear) } diff --git a/Packages/FlyCam/Sources/CameraFeature/Localizable.xcstrings b/Packages/FlyCam/Sources/CameraFeature/Localizable.xcstrings index a9146232..2581c3d0 100644 --- a/Packages/FlyCam/Sources/CameraFeature/Localizable.xcstrings +++ b/Packages/FlyCam/Sources/CameraFeature/Localizable.xcstrings @@ -1,7 +1,7 @@ { "sourceLanguage" : "en", "strings" : { - "Camera" : { + "FlyCam" : { } }, diff --git a/Packages/FlyCam/Sources/CameraResultFeature/CALayerView.swift b/Packages/FlyCam/Sources/CameraResultFeature/CALayerView.swift new file mode 100644 index 00000000..0037c055 --- /dev/null +++ b/Packages/FlyCam/Sources/CameraResultFeature/CALayerView.swift @@ -0,0 +1,16 @@ +import SwiftUI + +struct CALayerView: UIViewControllerRepresentable { + var caLayer: CALayer + + func makeUIViewController(context: Context) -> UIViewController { + let viewController = UIViewController() + viewController.view.layer.addSublayer(caLayer) + caLayer.frame = viewController.view.layer.frame + return viewController + } + + func updateUIViewController(_ uiViewController: UIViewController, context: Context) { + caLayer.frame = uiViewController.view.layer.frame + } +} diff --git a/Packages/FlyCam/Sources/CameraResultFeature/CameraResult.swift b/Packages/FlyCam/Sources/CameraResultFeature/CameraResult.swift index ed5c591d..96492468 100644 --- a/Packages/FlyCam/Sources/CameraResultFeature/CameraResult.swift +++ b/Packages/FlyCam/Sources/CameraResultFeature/CameraResult.swift @@ -62,7 +62,7 @@ public struct CameraResultView: View { public var body: some View { WithViewStore(store, observe: { $0 }) { viewStore in VStack(spacing: 24) { - VideoPlayer(player: viewStore.player) + CALayerView(caLayer: AVPlayerLayer(player: viewStore.player)) .aspectRatio(3 / 4, contentMode: .fill) .frame(width: UIScreen.main.bounds.width) .clipShape(RoundedRectangle(cornerRadius: 24)) @@ -89,15 +89,3 @@ public struct CameraResultView: View { } } } - -#Preview { - CameraResultView( - store: .init( - initialState: CameraResultLogic.State( - altitude: 1.0, - videoURL: .applicationDirectory - ), - reducer: { CameraResultLogic() } - ) - ) -}