Photo Editing Extension은 서드파티 앱이 시스템 사진 앱에 직접 편집 도구를 추가할 수 있도록 하는 iOS 메커니즘입니다. 완전한 기능을 갖춘 편집기와 달리, 확장 기능은 사진을 별도의 앱으로 로드하지 않습니다. 사용자는 표준 인터페이스를 벗어나지 않고 필터를 적용하고, 색상을 조정하고, 효과를 추가할 수 있습니다. Apple Developer Documentation(2025)에 따르면 PhotoKit은 PHAdjustmentData 및 PHContentEditingController를 포함하여 사진 리소스 작업을 위한 40개 이상의 API를 제공합니다.
핵심 사항
Photo Editing Extension은 사진 앱의 표준 인터페이스에 이미지 처리 도구를 임베드하는 iOS의 앱 확장 기능 유형입니다. 사용자가 사진을 열고 편집 버튼을 탭한 다음 설치된 확장 기능 목록에서 원하는 확장 기능을 선택합니다. 편집 후 결과는 라이브러리에 다시 저장되고 원본 파일은 되돌리기에 사용할 수 있게 유지됩니다.
이 아키텍처는 사용자 경험의 핵심 문제를 해결합니다: 앱 간 전환, 이미지 내보내기 및 가져오기, 버전 추적이 필요하지 않습니다. WWDC 2025에 따르면 모든 확장 기능은 자체 샌드박스와 제한된 실행 시간(편집 작업당 최대 30초)을 가진 격리된 프로세스에서 실행됩니다.
확장 기능은 기기 메모리의 임의 파일에 액세스할 수 없습니다 — 사용자가 선택 인터페이스를 통해 명시적으로 전달한 사진에만 액세스할 수 있습니다. 이는 서드파티 도구 사용 시 사용자 데이터의 보안을 보장합니다.
PhotoKit은 iOS 8에서 도입된 기기 미디어 라이브러리 작업을 위한 Apple 프레임워크입니다. 이미지, 비디오, 앨범 및 메타데이터를 포함한 사진 리소스에 대한 프로그래밍 방식의 액세스를 제공합니다. 편집 확장 기능의 경우 PhotoKit은 스토리지와 수정 인터페이스 사이의 중간 계층 역할을 합니다.
PHAsset은 라이브러리의 개별 미디어 객체(사진 또는 비디오)를 나타냅니다. PHAsset을 통해 촬영 날짜, 파일 유형, 지도상의 위치, 카메라 방향 등의 메타데이터를 얻을 수 있습니다. PHAssetResource는 기본 리소스(예: RAW 또는 HEIC 형식의 원본 사진 파일)에 대한 액세스를 제공합니다.
편집 확장 기능의 경우 PHContentEditingInput이 매우 중요합니다 — 읽기 및 처리를 위해 사용 가능한 전체 이미지(또는 비디오) 파일을 포함하는 객체입니다. 확장 기능은 활성화 시 이 객체를 수신하여 소스 자료로 사용합니다.
PHImageManager는 이미지 로딩 및 캐싱을 관리합니다. 편집 확장 기능의 경우 직접 사용되지 않습니다 — 확장 기능은 PHContentEditingInput을 통해 전체 파일을 수신합니다. 그러나 PHImageRequestOptions을 사용하면 요청 매개변수(크기, 전달 유형(동기 또는 비동기), 결과 형식)를 구성할 수 있습니다.
Apple에 따르면 PHImageManager는 이미지 썸네일을 RAM에 자동으로 캐시하여 미리보기의 반복 표시 속도를 높입니다. 편집 확장 기능의 경우 최상의 이미지 품질을 얻기 위해 PHImageRequestOptionsDeliveryModeHighQualityFormat을 사용하는 것이 좋습니다.
let options = PHImageRequestOptions()
options.deliveryMode = .highQualityFormat
options.isSynchronous = true
PHImageManager.default().requestImage(
for: asset,
targetSize: .init(width: 1024, height: 1024),
contentMode: .aspectFill,
options: options
) { image, _ in
// use image for display
}
각 Photo Editing Extension은 PHContentEditingController 프로토콜을 구현합니다 — 확장 기능의 중앙 제어 요소입니다. 프로토콜은 인터페이스 표시, 입력 데이터 수신 및 결과 저장을 위한 메서드를 정의합니다.
beginContentEditing(with:)은 편집 세션이 시작될 때 호출됩니다. 확장 기능은 PHContentEditingInput을 수신하고 원본 이미지와 함께 인터페이스를 표시해야 합니다. finishContentEditing(completionHandler:)은 편집을 완료합니다 — 확장 기능은 수정된 파일과 AdjustmentData가 포함된 PHContentEditingOutput을 반환합니다. cancelContentEditing()은 저장하지 않고 변경 사항을 취소합니다.
중요한 세부 사항: beginContentEditing 호출 시점에 확장 기능은 사진의 한 버전(사용자가 요청한 것)에만 액세스할 수 있습니다. 다른 사진이나 앨범에는 액세스할 수 없습니다. 이는 Apple이 보안을 위해 도입한 샌드박스 제한입니다.
class PhotoEditingViewController: UIViewController {
override func beginContentEditing(
with input: PHContentEditingInput
) {
guard let url = input.fullSizeImageURL else { return }
let image = CIImage(contentsOf: url)
displayImage.image = UIImage(ciImage: image)
}
}
PHContentEditingController는 편집 인터페이스를 저장 로직에서 분리합니다. 기본 iOS 프로세스가 beginContentEditing을 호출하고, 확장 기능이 자체 UI를 표시하고, 사용자가 변경을 수행한 다음 finishContentEditing이 새 파일을 생성합니다. Apple은 인터페이스를 차단하지 않도록 메인 스레드가 아닌 백그라운드 스레드에서 CIFilter 필터, Core Image 조작 등 모든 리소스 집약적 처리를 수행할 것을 권장합니다.
PHAdjustmentData는 Photo Editing Extension에서 비파괴 편집을 가능하게 하는 핵심 메커니즘입니다. 임의 형식으로 적용된 변경 사항에 대한 정보를 포함하는 객체입니다. 확장 기능은 필터 매개변수, 마스크 및 설정을 AdjustmentData로 직렬화하고 수정된 이미지와 함께 저장합니다.
사진을 다시 열면 확장 기능이 AdjustmentData를 읽고 이전 인터페이스 상태를 복원하며 사용자가 같은 지점에서 편집을 계속할 수 있도록 합니다. 확장 기능이 설치되지 않은 경우 사진은 마지막으로 저장된 버전으로 표시되고 원본은 별도로 저장됩니다.
Apple 문서에 따르면 PHAdjustmentData는 formatIdentifier와 formatVersion(데이터 형식을 식별하기 위한 문자열)을 저장합니다. 확장 기능을 업데이트할 때 버전을 확인하고 이전 형식을 올바르게 처리해야 합니다.
let adjustmentData = PHAdjustmentData(
formatIdentifier: "com.example.photoediting",
formatVersion: "1.0",
data: NSKeyedArchiver.archivedData(
withRootObject: params,
requiringSecureCoding: true
)
)
output.adjustmentData = adjustmentData
finishContentEditing 시점에 확장 기능은 수정된 이미지 파일과 함께 PHContentEditingOutput 객체에 AdjustmentData를 씁니다. 그런 다음 시스템은 두 구성 요소(표시용 버전과 편집 세션 복원용 메타데이터)를 모두 저장합니다.
Photo Editing Extension은 이를 포함하는 앱을 설치한 후 사진 앱 메뉴에 자동으로 나타납니다. 사용자가 사진을 열고 편집을 선택하면 도구의 하단 행에 시스템 및 서드파티의 모든 설치된 편집 확장 기능이 표시됩니다.
확장 기능은 메인 앱의 Info.plist에서 NSExtensionActivationRule 키를 통해 등록되며, 어떤 콘텐츠 유형이 확장 기능을 활성화하는지 지정합니다. 사진 편집기의 경우 ActivationRule은 일반적으로 image를 필요로 합니다 — 확장 기능은 비디오 또는 Live Photos에는 나타나지 않습니다.
Apple은 편집 메뉴를 과부하하지 않도록 구체적인 활성화 유형을 지정할 것을 권장합니다. 확장 기능이 JPEG 및 HEIC만 지원하는 경우 활성화를 이러한 형식으로 제한하는 것이 좋습니다.
<!-- Info.plist -->
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.photo-editing</string>
<key>NSExtensionActivationRule</key>
<string>SUBQUERY (extensionItems,
@count <= 1)</string>
</dict>
확장 기능을 선택하면 iOS는 사진 인터페이스 위에 표시되는 사용자 정의 UIViewController와 함께 별도의 프로세스를 만듭니다. 사용자는 자신의 사진, 확장 기능 도구 및 취소/완료 버튼을 볼 수 있습니다. 확장 기능은 자체 컨트롤러 외부의 탐색을 변경하거나 시스템의 다른 부분에 액세스할 수 없습니다.
Apple의 Human Interface Guidelines에 따르면 확장 기능 인터페이스는 광고, 외부 링크 또는 불필요한 탐색 요소 없이 최소화되고 기능적이어야 합니다. 화면을 어지럽히지 않도록 도구 팔레트를 표시하려면 UIScrollView를 사용하는 것이 좋습니다.
자주 묻는 질문
확장 기능은 beginContentEditing(with:) 메서드를 통해 전체 이미지 파일의 URL과 함께 PHContentEditingInput을 수신합니다. 선택한 하나의 사진에만 액세스가 허용됩니다 — 다른 라이브러리 리소스에 대한 권한은 없습니다.
아니요, 원본은 절대 수정되지 않습니다. 확장 기능은 PHContentEditingOutput을 통해 새 버전을 생성하고 AdjustmentData는 원래 상태로 되돌릴 수 있는 변경 매개변수를 저장합니다.
확장 기능은 PhotoKit이 지원하는 모든 형식(JPEG, HEIC, RAW, PNG, TIFF 및 Live Photos)에서 작동합니다. 제한 사항은 확장 기능의 Info.plist에서 NSExtensionActivationRule을 통해 설정됩니다.
iOS는 finishContentEditing 작업에 최대 30초를 할당합니다. 제한 시간을 초과하면 확장 기능이 강제로 종료되고 변경 사항이 저장되지 않습니다. CIFilter를 사용한 백그라운드 처리는 이 시간을 연장하지 않습니다.
네, Core Image(CIFilter)와 Metal(사용자 정의 셰이더용)이 완전히 지원됩니다. Apple은 Grand Central Dispatch를 통해 무거운 계산을 백그라운드 스레드로 오프로드할 것을 권장합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.