ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • swift concurrency 사용해 이미지 권한 얻기
    iOS 2023. 11. 29. 19:49
    [  💡 3줄 요약 ]
    iOS 14 부터는 이미지 권한을 얻는 새로운 api 가 추가됨. (async, closure 모두 지원.)
    limited status 가 생겼으니 deprecated 된 기존 권한 얻는 방식을 사용할 경우 주의가 필요함.
    Concurrency 로 구현한 코드.
    func hasPhotoLibraryAuthorization() async -> Bool {
        if #available(iOS 14, *) {
            let status = await PHPhotoLibrary.requestAuthorization(for: .readWrite)
            return status == .authorized || status == .limited
        } else {
            return await withCheckedContinuation { continuation in
                PHPhotoLibrary.requestAuthorization { status in
                    if status == .authorized {
                        continuation.resume(returning: true)
                    } else {
                        continuation.resume(returning: false)
                    }
                }
            }
        }
    }

     

     

    # 들어가기 

    concurrency 이전에 이미지 권한을 얻는 방법에 대해 먼저 알아보겠습니다.

    iOS 14 이후

    // closure를 사용한 비동기적 방식
    class func requestAuthorization( 
       for accessLevel: PHAccessLevel
       handler: @escaping (PHAuthorizationStatus)
    )
    
    // async를 사용한 동기적 방식
    class func requestAuthorization(for accessLevel: PHAccessLevel) async -> PHAuthorizationStatus


    - status > [notDetermined, restricted, denied, authorized, limited]
    - limited 추가됨 > 유저가 선택한 이미지들만 허용할 수 있도록.

    iOS 14 이전

    class func requestAuthorization(_ handler: @escaping (PHAuthorizationStatus) -> Void)


    - status > [notDetermined, restricted, denied, authorized]
    - iOS 14 이후 버전에서 이 deprecated 메서드 사용할 경우 limited 인 케이스 주의

     

    # 사용해보기 with concurrency

    사용자 권한이 있는 경우 true, 없는 경우 false 를 반환하는 함수를 만들어보겠습니다.

    func hasPhotoLibraryAuthorization() async -> Bool {
    
    }

    위에 async 를 사용할 수 있는 경우엔 간단하겠죠? 그냥 제공해주는 async 메서드를 사용합니다.
    (원하시는 PHAccessLevel 을 고려하세요.)

    func hasPhotoLibraryAuthorization() async -> Bool {
        if #available(iOS 14, *) {
            let status = await PHPhotoLibrary.requestAuthorization(for: .readWrite)
            return status == .authorized
        }
    }

    잠깐! status 가 limited 인 경우도 놓치지 않도록 주의합시다. 저는 이 케이스도 true 로 보고 싶어요 :)

    func hasPhotoLibraryAuthorization() async -> Bool {
        if #available(iOS 14, *) {
            let status = await PHPhotoLibrary.requestAuthorization(for: .readWrite)
            return status == .authorized || status == .limited
        }
    }

    iOS 14 이전 케이스는 그냥 기존처럼 하면 되는데요, 문제는 closure 를 어떻게 async 로 바꿀 수 있느냐 입니다.
    withCheckedContinuation 를 사용해서 처리해줄 수 있습니다. 

    func hasPhotoLibraryAuthorization() async -> Bool {
        if #available(iOS 14, *) {
            let status = await PHPhotoLibrary.requestAuthorization(for: .readWrite)
            return status == .authorized || status == .limited
        } else {
            return await withCheckedContinuation { continuation in
                PHPhotoLibrary.requestAuthorization { status in
                    if status == .authorized {
                        continuation.resume(returning: true)
                    } else {
                        continuation.resume(returning: false)
                    }
                }
            }
        }
    }

    with Continuation 메서드가 몇 개 존재하니 필요에 따라 다른 친구들을 사용해줘도 됩니다.

     

    읽어주셔서 감사합니다.

    댓글

Designed by Tistory.