Photo Editing Extension — to mechanizm iOS, który pozwala aplikacjom zewnętrznym dodawać narzędzia edycyjne bezpośrednio w systemowej aplikacji Zdjęcia. W przeciwieństwie do pełnoprawnych edytorów, rozszerzenie nie ładuje zdjęcia do osobnej aplikacji — użytkownik stosuje filtry, koryguje kolory lub nakłada efekty bez wychodzenia ze standardowego interfejsu. Według Apple Developer Documentation (2025), PhotoKit udostępnia ponad 40 API do pracy z zasobami zdjęć, w tym PHAdjustmentData i PHContentEditingController.
Najważniejsze
Photo Editing Extension — to rodzaj app extension w iOS, który wprowadza narzędzia do obróbki obrazów w standardowy interfejs aplikacji Zdjęcia. Użytkownik otwiera zdjęcie, naciska przycisk „Edytuj” i wybiera odpowiednie rozszerzenie z listy zainstalowanych. Po edycji wynik jest zapisywany z powrotem w bibliotece, a oryginalny plik pozostaje dostępny do przywrócenia.
Taka architektura rozwiązuje kluczowy problem doświadczenia użytkownika: nie trzeba przełączać się między aplikacjami, eksportować i importować obrazów ani śledzić wersji. Według WWDC 2025, wszystkie rozszerzenia działają w izolowanym procesie z własnym sandboxem i ograniczonym czasem wykonania — do 30 sekund na operację edycji.
Rozszerzenie nie ma dostępu do dowolnych plików w pamięci urządzenia — tylko do tego zdjęcia, które użytkownik jawnie przekazał przez interfejs wyboru. Zapewnia to bezpieczeństwo danych użytkownika przy korzystaniu z narzędzi zewnętrznych.
PhotoKit — to framework Apple do pracy z biblioteką multimediów urządzenia, wprowadzony w iOS 8. Zapewnia programowy dostęp do zasobów Zdjęć, w tym zdjęć, wideo, albumów i metadanych. Dla rozszerzeń edycji PhotoKit służy jako warstwa pośrednia między magazynem a interfejsem modyfikacji.
PHAsset reprezentuje pojedynczy obiekt multimedialny w bibliotece — zdjęcie lub wideo. Poprzez PHAsset można uzyskać metadane: datę wykonania, typ pliku, lokalizację na mapie i orientację kamery. PHAssetResource daje dostęp do podstawowych zasobów — na przykład do oryginalnego pliku zdjęcia w formacie RAW lub HEIC.
Dla rozszerzenia edycji krytycznie ważny jest PHContentEditingInput — obiekt, który zawiera pełny plik obrazu (lub wideo) dostępny do odczytu i przetwarzania. Rozszerzenie otrzymuje ten obiekt w momencie aktywacji i używa go jako materiału źródłowego.
PHImageManager zarządza ładowaniem i buforowaniem obrazów. Dla rozszerzenia edycji nie jest używany bezpośrednio — rozszerzenie otrzymuje pełny plik przez PHContentEditingInput. Jednak PHImageRequestOptions pozwala skonfigurować parametry zapytania: rozmiar, typ dostawy (synchroniczny lub asynchroniczny) i format wyniku.
Według Apple, PHImageManager automatycznie buforuje miniatury obrazów w pamięci RAM, co przyspiesza ponowne wyświetlanie podglądów. Dla rozszerzenia edycji zaleca się używanie PHImageRequestOptionsDeliveryModeHighQualityFormat, aby uzyskać najlepszą jakość zdjęcia.
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
// użyj obrazu do wyświetlenia
}
Każde Photo Editing Extension implementuje protokół PHContentEditingController — centralny element sterowania rozszerzeniem. Protokół definiuje metody wyświetlania interfejsu, pobierania danych wejściowych i zapisywania wyniku.
beginContentEditing(with:) jest wywoływane przy uruchomieniu sesji edycji. Rozszerzenie otrzymuje PHContentEditingInput i powinno wyświetlić interfejs z oryginalnym obrazem. finishContentEditing(completionHandler:) kończy edycję — rozszerzenie zwraca PHContentEditingOutput z zmodyfikowanym plikiem i AdjustmentData. cancelContentEditing() anuluje zmiany bez zapisywania.
Ważny niuans: w momencie wywołania beginContentEditing rozszerzenie otrzymuje dostęp tylko do jednej wersji zdjęcia — tej, którą zażądał użytkownik. Nie można uzyskać dostępu do innego zdjęcia lub albumu. To ograniczenie sandboxa wprowadzone przez Apple dla bezpieczeństwa.
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 oddziela interfejs edycji od logiki zapisywania. Główny proces iOS wywołuje beginContentEditing, rozszerzenie pokazuje swój UI, użytkownik wprowadza zmiany, następnie finishContentEditing generuje nowy plik. Apple zaleca całe zasobożerne przetwarzanie — filtry CIFilter, manipulacje Core Image — wykonywać w tle, a nie w głównym wątku, aby nie blokować interfejsu.
PHAdjustmentData — kluczowy mechanizm zapewniający edycję nieniszczącą w Photo Editing Extension. To obiekt zawierający informacje o zastosowanych zmianach w dowolnym formacie. Rozszerzenie serializuje parametry filtrów, maski i ustawienia w AdjustmentData i zapisuje wraz z zmodyfikowanym obrazem.
Przy ponownym otwarciu zdjęcia rozszerzenie odczytuje AdjustmentData, przywraca poprzedni stan interfejsu i pozwala użytkownikowi kontynuować edycję od tego samego miejsca. Jeśli rozszerzenie nie jest zainstalowane — zdjęcie wyświetla się w ostatniej zapisanej wersji, a oryginał jest przechowywany osobno.
Według Apple Documentation, PHAdjustmentData przechowuje formatIdentifier i formatVersion — ciągi do identyfikacji formatu danych. Przy aktualizacji rozszerzenia należy sprawdzać wersję i poprawnie obsługiwać stare formaty.
let adjustmentData = PHAdjustmentData(
formatIdentifier: "com.example.photoediting",
formatVersion: "1.0",
data: NSKeyedArchiver.archivedData(
withRootObject: params,
requiringSecureCoding: true
)
)
output.adjustmentData = adjustmentData
W momencie finishContentEditing rozszerzenie zapisuje AdjustmentData w obiekcie PHContentEditingOutput wraz z zmodyfikowanym plikiem obrazu. System następnie zapisuje oba komponenty: wersję do wyświetlania i metadane do przywrócenia sesji edycji.
Photo Editing Extension automatycznie pojawia się w menu aplikacji Zdjęcia po instalacji zawierającej go aplikacji. Użytkownik otwiera zdjęcie, wybiera „Edytuj”, a w dolnym rzędzie narzędzi wyświetlane są wszystkie zainstalowane rozszerzenia edycji — zarówno systemowe, jak i zewnętrzne.
Rozszerzenie rejestruje się przez Info.plist głównej aplikacji z kluczem NSExtensionActivationRule, który określa, jakie typy treści aktywują rozszerzenie. Dla edytora zdjęć ActivationRule zwykle wymaga image — rozszerzenie nie będzie wyświetlane dla wideo lub żywych zdjęć.
Apple zaleca określanie konkretnych typów aktywacji, aby nie obciążać menu edycji. Jeśli rozszerzenie obsługuje tylko JPEG i HEIC, warto ograniczyć aktywację do tych formatów.
<!-- 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>
Po wyborze rozszerzenia iOS tworzy osobny proces z niestandardowym UIViewController, który wyświetla się nad interfejsem Zdjęć. Użytkownik widzi swoje zdjęcie, narzędzia rozszerzenia i przyciski „Anuluj” / „Gotowe”. Rozszerzenie nie może zmienić nawigacji poza swoim kontrolerem ani uzyskać dostępu do innych części systemu.
Według Human Interface Guidelines od Apple, interfejs rozszerzenia powinien być minimalny i funkcjonalny — bez reklam, zewnętrznych linków i zbędnych elementów nawigacji. Zaleca się używanie UIScrollView do wyświetlania palety narzędzi, aby nie zagracać ekranu.
Często zadawane pytania
Rozszerzenie otrzymuje PHContentEditingInput z URL pełnego pliku obrazu przez metodę beginContentEditing(with:). Dostęp jest udzielany tylko do jednego wybranego zdjęcia — bez praw do innych zasobów biblioteki.
Nie, oryginał nigdy nie jest zmieniany. Rozszerzenie tworzy nową wersję przez PHContentEditingOutput, a AdjustmentData przechowuje parametry zmian umożliwiające przywrócenie do stanu pierwotnego.
Rozszerzenie działa ze wszystkimi formatami obsługiwanymi przez PhotoKit: JPEG, HEIC, RAW, PNG, TIFF i Live Photos. Ograniczenia są ustawiane przez NSExtensionActivationRule w Info.plist rozszerzenia.
iOS przydziela do 30 sekund na wykonanie operacji finishContentEditing. Po przekroczeniu limitu rozszerzenie jest przymusowo zamykane, a zmiany nie są zapisywane. Przetwarzanie w tle z CIFilter nie wydłuża tego czasu.
Tak, Core Image (CIFilter) i Metal (dla niestandardowych shaderów) są w pełni obsługiwane. Apple zaleca przenoszenie ciężkich obliczeń do wątków tła przez Grand Central Dispatch.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również