각종 퍼미션을 요청해야되는 일이 있어서 일단 사진 / 카메라 퍼미션만 구현했습니다.
다른 퍼미션도 계속 추가해서 동일하게 사용하면 될듯 합니다.
[PermissionManager.swift]
import SwiftUI
import Photos
class PermissionManager: ObservableObject {
@Published var photoPermissionGranted = false
@Published var cameraPermissionGranted = false
/// 포토라이브러리 권한 체크
public func requestPhotoLibraryPermission() {
checkPhotoLibraryPermission { [weak self] (isAuthorize) in
if isAuthorize == true {
DispatchQueue.main.async {
self?.photoPermissionGranted = true
}
} else {
self?.requestPermissionSettingAlertAction(mediaType: .photoLibrary)
}
}
}
/// 카메라 사용 권한 체크
public func requestCameraPermission() {
checkCameraPermission { [weak self] (isAuthorize) in
if isAuthorize == true {
DispatchQueue.main.async {
self?.cameraPermissionGranted = true
}
} else {
self?.requestPermissionSettingAlertAction(mediaType: .camera)
}
}
}
// MARK: 앨범 사용권한 확인
private func checkPhotoLibraryPermission(complete: @escaping (Bool) -> Void) {
let status = PHPhotoLibrary.authorizationStatus()
switch status {
case .authorized:
complete(true)
case .limited:
complete(true)
case .denied :
complete(false)
case .notDetermined: // 선택안함.
requestPhotoLibraryAuthorization { (isAuthorize) in
complete(isAuthorize)
}
default: break
}
}
/// 앨범 사용권한 요청
private func requestPhotoLibraryAuthorization(complete: @escaping (Bool) -> Void ) {
DispatchQueue.main.async {
// PHPhotoLibrary.requestAuthorization(for: .readWrite) { (status) in
PHPhotoLibrary.requestAuthorization { (status) in
switch status{
case .authorized:
complete(true)
case .limited:
complete(true)
case .denied:
complete(false)
case .restricted:
complete(false)
default:
complete(false)
}
}
}
}
// MARK: 카메라 사용권한 확인
private func checkCameraPermission(complete: @escaping (Bool) -> Void) {
let status = AVCaptureDevice.authorizationStatus(for: .video)
switch status {
case .authorized:
complete(true)
case .denied :
complete(false)
case .notDetermined: // 선택안함.
requestCameraAuthorization { (isAuthorize) in
complete(isAuthorize)
}
default: break
}
}
/// 카메라 사용권한 요청
private func requestCameraAuthorization(completion: @escaping (Bool) -> Void ) {
DispatchQueue.main.async {
if AVCaptureDevice.authorizationStatus(for: .video) == .authorized{
completion(true)
}else{
AVCaptureDevice.requestAccess(for: .video) { (granted) in
completion(granted)
}
}
}
}
// MARK: 접근권한 설정 알림(권한설정 거부시)
/// 접근권한 거부시 알림 얼럿 (설정 페이지 이동)
private func requestPermissionSettingAlertAction(mediaType: UIImagePickerController.SourceType) {
let alertController = UIAlertController(
title: mediaType == .photoLibrary ? "현재 앨범 사용에 대한 접근 권한이 없습니다." : "현재 카메라 사용에 대한 접근 권한이 없습니다.",
message: mediaType == .photoLibrary ? "앨범의 사진을 사용하려면 사진 권한이 필요합니다. 권한 설정 화면으로 이동 하시겠습니까?" : "카메라를 사용하려면 권한이 필요합니다. 권한 설정 화면으로 이동 하시겠습니까?",
preferredStyle: .alert
)
let cancelAlert = UIAlertAction(
title: "취소",
style: .cancel
) { _ in
alertController.dismiss(animated: true, completion: nil)
}
let goToSettingAlert = UIAlertAction(
title: "설정으로 이동하기",
style: .default) { _ in
appSettingOpen()
}
[cancelAlert, goToSettingAlert]
.forEach(alertController.addAction(_:))
guard let topVC = UIApplication.currentTopViewController() else {
return
}
DispatchQueue.main.async {
topVC.present(alertController, animated: true) // must be used from main thread only
}
}
}
[사용방법]
struct ContentView: View {
@StateObject var permissionManager = PermissionManager()
@State var isShowPhotoGridView: Bool = false
var body: some View {
VStack {
Button {
permissionManager.requestPhotoLibraryPermission()
} label: {
HStack {
Image(systemName: "globe")
Text("카메라 이미지 촬영")
}
}
.onReceive(imagePickerManager.$photoPermissionGranted, perform: { granted in
// 퍼미션 상태 확인
if granted {
isShowPhotoGridView.toggle()
}
})
.fullScreenCover(isPresented: $isShowPhotoGridView,
content: {
/*
커스텀한 멀티선택 가능한 겔러리 UI 인데 추후 개제 하겠습니다. 양이 많아서...
*/
PhotoGridView()
})
}
}
}
'SwiftUI' 카테고리의 다른 글
[SwiftUI] 조절가능한 BottomSheetView (IOS 16 미만) (0) | 2024.06.10 |
---|---|
[SwiftUI] PHPickerViewController 멀티선택 사진앨범 가져오기(IOS 14이상) (0) | 2024.05.31 |
[SwiftUI] UIImagePickerController 카메라,앨범 이미지 가져오기 (0) | 2024.05.30 |
[SwiftUI] .fullScreenCover 로 NavigationView 열기 (0) | 2024.05.30 |
[SwiftUI] TabView Show / Hide (TabView - NavigationView) (0) | 2024.05.29 |