Photo Library Permission — 기본, 액세스 유형 및 작동 원리

저자: IT Sectr 게시일: 2026-05-21 읽는 시간: 8 분

Photo Library Permission은 사용자 기기에 저장된 사진 및 비디오에 앱이 액세스하는 데 필요한 권한입니다. 갤러리에서 이미지를 선택하고, 미디어 파일을 저장하며, 사진 앨범을 관리하는 데 필요합니다. Apple Developer Documentation, 2024에 따르면, iOS 14부터 앱은 모든 사진에 한 번에 액세스하는 것이 아니라 제한된 라이브러리에 대한 액세스를 요청해야 합니다.

핵심 사항

  • Photo Library Permission — 기기 갤러리에서 미디어 파일을 읽고 쓰는 권한, 사진 및 비디오 작업에 필수적입니다.
  • Android는 갤러리 액세스를 위해 READ_MEDIA_IMAGES, READ_MEDIA_VIDEO(Android 13+) 또는 READ_EXTERNAL_STORAGE를 사용합니다.
  • iOS는 iOS 14부터 제한된 액세스(Limited Photo Library Access)로 PHPhotoLibrary를 사용합니다.
  • 개별 사진 선택은 시스템 피커(PhotoPicker)를 통해 이루어지며 전체 라이브러리에 액세스할 권한이 필요하지 않습니다.
  • 갤러리에 쓰기에는 별도의 쓰기 권한(Android에서는 WRITE_EXTERNAL_STORAGE, iOS에서는 PHPhotoLibrary)이 필요합니다.

Photo Library Permission 기본

Photo Library Permission은 기기에 저장된 미디어 파일에 대한 앱의 액세스를 제어하는 시스템 권한입니다. 읽기(사진 및 비디오 보기 및 선택)와 쓰기(갤러리에 새 파일 저장)를 모두 포괄합니다. 모바일 플랫폼은 사진에 개인 및 민감한 정보가 포함될 수 있으므로 미디어 라이브러리를 민감한 데이터로 간주합니다.

Android 13(API 33)에서 Google은 단일 READ_EXTERNAL_STORAGE 권한을 세 개로 분할했습니다: READ_MEDIA_IMAGES(사진용), READ_MEDIA_VIDEO(비디오용), READ_MEDIA_AUDIO(오디오용). 이를 통해 사용자는 특정 유형의 미디어 파일에만 액세스 권한을 부여할 수 있습니다. iOS에서는 iOS 14부터 PhotoKit을 통해 사용자가 전체 라이브러리를 여는 대신 특정 사진을 선택하여 액세스할 수 있습니다.

Counterpoint Research(2024)에 따르면, 소셜 네트워크, 커뮤니케이션 및 사진 편집기 카테고리의 모바일 앱 중 70% 이상이 Photo Library Permission을 요청합니다. 동시에 사용자의 32%는 앱이 자신의 사진을 왜 필요로 하는지 이해하지 못할 경우 갤러리 액세스를 거부합니다. Apple과 Google은 전체 액세스를 요청하지 않고 개별 파일을 선택하기 위해 시스템 PhotoPicker를 사용할 것을 권장합니다.

Android에서 갤러리 액세스

Android에서 갤러리 액세스는 Android 13 출시와 함께 크게 변경되었습니다. 단일 READ_EXTERNAL_STORAGE 권한 대신 각 미디어 유형에 대한 세분화된 권한이 도입되어 사용자에게 더 많은 제어권을 제공합니다.

Android 13+ 권한

Android 13부터 사진 액세스에는 READ_MEDIA_IMAGES, 비디오 액세스에는 READ_MEDIA_VIDEO가 사용됩니다. READ_EXTERNAL_STORAGE 권한은 더 이상 미디어 파일에 대한 액세스를 제공하지 않으며 — 공유 저장소에서 비미디어 파일을 읽는 용도로만 유지됩니다. 매니페스트의 선언은 다음과 같습니다:

xml
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

Android 12 이하와의 호환성

Android 12 이하와의 하위 호환성을 위해 READ_EXTERNAL_STORAGE도 선언해야 합니다. 그러나 Android 13은 새로운 세분화된 권한이 있는 경우 이 권한을 자동으로 무시합니다. 새 버전에서 이전 권한을 숨기려면 매니페스트에서 android:maxSdkVersion="32" 속성을 사용하세요. 이렇게 하면 Android 13+를 실행하는 기기에서 중복 요청을 방지할 수 있습니다.

xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />

Kotlin에서 런타임 요청

Android에서 Photo Library Permission에 대한 런타임 요청은 Activity Result API를 통해 수행됩니다. 이미지 액세스 요청 예시:

kotlin
private val photoPermissionLauncher =
    registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
    if (granted) {
        loadGalleryImages()
    } else {
        showPermissionDenied()
    }
}

fun pickPhoto() {
    val permission = if (Build.version.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        Manifest.permission.READ_MEDIA_IMAGES
    } else {
        Manifest.permission.READ_EXTERNAL_STORAGE
    }
    if (ContextCompat.checkSelfPermission(this, permission)
        == PackageManager.PERMISSION_GRANTED) {
        loadGalleryImages()
    } else {
        photoPermissionLauncher.launch(permission)
    }
}

