diff --git a/Projects/App/Project.swift b/Projects/App/Project.swift index 25b486c..40506e3 100644 --- a/Projects/App/Project.swift +++ b/Projects/App/Project.swift @@ -25,6 +25,7 @@ let project = Project.configure( "CFBundleVersion": "1", "UILaunchStoryboardName": "launch", "NSUserTrackingUsageDescription": "이 앱은 사용자 맞춤형 광고 제공 및 분석을 위해 사용자 추적 정보를 수집합니다.", + "NSPhotoLibraryUsageDescription": "밈 이미지 등록을 위해 앨범 접근 권한이 필요합니다.", "UIUserInterfaceStyle": "Light", // 다크모드 방지 "NSAllowArbitraryLoads": true, "NSAppTransportSecurity": [ @@ -75,6 +76,7 @@ let project = Project.configure( "UILaunchStoryboardName": "launch", "NSUserTrackingUsageDescription": "이 앱은 사용자 맞춤형 광고 제공 및 분석을 위해 사용자 추적 정보를 수집합니다.", "UIUserInterfaceStyle": "Light", // 다크모드 방지 + "NSPhotoLibraryUsageDescription": "밈 이미지 등록을 위해 앨범 접근 권한이 필요합니다.", "NSAppTransportSecurity": [ "NSAllowsArbitraryLoads": true ] diff --git a/Projects/Features/MemeEditor/Sources/ImagePicker.swift b/Projects/Features/MemeEditor/Sources/ImagePicker.swift index 9f375dc..c2c990c 100644 --- a/Projects/Features/MemeEditor/Sources/ImagePicker.swift +++ b/Projects/Features/MemeEditor/Sources/ImagePicker.swift @@ -7,40 +7,85 @@ import SwiftUI import UIKit +import Photos struct ImagePicker: UIViewControllerRepresentable { - @Binding var selectedImage: UIImage? - @Environment(\.presentationMode) var presentationMode + @Binding var selectedImage: UIImage? + @Environment(\.presentationMode) var presentationMode + + class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate { + var parent: ImagePicker - class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate { - var parent: ImagePicker - - init(parent: ImagePicker) { - self.parent = parent - } - - func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { - if let uiImage = info[.originalImage] as? UIImage { - parent.selectedImage = uiImage - } - - parent.presentationMode.wrappedValue.dismiss() - } - - func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { - parent.presentationMode.wrappedValue.dismiss() - } + init(parent: ImagePicker) { + self.parent = parent } - - func makeCoordinator() -> Coordinator { - return Coordinator(parent: self) + + func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { + if let uiImage = info[.originalImage] as? UIImage { + parent.selectedImage = uiImage + } + parent.presentationMode.wrappedValue.dismiss() } - - func makeUIViewController(context: Context) -> UIImagePickerController { - let picker = UIImagePickerController() - picker.delegate = context.coordinator - return picker + + func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { + parent.presentationMode.wrappedValue.dismiss() } - - func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {} + } + + func makeCoordinator() -> Coordinator { + return Coordinator(parent: self) + } + + func makeUIViewController(context: Context) -> UIImagePickerController { + let picker = UIImagePickerController() + picker.delegate = context.coordinator + checkPhotoLibraryPermission { granted in + if !granted { + print("사진 접근 권한이 허용되어 있지 않음") + showPermissionDeniedAlert(on: picker) + context.coordinator.parent.presentationMode.wrappedValue.dismiss() + } + } + + return picker + } + + func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {} + private func checkPhotoLibraryPermission(completion: @escaping (Bool) -> Void) { + let status = PHPhotoLibrary.authorizationStatus() + switch status { + case .authorized: + completion(true) + case .denied, .restricted: + completion(false) + case .notDetermined: + PHPhotoLibrary.requestAuthorization { status in + DispatchQueue.main.async { + completion(status == .authorized) + } + } + default: + completion(false) + } + } + + private func showPermissionDeniedAlert(on viewController: UIViewController) { + let alert = UIAlertController( + title: "사진 접근 권한 필요", + message: "사진을 선택하려면 설정에서 접근 권한을 허용해주세요.", + preferredStyle: .alert + ) + + alert.addAction(UIAlertAction(title: "취소", style: .cancel, handler: nil)) + alert.addAction(UIAlertAction(title: "설정으로 이동", style: .default, handler: { _ in + if let appSettings = URL(string: UIApplication.openSettingsURLString) { + UIApplication.shared.open(appSettings) + } + })) + + // UIAlertController를 UIImagePickerController 위에 표시 + DispatchQueue.main.async { + viewController.present(alert, animated: true, completion: nil) + } + } }