PhotoKit — 개념, 주요 개념 및 PHAsset

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

PhotoKit은 iOS 및 macOS에서 미디어 라이브러리로 작업하기 위한 Apple의 프레임워크로, 기기에서 사진, 비디오 및 Live Photos에 직접 액세스할 수 있도록 제공합니다. Apple 문서에 따르면, 이 프레임워크는 레거시 AssetsLibrary를 대체하고 iCloud, 앨범, 편집 및 Change Tracking을 지원합니다. PhotoKit은 iCloud를 통한 자동 동기화와 함께 쿼리, 캐싱 및 미디어 라이브러리 변경을 위한 통합 API를 제공합니다.

주요 포인트

  • PhotoKit은 시스템 미디어 라이브러리로 작업하기 위한 Apple의 프레임워크로, 사진, 비디오, Live Photos 및 앨범에 액세스할 수 있습니다.
  • PHAsset은 메타데이터(날짜, 위치, 유형)가 포함된 단일 미디어 항목(사진 또는 비디오)을 나타내는 데이터 모델입니다.
  • PHFetchResult는 지연 로딩 및 PHPhotoLibraryChangeObserver를 통한 변경 알림이 있는 쿼리 결과 컨테이너입니다.
  • PHImageManager는 PHCachingImageManager를 통해 크기, 모드 및 캐싱 옵션으로 이미지를 검색하기 위한 관리자입니다.
  • PHPhotoLibrary는 변경(미디어 개체 생성, 삭제 및 편집)을 수행하기 위한 진입점입니다.

PhotoKit이란?

PhotoKit은 시스템 미디어 라이브러리로 작업하기 위한 객체 지향 API를 제공하는 Apple의 프레임워크(iOS 8, macOS 10.11에서 도입)입니다. AssetsLibrary와 달리 PhotoKit은 미디어 라이브러리를 데이터베이스로 취급합니다. 쿼리는 콘텐츠 및 저장소 구조를 나타내는 PHAsset, PHCollectionPHCollectionList 개체를 반환합니다.

PhotoKit은 모든 미디어 유형을 지원합니다: 사진(JPEG, HEIF, RAW), 비디오(MOV, MP4), Live Photos 및 버스트 샷. 프레임워크는 iCloud 동기화를 자동으로 관리합니다. 이미지가 iCloud에 저장된 경우 PhotoKit은 네트워크를 통해 요청하고 PHImageRequestOptions.progressHandler를 통해 진행 상황을 보고합니다.

PhotoKit의 핵심 기능은 세션 간에 안정적인 로컬 식별자(localIdentifier)를 가진 PHObject 기반 데이터 모델입니다. 이를 통해 미디어 개체에 대한 참조를 저장하고 앱 재시작 후 다시 쿼리하지 않고 복원할 수 있습니다.

PhotoKit 작동 방식: 데이터 모델 및 쿼리

PhotoKit은 데이터 모델(PHObject), 쿼리(PHFetchResult) 및 변경(PHPhotoLibrary.performChanges)의 세 가지 수준으로 구축됩니다. 데이터 모델은 계층적입니다. PHAsset(사진/비디오)은 PHAssetCollection(앨범) 내에 있으며, 앨범은 PHCollectionList(폴더)로 그룹화됩니다.

쿼리 실행

쿼리는 PHAsset.fetchAssetsPHAssetCollection.fetchAssetCollections를 통해 실행됩니다. 모든 fetch 메서드는 동기식이며 PHFetchResult를 반환하며, 이는 즉시 미디어 라이브러리 데이터베이스에 대해 쿼리를 실행합니다. PHFetchResult는 인덱스별 빠른 액세스(object(at:)) 및 enumerateObjects를 통한 열거를 지원합니다.

  • fetchAssets(with:options:) — 유형, 날짜, 앨범별로 필터링된 모든 미디어 쿼리
  • fetchAssetCollections(with:subtype:options:) — 앨범 및 폴더 쿼리
  • fetchAssets(in:options:) — 특정 앨범 내 미디어 쿼리

PHFetchOptions

PHFetchOptions는 쿼리 구성을 위한 개체입니다: 정렬(sortDescriptors), 조건자(predicate), 숨겨진 및 삭제된 미디어 포함(includeHiddenAssets, includeAllBurstAssets). Fetch 옵션을 사용하면 미디어 유형별로 필터링할 수 있습니다: PHAssetMediaType.image, .video, .audio.