iOS에서 갤러리 액세스

iOS에서 갤러리 액세스는 PhotoKit 프레임워크와 Info.plist의 NSPhotoLibraryUsageDescription 및 NSPhotoLibraryAddUsageDescription 키를 통해 관리됩니다. iOS 14부터 사용자는 선택한 사진에만 액세스 권한을 부여할 수 있습니다(Limited Photo Library).

Info.plist 구성

라이브러리에서 사진을 읽으려면 NSPhotoLibraryUsageDescription이 필요하고, 쓰기(사진 저장)에는 NSPhotoLibraryAddUsageDescription이 필요합니다. 앱이 미디어를 저장만 하고 읽지 않는 경우 두 번째 키면 충분합니다.

xml
<key>NSPhotoLibraryUsageDescription</key>
<string>앱이 프로필 이미지를 선택하고 스냅샷을 게시하려면 사진에 액세스해야 합니다.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>앱이 처리된 사진을 갤러리에 저장하려면 액세스가 필요합니다.</string>

Swift에서 요청

iOS에서 사진 액세스 요청은 PHPhotoLibrary.requestAuthorization을 통해 수행됩니다. iOS 14부터 .limited 상태는 사용자가 제한된 사진 세트에 대한 액세스 권한을 부여했음을 나타냅니다.

swift
import PhotosUI

func requestPhotoLibraryAccess() {
    PHPhotoLibrary.requestAuthorization { status in
        DispatchQueue.main.async {
            switch status {
            case .authorized:
                self.loadPhotoLibrary()
            case .limited:
                self.loadSelectedPhotos()
            case .denied, .restricted:
                self.showSettingsAlert()
            case .notDetermined:
                break
            }
        }
    }
}

private func loadPhotoLibrary() {
    let fetchOptions = PHFetchOptions()
    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    let assets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
    // 요청 결과 처리
}

제한된 액세스 처리

iOS 14+의 .limited 상태는 사용자가 선택한 몇 장의 사진에만 액세스 권한을 부여했음을 의미합니다. 앱은 PHPhotoLibrary.shared().presentLimitedLibraryPicker를 호출하여 시스템 대화 상자를 통해 확장된 액세스를 요청할 수 있습니다. 이 대화 상자는 사용자가 추가 사진이 필요한 기능을 명시적으로 요청할 때만 표시하는 것이 좋습니다.

PhotoPicker vs 시스템 권한

PhotoPicker는 전체 라이브러리에 액세스할 권한이 필요하지 않은 미디어 파일 선택을 위한 시스템 구성 요소입니다. Android 13 및 iOS 14부터 Google과 Apple은 앱이 하나 또는 몇 장의 사진만 선택하면 되는 경우 Photo Library Permission을 요청하는 대신 PhotoPicker를 사용할 것을 권장합니다.

Android의 PhotoPicker

Android 13+에서 내장된 PhotoPicker(ActivityResultContracts.PickVisualMedia)를 통해 사용자는 전체 갤러리에 대한 액세스 권한을 부여하지 않고 사진이나 비디오를 선택할 수 있습니다. 앱은 선택된 파일의 URI만 받습니다. PhotoPicker는 매니페스트에서 권한을 선언하지 않고 작동합니다.

kotlin
private val pickMedia =
    registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
    if (uri != null) {
        // 선택한 파일의 URI, 전체 라이브러리에 액세스하지 않음
        showImage(uri)
    }
}

fun selectPhoto() {
    pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}

iOS의 PHPicker

iOS 14+에서 PHPickerViewController가 도입되었습니다 — 전체 라이브러리에 대한 액세스가 필요하지 않은 시스템 피커입니다. PHPicker는 별도의 프로세스에서 실행되며 앱의 라이브러리에 액세스할 수 없습니다. 대부분의 시나리오에서 사진을 선택하는 선호되는 방법입니다.

swift
import PhotosUI

func presentPhotoPicker() {
    var config = PHPickerConfiguration()
    config.selectionLimit = 1
    config.filter = .images

    let picker = PHPickerViewController(configuration: config)
    picker.delegate = self
    present(picker, animated: true)
}

전체 권한이 필요한 경우

PhotoPicker는 앱이 백업, 클라우드 동기화, 갤러리 앱, 파일 관리자와 같은 대량 작업을 위해 전체 라이브러리에 액세스해야 하는 경우 적합하지 않습니다. 이러한 경우 Photo Library Permission을 요청하고 제한된 액세스(Limited)를 처리해야 합니다. iOS의 경우 .limited 상태 처리를 포함하고 사용자에게 액세스를 확장할 수 있는 옵션을 제공해야 합니다.

갤러리 액세스 모범 사례

모범 사례를 따라 Photo Library Permission을 처리하면 거부 횟수를 줄이고 플랫폼의 개인정보 보호 요구 사항을 준수할 수 있습니다.

기본적으로 PhotoPicker 사용

하나 또는 여러 장의 사진을 선택하려면 시스템 PhotoPicker 또는 PHPicker를 사용하세요. 이러한 구성 요소는 권한이 필요하지 않으며 최상의 사용자 경험을 제공합니다. 앱 기능이 전체 미디어 라이브러리에 액세스해야 하는 경우에만 전체 갤러리 액세스를 요청하세요. Google과 Apple은 개발자 문서에서 이 접근 방식을 명시적으로 권장합니다.

전체 액세스 이유 설명

앱이 정말로 전체 갤러리 액세스가 필요한 경우 설명과 함께 사전 화면을 표시하세요. 모든 사진이 필요한 이유를 설명합니다. 예를 들어, 백업 앱은 복사본을 만들기 위해 모든 미디어 파일을 스캔할 것이라고 설명해야 합니다. 사전 권한 화면은 제한된 액세스 메커니즘 때문에 iOS에서 특히 중요합니다.

필요한 권한만 요청

앱이 사진을 저장만 하고 읽지 않는 경우(예: 결과를 저장하는 사진 편집기), 갤러리에 대한 쓰기 권한만 요청하세요. Android에서는 WRITE_EXTERNAL_STORAGE(Android 12 이하의 경우) 또는 권한 없는 MediaStore API(Android 10+의 경우)입니다. iOS에서는 NSPhotoLibraryUsageDescription 없이 NSPhotoLibraryAddUsageDescription을 사용하세요.

자주 묻는 질문

Android 10+에서 사진을 저장하는 데 권한이 필요한가요?

Android 10(API 29)부터 MediaStore를 통한 사진 저장에는 WRITE_EXTERNAL_STORAGE 권한이 필요하지 않습니다. 시스템은 명시적 권한 없이 쓰기를 위해 공유 저장소에 대한 액세스를 제공합니다. 다른 사용자의 파일을 읽으려면 여전히 적절한 권한이 필요합니다.

READ_EXTERNAL_STORAGE와 READ_MEDIA_IMAGES의 차이점은 무엇인가요?

READ_EXTERNAL_STORAGE는 공유 저장소에서 모든 파일을 읽는 이전 권한입니다(Android 12까지). READ_MEDIA_IMAGES는 이미지만 읽는 새로운 세분화된 권한입니다(Android 13+). 사용자는 비디오 및 오디오에 대한 액세스를 거부하면서 사진에만 액세스 권한을 부여할 수 있습니다.

iOS에서 .limited 상태를 어떻게 처리하나요?

.limited 상태는 사용자가 액세스용으로 몇 장의 사진을 선택했음을 의미합니다. 앱은 PHPhotoLibrary.shared().presentLimitedLibraryPicker를 통해 시스템 확장 대화 상자를 표시할 수 있습니다. 이 대화 상자는 사용자가 명시적으로 요청할 때만 표시하는 것이 좋습니다(예: “사진 더 추가” 버튼을 탭할 때).

사진에서 EXIF 메타데이터를 읽을 수 있나요?

네, Photo Library Permission이 있으면 앱이 지리 태그, 촬영 날짜 및 카메라 모델을 포함한 EXIF 데이터를 읽을 수 있습니다. iOS에서 Apple은 GPS 좌표를 기밀 데이터로 간주하므로 지리 태그에 액세스하려면 추가 위치 권한이 필요할 수 있습니다.

권한 없이 갤러리에서 비디오를 선택하려면 어떻게 하나요?

시스템 피커를 사용하세요: iOS에서는 filter = .videos인 PHPicker, Android에서는 VideoOnly인 PickVisualMedia. Android에서는 MediaStore.Video.Media.EXTERNAL_CONTENT_URI와 함께 Intent(Intent.ACTION_PICK)를 사용할 수도 있지만, Android 13 미만 버전에서는 READ_EXTERNAL_STORAGE 권한이 필요합니다.

요약

  • Photo Library Permission — 미디어 파일 읽기 및 쓰기 권한, 기기 갤러리와 함께 작동하는 앱에 필수적입니다.
  • Android 13+는 단일 READ_EXTERNAL_STORAGE 대신 세분화된 권한 READ_MEDIA_IMAGES 및 READ_MEDIA_VIDEO를 사용합니다.
  • iOS 14+는 PhotoKit을 통해 사용자가 선택한 사진에만(Limited) 액세스 권한을 부여할 수 있도록 합니다.
  • PhotoPicker는 전체 라이브러리 액세스를 요청하지 않고 개별 파일을 선택하는 권장 방법입니다.
  • 갤러리에 쓰기는 Android 10+에서 MediaStore를 통해 권한이 필요하지 않으며, iOS에서는 NSPhotoLibraryAddUsageDescription이 필요합니다.
  • 사전 권한 화면으로 사진 수집 목적을 설명하면 승인 전환율이 높아지고 거부가 줄어듭니다.
  • 제한된 액세스는 iOS에서 추가 처리와 시스템 대화 상자를 통한 확장된 액세스 요청 기능이 필요합니다.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기