Я разрабатываю расширение для редактирования фотографий для iOS, включенное в контейнерное приложение, которое обеспечивает те же функции редактирования фотографий.
Для повторного использования кода у меня есть класс контроллера представления, который принимает требуемый *Протокол 1003 *, и я разделил его на подклассы для использования как в качестве основного интерфейса расширения приложения, так и в качестве «рабочего экрана» приложения контейнера.
О редактированиирасширение, методы контроллера вызываются сеансом редактирования приложения Photos, как описано в документации Apple и различных руководствах, которые можно найти в Интернете.
В приложении контейнера, , с другой стороны, я сначала получаю экземпляр PHAsset
с помощью класса UIImagePickerController
и напрямую запускаю сеанс редактирования на моем контроллере представления "работа", например:
// 'work' is my view controller which adopts
// `PHContentEditingController`. 'workNavigation'
// embeds it.
let options = PHContentEditingInputRequestOptions()
options.canHandleAdjustmentData = { (adjustmentData) in
return work.canHandle(adjustmentData)
}
asset.requestContentEditingInput(with: options, completionHandler: { [weak self] (input, options) in
// (Called on the Main thread on iOS 10.0 and above)
guard let this = self else {
return
}
guard let editingInput = input else {
return
}
work.asset = asset
work.startContentEditing(with: editingInput, placeholderImage: editingInput.displaySizeImage!)
this.present(workNavigation, animated: true, completion: nil)
})
Когда пользователь заканчивает редактирование , контроллер рабочего представления вызывает finishContentEditing(completionHandler:
для себя, чтобы завершить сеанс:
self.finishContentEditing(completionHandler: {(output) in
// nil output results in "Revert" prompt.
// non-nil output results in "Modify" prompt.
let library = PHPhotoLibrary.shared()
library.performChanges({
let request = PHAssetChangeRequest(for: self.asset)
request.contentEditingOutput = output
}, completionHandler: {(didSave, error) in
if let error = error {
// handle error...
} else if didSave {
// proceed after saving...
} else {
// proceed after cancellation...
}
})
})
В пределахВо время сеанса редактирования пользователь может «очистить» предыдущие правки, переданные как данные корректировки , эффективно вернув изображение в исходное состояние.Я заметил, что если я закончу редактирование, вызвав обработчик завершения, переданный в finishContentEditing(completionHandler:)
с nil
в качестве аргумента (вместо действительного PHContentEditingOutput
объекта), среда Photoshop предложит пользователю «вернуться»изображение вместо «изменения» его:
func finishContentEditing(completionHandler: @escaping (PHContentEditingOutput?) -> Void) {
guard let editingInput = self.editingInput, let inputURL = editingInput.fullSizeImageURL else {
return completionHandler(nil)
}
if editingInput.adjustmentData != nil && hasUnsavedEdits == false {
// We began with non-nil adjustment data but now have
// no outstanding edits - means REVERT:
return completionHandler(nil)
}
// (...proceed with writing output to url...)
Однако это работает только при запуске из приложения контейнера. Если я попробую тот же трюк с расширением (т.е. загрузить изображение, которое содержит предыдущие изменения, сбросить их и нажать «Готово») Я получаю страшное «Невозможно сохранить изменения» сообщение ...
Как правильно вернуть предыдущие изменения в изображение из расширения для редактирования фотографий?