PhotoKit의 주요 클래스

PhotoKit에는 미디어 라이브러리에 액세스, 쿼리 및 수정하기 위한 클래스 집합이 포함되어 있습니다. 프레임워크로 효과적으로 작업하려면 각각을 이해하는 것이 필수적입니다.

PHAsset

PHAsset은 단일 미디어 항목을 나타내는 변경 불가능한 개체입니다. 메타데이터를 포함합니다: mediaType, mediaSubtypes, creationDate, location, pixelWidth, pixelHeight, duration(비디오용), isFavorite, burstIdentifier. LocalIdentifier는 앱 재시작 후에도 액세스 가능한 안정적인 문자열 키입니다.

PHAssetCollection

PHAssetCollection은 미디어 그룹입니다: 시스템 앨범(Recents, Favorites, Selfies, Screenshots), 사용자 앨범 또는 Moments(시간 및 장소별 자동 그룹화). 속성: localizedTitle, assetCollectionType, assetCollectionSubtype, startDate, endDate.

PHCollectionList

PHCollectionList는 앨범(PHAssetCollection) 또는 다른 폴더를 포함하는 폴더입니다. 주로 사용자 인터페이스에서 계층 구조를 표시하는 데 사용되며 거의 사용되지 않습니다.

PHImageManager 및 캐싱

PhotoKit은 PHAsset에서 직접 UIImage를 반환하지 않습니다 — PHImageManager를 통해 이미지를 요청해야 합니다. 이렇게 하면 iCloud 지원, 캐싱 및 필요한 크기로 이미지가 로드됩니다.

구성 요소목적특징
PHImageManager.default()일회성 요청을 위한 표준 관리자요청 간 캐싱 없음
PHCachingImageManager컬렉션을 위한 프리로드 관리자부드러운 스크롤을 위한 startCachingImages
PHImageRequestOptions요청 설정: 크기, 모드, 전달synchronous, deliveryMode, progressHandler
PHImageRequestID취소를 위한 요청 식별자cancelImageRequest(PHImageRequestID)

PHImageManager는 세 가지 전달 모드를 지원합니다: opportunistic(먼저 축소 버전, 그 다음 전체), highQualityFormat(전체 품질만), fastFormat(가장 빠른 사용 가능 버전). 컬렉션의 경우 항상 표시 셀에 대한 이미지 프리로드와 함께 PHCachingImageManager를 사용하세요.

Swift에서 PhotoKit 사용 예제

PhotoKit은 사용자 정의 갤러리, 편집기 및 미디어 응용 프로그램을 만드는 데 사용됩니다. 세 가지 주요 시나리오를 살펴보겠습니다.

미디어 라이브러리에서 모든 사진 가져오기

생성 날짜별로 정렬된 PHFetchOptions와 함께 PHAsset.fetchAssets는 사용자 정의 사진 갤러리를 구축하기 위한 기본 쿼리입니다. PHFetchResult는 지연 로딩 및 스트리밍 액세스를 지원합니다.

swift
let options = PHFetchOptions()
options.sortDescriptors = [NSSortDescriptor(
    key: "creationDate",
    ascending: .false
)]
options.predicate = NSPredicate(
    format: "mediaType == %d",
    PHAssetMediaType.image.rawValue
)

let allPhotos = PHAsset.fetchAssets(with: options)
print("\(allPhotos.count)개의 사진을 찾았습니다")

allPhotos.enumerateObjects { asset, index, stop in
    print("사진 \(index): \(asset.localIdentifier)")
}

PHFetchResult는 스레드 안전 컨테이너입니다. object(at:)를 통해 인덱스로 개체에 액세스하면 UI가 차단되지 않지만 PHImageManager를 통한 이미지 요청은 비동기식으로 수행되어야 합니다.

캐싱으로 이미지 로드

PHCachingImageManager는 프리로드를 위한 startCachingImages 및 stopCachingImages 메서드가 있는 PHImageManager의 하위 클래스입니다. 부드러운 스크롤을 위해 UICollectionView에서 사용됩니다.

swift
let cachingManager = PHCachingImageManager()
let targetSize = CGSize(width: 200, height: 200)

// 표시 셀을 위한 프리로드
cachingManager.startCachingImages(
    for: visibleAssets,
    targetSize: targetSize,
    contentMode: .aspectFill,
    options: nil
)

// iCloud 폴백이 있는 PHImageRequestOptions를 통한 이미지 요청
let requestOptions = PHImageRequestOptions()
requestOptions.deliveryMode = .opportunistic
requestOptions.isNetworkAccessAllowed = .true
requestOptions.progressHandler = { progress, error, stop, info in
    DispatchQueue.main.async {
        print("iCloud에서 다운로드 중: \(progress * 100)%")
    }
}

let requestID = cachingManager.requestImage(
    for: asset,
    targetSize: targetSize,
    contentMode: .aspectFill,
    options: requestOptions
) { image, info in
    print("이미지를 가져왔습니다: \(image?.size ?? .zero)")
}

미디어 라이브러리 편집: 즐겨찾기 추가

미디어 라이브러리 변경은 changeRequest 블록 내에서 PHPhotoLibrary.shared().performChanges를 통해 수행됩니다. 모든 작업은 일괄 처리되어 트랜잭션 방식으로 적용됩니다.

swift
PHPhotoLibrary.shared().performChanges {
    let changeRequest = PHAssetChangeRequest(for: asset)
    changeRequest.isFavorite = .true
} completionHandler: { success, error in
    if success {
        print("즐겨찾기에 추가됨")
    }
}

Change Tracking을 통한 변경 및 관찰

PhotoKit은 PHPhotoLibraryChangeObserver 프로토콜을 통해 미디어 라이브러리 변경을 관찰하는 메커니즘을 제공합니다. 변경(생성, 삭제, 편집)이 발생하면 PHChange 개체와 함께 photoLibraryDidChange 메서드가 호출됩니다.

PHChange에는 각 쿼리 유형에 대한 changeDetails가 포함됩니다: PHFetchResultChangeDetails에는 removedIndexes, insertedIndexes, changedIndexes가 포함됩니다. 이를 통해 UICollectionView에 대한 performBatchUpdates(move, insert, delete)를 사용하여 애니메이션과 함께 UI에 변경 사항을 적용할 수 있습니다.

swift
class PhotosViewController: UIViewController {
    var fetchResult: PHFetchResult>PHAsset>?

    override func viewDidLoad() {
        super.viewDidLoad()
        PHPhotoLibrary.shared().register(self)
    }

    deinit {
        PHPhotoLibrary.shared().unregisterChangeObserver(self)
    }
}

extension PhotosViewController: PHPhotoLibraryChangeObserver {
    func photoLibraryDidChange(_ changeInstance: PHChange) {
        guard let fetchResult,
              let details = changeInstance.changeDetails(for: fetchResult)
        else { return }

        DispatchQueue.main.async {
            self.fetchResult = details.fetchResultAfterChanges
            // collectionView에 변경 사항 적용
        }
    }
}

RAW 편집 및 확장

PhotoKit은 PHContentEditingInputPHContentEditingOutput 메커니즘을 통해 미디어 편집을 지원합니다. 앱은 원본 데이터와 함께 editingInput을 요청하고, 변경 사항을 적용하며, editingOutput을 통해 결과를 저장합니다. 프레임워크는 자동으로 원본을 보존하여 사용자가 원본으로 재설정하여 변경 사항을 되돌릴 수 있습니다.

RAW 사진(DNG, CR2, NEF)은 원본 RAW 파일에 대한 액세스를 제공하는 PHAssetResourceManager를 통해 지원됩니다. RAW 처리를 위해서는 온도, 노출 및 선명도 조정을 지원하는 CIRAWFilter와 함께 CoreImage를 사용하는 것이 좋습니다. PhotoKit은 Photo Editing Extension(iOS)을 통해 편집기 확장도 지원합니다 — 선택한 사진이나 비디오를 처리하기 위해 시스템 편집기에서 앱을 호출할 수 있습니다.

PhotoKit 성능 최적화

PhotoKit은 강력하지만 리소스를 많이 사용하는 프레임워크입니다. 잘못 사용하면 스크롤 지연 및 과도한 메모리 소비가 발생할 수 있습니다. 최적의 성능을 위해 다음 권장 사항을 따르세요.

  • 컬렉션에는 PHCachingImageManager 사용 — 표시 +/-1 화면 셀에 대한 이미지 프리로드가 스크롤 지연을 제거합니다
  • targetSize 설정 — 썸네일에 PHImageManagerMaximumSize를 요청하지 마세요. 셀의 물리적 크기에 화면 배율을 곱한 크기를 사용하세요
  • 셀 재사용 시 요청 취소 — PHImageRequestID를 저장하고 prepareForReuse에서 cancelImageRequest를 호출하세요
  • iCloud 요청 제한 — 빠른 스크롤 중에는 isNetworkAccessAllowed = false로 설정하고 정지 시에만 iCloud 사진을 로드하세요
  • PHFetchResult 캐싱 — 동일한 옵션으로 반복 fetchAssets는 새 PHFetchResult를 반환합니다. 결과를 속성으로 저장하고 Change Observer를 통해 업데이트하세요

PHLivePhoto는 PHLivePhoto.request(with:targetSize:contentMode:options:resultHandler:)를 통해 별도의 요청이 필요합니다. 사진만 표시하는 셀에는 Live Photo를 요청하지 마세요 — 표시에는 PHLivePhotoBadge를 사용하세요.

자주 묻는 질문

PhotoKit이란 무엇이며 AssetsLibrary와 어떻게 다른가요?

PhotoKit은 iOS 8에서 도입된 미디어 라이브러리 작업을 위한 최신 Apple 프레임워크입니다. 레거시 AssetsLibrary와 달리 PhotoKit은 PHAsset 개체 모델, 빠른 검색이 가능한 PHFetchResult, iCloud 지원 및 변경 사항 관찰을 위한 Change Tracking을 제공합니다.

PhotoKit을 통해 미디어 라이브러리에 대한 액세스를 요청하려면 어떻게 해야 하나요?

콜백 핸들러와 함께 PHPhotoLibrary.requestAuthorization(for: .readWrite)를 호출하세요. .authorized 상태를 받은 후 PHAsset.fetchAssets 쿼리를 실행할 수 있습니다. 쓰기 액세스에는 .readWrite 권한이 필요합니다. 읽기 전용의 경우 .addOnly입니다.

PHAsset에서 이미지를 가져오려면 어떻게 해야 하나요?

매개변수(asset, targetSize, contentMode, PHImageRequestOptions)와 함께 PHImageManager.default().requestImage를 사용하세요. 비동기 메서드는 PHImageRequestID를 반환하여 요청을 취소할 수 있습니다. 컬렉션의 경우 프리로드와 함께 PHCachingImageManager를 사용하세요.

미디어 라이브러리의 변경 사항을 추적하려면 어떻게 해야 하나요?

PHPhotoLibrary.shared().register(self)를 통해 관찰자를 등록하고 PHPhotoLibraryChangeObserver 프로토콜을 구현하세요. photoLibraryDidChange 메서드에서 각 fetchResult에 대한 changeDetails와 함께 PHChange를 수신하고 애니메이션과 함께 UI에 변경 사항을 적용하세요.

PhotoKit에서 iCloud 사진을 처리하려면 어떻게 해야 하나요?

PHImageRequestOptions에서 iCloud 다운로드 진행 상황을 추적하기 위해 isNetworkAccessAllowed = true 및 progressHandler를 설정하세요. 빠른 스크롤 중에는 네트워크 액세스를 비활성화하고 스크롤 지연을 방지하기 위해 로컬 버전만 로드하세요.

요약

  • PhotoKit은 iOS 8 및 macOS 10.11부터 AssetsLibrary를 대체하는 미디어 라이브러리 작업용 Apple 프레임워크입니다.
  • PHAsset은 로컬 식별자, 유형, 날짜, 위치 및 크기가 있는 핵심 데이터 모델입니다.
  • PHFetchResult는 저장소에 동기 쿼리를 수행하고 결과에 대한 스레드 안전 액세스를 제공합니다.
  • PHCachingImageManager는 프리로드를 통해 컬렉션에서 지연 없는 부드러운 스크롤을 보장합니다.
  • Change Tracking(PHPhotoLibraryChangeObserver)을 통해 UI가 미디어 라이브러리 변경에 즉시 반응할 수 있습니다.
  • iCloud 동기화는 프레임워크에 내장되어 있습니다: 이미지 요청 시 진행 상황과 함께 iCloud에서 자동으로 다운로드됩니다.
  • 최적화 — 적절한 targetSize, 요청 취소 및 스크롤 중 iCloud 제한은 성능에 중요합니다.

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

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

프로젝트 논의

더 읽어보기