본문 바로가기
iOS

iOS 사진 라이브러리 접근에 필요한 권한

by vapor3965 2021. 9. 3.

목차

     

    나는 지금까지 무조건 사진 라이브러리 ( 사용자의 사진첩 ) 에 접근하기 위해서는 권한이 필요한 줄 알았다. 

    하지만, 단순히 접근해서 읽기만 하는 경우에는 명시적으로 권한을 요청할 필요가 없다.  

     

    만약 사진을 읽어와서 편집하여 사용자의 사진 라이브러리에 덮어씌우거나,

    또는 사진 라이브러리에 저장하는 경우에는 권한이 필요하다

    ( 다양한 글들에 그러한 내용을 발견할 수 있었는데, 공식문서에서도 확인할 수 있었다. ) 

     

    우선, iOS 14부터는 PHPickerViewController가 등장했는데, UIImagePickerController를 대체하는 새로운 picker다. 

    사진첩과 같은 인터페이스를 제공하면서, 멀티플 샐랙션을 제공한다. 

     

    여튼, 사진을 단순히 읽어오거나, 인터넷이나 이메일에 포함시키는 경우에는 명시적인 권한 없이 이러한 Picker를 이용하면 된다. 

    하지만, asset, collection을 가져오거나, 사진첩 라이브러리를 업데이트하는 경우에는 명시적인 권한이 필요하다.

    단순히 사진라이브러리에 추가하는 경우에는 NSPhotoLibraryAddUsageDescription을 Info.plist에 추가하고, 

    다른 모든 경우에는 NSPhotoLibraryUsageDescription을 추가한다. 

     

    만약 권한없이 위와 같은 행동을 한다면 앱이 크래쉬난다. 

     

     

    권한 확인

    authorizationStatus 

    권한을 요청하기 전에 우선 현재 권한이 있는지 확인해야겠다. 

    ( 앱이 처음으로 아래의 코드를 사용하여 status를 체크한다면, .notDetermined가 뜰것이다. 이는 아직 사용자가 결정하지 못한 상태이다 ) 

    // Check the app's authorization status (either read/write or add-only access).
    let readWriteStatus = PHPhotoLibrary.authorizationStatus(for: .readWrite)

     

    권한 요청

    requestAuthorization 핸들러

    그 다음에 권한이 없는 경우에는 추가적으로 다음과 같이 사용자에게 요청하여 접근할 수 있다. 

    • 처음으로 앱에서 처음으로 권한을 요청한다면, 시스템은 자동적으로 얼럿창을 띄운다. 
      • 즉, 이미 한번 유저가 이 얼럿에 대해 어떠한 선택을 했다면, 다시는 뜨지 않는다. 그러므로, 사용자는 설정앱에서 언제든 변경할 수 있고, 그에 따라 앱은 변경된 권한에 대해 적절히 반응할 필요가 있다. 
    • 하지만, 앱이 처음 런치할때, 이와 같은 행동은 피하도록 해라.  왜냐하면 온보딩이나 준비과정이 필요한 과정에서 방해하지 않기 위해서다.  그러므로, 유저가 행동에 의해 호출하도록 하라. 
    // Request read-write access to the user's photo library.
    PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in
        switch status {
        case .notDetermined:
            // 아직 사용자가 앱의 접근을 결정하지 않았음.
        case .restricted:
            // 시스템이 앱의 접근을 제한함 
        case .denied:
            // 사용자가 명시적으로 앱의 접근을 거부함 ㅠ 
        case .authorized:
            // 사용자가 사진첩의 데이터에 접근을 허가함 
        case .limited:
            // 사용자가 사진첩의 접근을 허가하지만, 제한된 사진들만 가능.
        @unknown default:
            fatalError()
        }
    }

     

    위의 코드는 read, write 하는 경우에 권한을 확인하는 메서드다.  .readWrite 

    만약 사진 라이브러리에 추가만 한다면 .addOnly로 변경해도 된다. 

     

    iOS 14 부터는 requestAuthorization( for: ) 이 추가됐다.

    기존에는 for: 이 없이 요청할 수 있었다. 

     

    여기서 중요한점이, iOS14 부터는 개인정보를 강화하여, 기존에는 모든 사진에 대해 접근하거나 못하거나 였는데, 이제는 선택적으로 사진을 접근하도록 할 수 있게 됐다. 

    그러므로, .limited 라는 status가 추가됐는데, 이것이 선택적으로 접근한다는 것을 뜻한다. 

     

    그러므로, 권한을 확인하기 위한 authorizationStatus() 메서드 ( iOS14 이전 )는 limited가 뜨지 않고, .authorized가 뜬다. 

    마찬가지로, 권한 획득을 위한 requestAuthorization 메서드 또한 authorized를 return한다. 

    그러므로 limited를 확인하기 위해서는iOS14 메서드를 사용해야한다. 

     

     

     


    참고

    https://developer.apple.com/documentation/photokit/delivering_an_enhanced_privacy_experience_in_your_photos_app

     

    댓글