banner



How To Pick Image From Camera Roll Swift

Writing an image to the photographic camera gyre is adequately simple in iOS development, simply when information technology comes to detecting when the image has been written to the camera scroll, it is not as simple as we think. Surprisingly, Apple tree does not give us any closure-based APIs that we can leverage to know exactly when the write functioning is completed.

To get the job done, we must make utilise of some APIs created mode back in Objective-C fourth dimension. Permit'south buckle up and get ready to deal with some old schoolhouse UIKit API that involves target, selector and UnsafeRawPointer.


Getting Write Admission to Camera Roll

Before we can start writing images to the camera coil, it is mandatory to obtain a write permission from the users. As you might take expected, we demand to add the NSPhotoLibraryAddUsageDescription key into "info.plist" and provide a reason why we desire to admission the camera roll.

Getting camera roll write permission in iOS
Adding NSPhotoLibraryAddUsageDescription key into "info.plist"

Our app will crash with the following error message if we try to access the camera curlicue without the user's permission.

                      This app has crashed considering it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryAddUsageDescription cardinal with a cord value explaining to the user how the app uses this data.                  

With that out of the mode, information technology'due south time to write some images to the camera roll.


Detecting Camera Curlicue Write Operation Completion

Writing an image to the camera roll merely required i line of code:

          UIImageWriteToSavedPhotosAlbum(image, nil, nada, nix)        

This unmarried line of code will trigger a background operation that writes a given image to the camera roll. If we take a look at the function announcement:

          func UIImageWriteToSavedPhotosAlbum(_ image: UIImage,                                      _ completionTarget: Any?,                                      _ completionSelector: Selector?,                                      _ contextInfo: UnsafeMutableRawPointer?)        

You volition detect that the 2d and 3rd parameters are what we need in lodge to detect when an image is successfully written to the camera scroll.

The completionTarget is the object whose selector should exist chosen afterwards the image has been written to the camera roll. Whereas the completionSelector is the method selector of thecompletionTarget object to telephone call and information technology must conform to the following signature:

          func image(_ paradigm: UIImage,            didFinishPhotoLibrarySavingWithError error: Fault?,            contextInfo: UnsafeRawPointer)        

With that in mind, detecting the completion of the write operation should exist adequately straightforward:

          func writeImageToCameraRoll(_ image: UIImage) {          UIImageWriteToSavedPhotosAlbum(         image,         cocky,         #selector(image(_:didFinishPhotoLibrarySavingWithError:contextInfo:)),         cypher     ) }  /// This will trigger when finish writing ane image to photo library @objc private func image(_ paradigm: UIImage,                          didFinishPhotoLibrarySavingWithError error: Error?,                          contextInfo: UnsafeRawPointer) {          print("Image successfully written to camera coil") }        

Make sure to mark the completion selector with the @objc attribute. This is to permit the compiler know that nosotros want to interact with the Objective-C runtime.

That's it! That's how we tin detect an image has been successfully written to the camera roll.

Now, imagine a situation where nosotros want to write multiple images to the photographic camera gyre, and we want to know exactly when each private image has been successfully saved. How should we go about that? This is where the 4th parameter (contextInfo) comes into play.


Passing Information Using UnsafeRawPointer

If Swift is the commencement linguistic communication you use for iOS development, most likely you accept non used or seen UnsafeRawPointer earlier. In fact, it is not that commonly used in Objective-C either. Therefore, I call back information technology is not worth information technology to spend time explaining what an UnsafeRawPointer is. Instead, I will focus on showing yous how to employ UnsafeRawPointer in this specific utilise case.

Permit's say all the images that we are writing to the camera roll have a unique ID. So we can pass this ID to the completion selector and employ it to place the image that triggers the selector.

First, allow's create a simple class to hold this unique ID:

          last class CameraRollContext {     permit imageId: String          init(imageId: String) {         self.imageId = imageId     } }        

Note that CameraRollContext must be a reference blazon so that nosotros can convert it to become UnsafeRawPointer and pass it into UIImageWriteToSavedPhotosAlbum() like so:

          let context = CameraRollContext(imageId: imageId)  // Convert CameraRollContext to UnsafeRawPointer let rawPointer = UnsafeMutableRawPointer(Unmanaged.passRetained(context).toOpaque())  UIImageWriteToSavedPhotosAlbum(     prototype,     self,     #selector(paradigm(_:didFinishPhotoLibrarySavingWithError:contextInfo:)),     rawPointer )        

The UnsafeRawPointer that we pass in will and so be given back to usa as contextInfo in the completion selector. With that, all that'southward left to do is catechumen contextInfo back to CameraRollContext.

          @objc private func image(_ prototype: UIImage,                          didFinishPhotoLibrarySavingWithError error: Error?,                          contextInfo: UnsafeRawPointer) {          // Convert contextInfo to CameraRollContext     let context: CameraRollContext = Unmanaged<CameraRollContext>.fromOpaque(contextInfo).takeRetainedValue()     let imageId = context.imageId      print("\(imageId) successfully written to camera ringlet") }        

Creating a Wrapper Form for Writing Images

If y'all feel that the sample code above is not Swifty and hard to read, there is zip stopping you from creating your ain wrapper course that triggers a closure-based callback when an image is written to the camera whorl.

Nevertheless, do go on in mind that your wrapper course must be a bracket of NSObject. Failing to do so volition give you the post-obit runtime error when writing images to the camera roll:

                      NSForwarding: alarm: object 0x280d3b120 of class 'DemoProject.CameraRollWrapperClass' does not implement methodSignatureForSelector: -- trouble ahead Unrecognized selector -[DemoProject.CameraRollWrapperClass methodSignatureForSelector:]                  

Wrapping Upwardly

There you lot have it! If you find this article helpful, I think you will enjoy reading the following articles as well:

  • How to Manage Photo Library Permission in iOS
  • Reducing Memory Footprint When Using UIImage

Feel complimentary to follow me on Twitter, and subscribe to my monthly newsletter and so that you won't miss out on any of my upcoming iOS evolution-related articles

Thanks for reading. 👨🏻‍💻


[Updated: 26 March 2022]

Kudos to Filip Nemecek for pointing out that Apple does in fact provide closure-based APIs for writing images to camera roll. Make sure to check out his blog mail service to discover out more.


Source: https://swiftsenpai.com/development/write-images-to-camera-roll/

Posted by: preusserforthand.blogspot.com

0 Response to "How To Pick Image From Camera Roll Swift"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel