I wanted to use the following void API to write a captured image to the photo album but I am not very clear about 2 of the parameters
UIImageWriteToSavedPhot
In modern iOS, there is an additional requirement for using UIImageWriteToSavedPhotosAlbum. You have to include in your Info.plist a key NSPhotoLibraryAddUsageDescription ("Privacy - Photo Library Additions Usage Description"). This is so that the system can present the user with a dialog requesting permission to write into the camera roll.
You can then call UIImageWriteToSavedPhotosAlbum in your code:
func myFunc() {
let im = UIImage(named:"smiley.jpg")!
UIImageWriteToSavedPhotosAlbum(im, self, #selector(savedImage), nil)
}
The last parameter, the context, will usually be nil.
The idea of the second two parameters, self and #selector(savedImage), is that your savedImage method in self will be called back after the image is saved (or not saved). That method should look something like this:
@objc func savedImage(_ im:UIImage, error:Error?, context:UnsafeMutableRawPointer?) {
if let err = error {
print(err)
return
}
print("success")
}
A typical error would be if the user refused permission in the system dialog. If all goes well, the error will be nil and you'll know that the write succeeded.
In general, UIImageWriteToSavedPhotosAlbum should probably be avoided, in favor of the Photos framework. However, it's a simple way to get the job done.
completionSelector is the selector (method) to call when the writing of the image has finished.completionTarget is the object on which to call this method.Generally:
nil for both parametersUIImageWriteToSavedPhotosAlbum function from, so the completionTarget will generally be selfAs the documentation states, the completionSelector is a selector representing a method with the signature described in the documentation, so it has to have a signature like:
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo: (void *) contextInfo;
It does not have to have this exact name, but it has to use the same signature, namely take 3 parameters (the first being an UIImage, the second an NSError and the third being of void* type) and return nothing (void).
You may for example declare and implement a method that you could call anything like this :
- (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
}
}
And when you call UIImageWriteToSavedPhotosAlbum you will use it like this:
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
Note the multiple ':' in the @selector(...) syntax. The colons are part of the method name so don't forget to add these ':' in the @selector (event the trainling one) when you write this line!
SWIFT VERSION based on AliSoftware solution
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
}
}