Подтвердить что ты не робот

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 здесь? Может ли кто-нибудь объяснить пример использования этого параметра? Или любой ресурс, который может помочь мне в этом.

4b9b3361

Ответ 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: "");
    }