Photo Editing Extension is an iOS mechanism that allows third-party apps to add editing tools directly into the system Photos app. Unlike full-featured editors, the extension does not load the photo into a separate app — the user applies filters, adjusts colors, or adds effects without leaving the standard interface. According to Apple Developer Documentation (2025), PhotoKit provides over 40 APIs for working with photo resources, including PHAdjustmentData and PHContentEditingController.
Key Takeaways
Photo Editing Extension is a type of app extension in iOS that embeds image processing tools into the standard interface of the Photos app. The user opens a photo, taps the Edit button, and selects the desired extension from the list of installed ones. After editing, the result is saved back to the library, and the original file remains available for reverting.
This architecture solves a key user experience problem: there is no need to switch between apps, export and import images, or keep track of versions. According to WWDC 2025, all extensions run in an isolated process with their own sandbox and limited execution time — up to 30 seconds per editing operation.
The extension does not have access to arbitrary files in the device memory — only to the photo that the user explicitly passed through the selection interface. This ensures the security of user data when using third-party tools.
PhotoKit is an Apple framework for working with the device media library, introduced in iOS 8. It provides programmatic access to Photos resources, including images, videos, albums, and metadata. For editing extensions, PhotoKit serves as an intermediary layer between storage and the modification interface.
PHAsset represents an individual media object in the library — a photo or video. Through PHAsset, you can obtain metadata: capture date, file type, location on the map, and camera orientation. PHAssetResource provides access to underlying resources — for example, to the original photo file in RAW or HEIC format.
For an editing extension, PHContentEditingInput is critically important — an object that contains the full image (or video) file available for reading and processing. The extension receives this object at activation time and uses it as source material.
PHImageManager manages image loading and caching. For an editing extension, it is not used directly — the extension receives the full file via PHContentEditingInput. However, PHImageRequestOptions allows you to configure request parameters: size, delivery type (synchronous or asynchronous), and result format.
According to Apple, PHImageManager automatically caches image thumbnails in RAM, which speeds up repeated preview display. For editing extensions, it is recommended to use PHImageRequestOptionsDeliveryModeHighQualityFormat to get the best image quality.
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
}
Each Photo Editing Extension implements the PHContentEditingController protocol — the central control element of the extension. The protocol defines methods for displaying the interface, receiving input data, and saving the result.
beginContentEditing(with:) is called when the editing session starts. The extension receives PHContentEditingInput and must display the interface with the original image. finishContentEditing(completionHandler:) completes the editing — the extension returns PHContentEditingOutput with the modified file and AdjustmentData. cancelContentEditing() cancels changes without saving.
An important nuance: at the time of beginContentEditing call, the extension gets access only to one version of the photo — the one that was requested by the user. It cannot access another photo or album. This is a sandbox restriction introduced by Apple for security.
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 separates the editing interface from the saving logic. The main iOS process calls beginContentEditing, the extension shows its UI, the user makes changes, then finishContentEditing generates a new file. Apple recommends performing all resource-intensive processing — CIFilter filters, Core Image manipulations — in a background thread, not the main one, to avoid blocking the interface.
PHAdjustmentData is the key mechanism that enables non-destructive editing in Photo Editing Extension. It is an object that contains information about applied changes in an arbitrary format. The extension serializes filter parameters, masks, and settings into AdjustmentData and saves them along with the modified image.
When the photo is reopened, the extension reads AdjustmentData, restores the previous interface state, and allows the user to continue editing from the same point. If the extension is not installed, the photo is displayed in the last saved version, while the original is stored separately.
According to Apple Documentation, PHAdjustmentData stores formatIdentifier and formatVersion — strings for identifying the data format. When updating the extension, you should check the version and correctly handle old formats.
let adjustmentData = PHAdjustmentData(
formatIdentifier: "com.example.photoediting",
formatVersion: "1.0",
data: NSKeyedArchiver.archivedData(
withRootObject: params,
requiringSecureCoding: true
)
)
output.adjustmentData = adjustmentData
At the moment of finishContentEditing, the extension writes AdjustmentData to the PHContentEditingOutput object along with the modified image file. The system then saves both components: the version for display and the metadata for restoring the editing session.
Photo Editing Extension automatically appears in the Photos app menu after installing the app that contains it. The user opens a photo, selects Edit, and all installed editing extensions — both system and third-party — are displayed in the bottom row of tools.
The extension is registered through the main app's Info.plist with the NSExtensionActivationRule key, which specifies what types of content activate the extension. For a photo editor, ActivationRule typically requires image — the extension will not appear for videos or Live Photos.
Apple recommends specifying specific activation types to avoid overloading the editing menu. If the extension only supports JPEG and HEIC, it is worth limiting activation to these formats.
<!-- 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>
After selecting an extension, iOS creates a separate process with a custom UIViewController that is displayed on top of the Photos interface. The user sees their photo, the extension tools, and Cancel/Done buttons. The extension cannot change navigation outside its own controller or access other parts of the system.
According to Apple's Human Interface Guidelines, the extension interface should be minimal and functional — without ads, extraneous links, or unnecessary navigation elements. It is recommended to use UIScrollView to display the tool palette so as not to clutter the screen.
Frequently Asked Questions
The extension receives PHContentEditingInput with the URL of the full image file via the beginContentEditing(with:) method. Access is granted only to the one selected photo — without rights to other library resources.
No, the original is never modified. The extension creates a new version via PHContentEditingOutput, and AdjustmentData stores the change parameters for the ability to revert to the original state.
The extension works with all formats supported by PhotoKit: JPEG, HEIC, RAW, PNG, TIFF, and Live Photos. Limitations are set via NSExtensionActivationRule in the extension's Info.plist.
iOS allocates up to 30 seconds for the finishContentEditing operation. If the limit is exceeded, the extension is forcibly terminated and changes are not saved. Background processing with CIFilter does not extend this time.
Yes, Core Image (CIFilter) and Metal (for custom shaders) are fully supported. Apple recommends offloading heavy computations to background threads via Grand Central Dispatch.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also