IOS - UIImageWriteToSavedPhotosAlbum
Я хотел использовать следующий API-интерфейс void для записи захваченного изображения в фотоальбом, но я не очень понимаю о 2 параметрах
UIImageWriteToSavedPhotosAlbum (
UIImage *image,
id completionTarget,
SEL completionSelector,
void *contextInfo
);
Из объяснения от АЦП:
completionTarget:
необязательный; объект, селектор которого следует вызывать после изображения, был записан в альбом Camera Roll.
completionSelector:
селектор метода объекта завершенияTarget. Этот необязательный метод должен соответствовать следующей сигнатуре:
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo: (void *) contextInfo;
В чем смысл completionTarget
здесь? Может ли кто-нибудь объяснить пример использования этого параметра? Или любой ресурс, который может помочь мне в этом.
Ответы
Ответ 1
-
completionSelector
- это селектор (метод) для вызова, когда запись изображения завершена.
-
completionTarget
- это объект, для которого можно вызвать этот метод.
В общем:
- Либо вам не нужно получать уведомления, когда запись изображения завершена (во многих случаях это не полезно), поэтому вы используете
nil
для обоих параметров
- Или вы действительно хотите, чтобы вас уведомили, когда файл изображения был записан в фотоальбом (или закончил с ошибкой записи), и в этом случае вы обычно реализуете обратный вызов (= метод для вызова при завершении) в том же классе, из которого вы вызвали функцию
UIImageWriteToSavedPhotosAlbum
, поэтому completionTarget
будет обычно self
Как указано в документации, completionSelector
- это селектор, представляющий метод с сигнатурой, описанной в документации, поэтому он должен иметь подпись типа:
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo: (void *) contextInfo;
Он не должен иметь это точное имя, но он должен использовать одну и ту же подпись, а именно взять 3 параметра (первый из которых - UIImage
, второй a NSError
и третий тип void*
) и не возвращать ничего (void
).
Пример
Вы можете, например, объявить и реализовать метод, который вы могли бы назвать следующим:
- (void)thisImage:(UIImage *)image hasBeenSavedInPhotoAlbumWithError:(NSError *)error usingContextInfo:(void*)ctxInfo {
if (error) {
// Do anything needed to handle the error or display it to the user
} else {
// .... do anything you want here to handle
// .... when the image has been saved in the photo album
}
}
И когда вы вызываете UIImageWriteToSavedPhotosAlbum
, вы будете использовать его следующим образом:
UIImageWriteToSavedPhotosAlbum(theImage,
self, // send the message to 'self' when calling the callback
@selector(thisImage:hasBeenSavedInPhotoAlbumWithError:usingContextInfo:), // the selector to tell the method to call on completion
NULL); // you generally won't need a contextInfo here
Обратите внимание на множественный ':' в синтаксисе @selector(...)
. Двоеточия являются частью имени метода, поэтому не забудьте добавить эти ":" в @selector (событие для тренировки) при написании этой строки!
Ответ 2
Вызов UIImageWriteToSavedPhotosAlbum в современных iOS и Swift
В современной iOS существует дополнительное требование для использования UIImageWriteToSavedPhotosAlbum. Вы должны включить в свой Info.plist ключ NSPhotoLibraryAddUsageDescription
("Конфиденциальность - описание использования дополнений библиотеки фотографий"). Это сделано для того, чтобы система могла предоставить пользователю диалоговое окно, запрашивающее разрешение на запись в рулон камеры.
Затем вы можете вызвать UIImageWriteToSavedPhotosAlbum в своем коде:
func myFunc() {
let im = UIImage(named:"smiley.jpg")!
UIImageWriteToSavedPhotosAlbum(im, self, #selector(savedImage), nil)
}
Последний параметр, контекст, обычно будет равен nil
.
Идея второго двух параметров, self
и #selector(savedImage)
, является то, что ваш savedImage
метод в self
перезвонят после того, как изображение будет сохранено (или не сохранены). Этот метод должен выглядеть примерно так:
@objc func savedImage(_ im:UIImage, error:Error?, context:UnsafeMutableRawPointer?) {
if let err = error {
print(err)
return
}
print("success")
}
Типичная ошибка: пользователь отказывает в разрешении в системном диалоге. Если все пойдет хорошо, ошибка будет равна nil
и вы будете знать, что запись прошла успешно.
Ответ 3
SWIFT VERSION на основе решения AliSoftware
UIImageWriteToSavedPhotosAlbum(
yourImage,
self, // send the message to 'self' when calling the callback
#selector(image(path:didFinishSavingWithError:contextInfo:)), // the selector to tell the method to call on completion
nil // you generally won't need a contextInfo here
)
@objc private func image(path: String, didFinishSavingWithError error: NSError?, contextInfo: UnsafeMutableRawPointer?) {
if ((error) != nil) {
// Do anything needed to handle the error or display it to the user
} else {
// .... do anything you want here to handle
// .... when the image has been saved in the photo album
}
}
Ответ 4
Вкратце: как упомянуто в документации Apple здесь: UIImageWriteToSavedPhotosAlbum (: :)
завершениеВыбор Селектор метода объекта завершение-объекта для вызова. Этот необязательный метод должен соответствовать следующей подписи:
- (void)image:(UIImage *)image
didFinishSavingWithError:(NSError *)error
contextInfo:(void *)contextInfo;
Так что ваша функция обратного вызова в Swift должна быть что-то вроде
@objc func imageSaved(image:UIImage,didFinishSavingWithError error:Error,contextInfo:UnsafeMutableRawPointer?){
self.showAlert(title:"Image saved to Photos!", message: "");
}