Search code examples
iosuiimageswift3nsdatauiimagepngrepresentation

From raw data to UIImagePNGRepresentation in fewer steps


Using this code, I extract an image from a Share Extension and I write it to a directory I created in an App Group.

let content = self.extensionContext!.inputItems[0] as! NSExtensionItem

   let contentType = kUTTypeImage as String

      for attachment in content.attachments as! [NSItemProvider] {

         if attachment.hasItemConformingToTypeIdentifier(contentType) {

            attachment.loadItem(forTypeIdentifier: contentType, options: nil) { data, error in

            // from here
            if error == nil {

               let url = data as! NSURL
               let originalFileName = url.lastPathComponent

               if let imageData = NSData(contentsOf: url as URL) {

                  let img = UIImage(data:imageData as Data)

                  if let data = UIImagePNGRepresentation(img!) {
                     // write, etc.
                                    }

                                }
                            }

                        }

Anything is working fine.

What I'd like to know is if it is possible to reduce some code: in particular, after if error == nil, I:

  • cast data to NSURL;
  • use NSURL to get a NSData;
  • use NSData to get a UIImage;
  • use UIImage to get a UIImagePNGRepresentation;

Aside from avoiding the creation of the imageData variable, isn't there a way to (safely) achieve the same goal with fewer steps?


Solution

  • First of all you need to use native Data and URL instead of NSData & NSURL also if you want to write file in DocumentDirectory then you can directly use that imageData no need to make UIImage object from it and then convert it to data using UIImagePNGRepresentation.

    if let url = data as? URL, error == nil {
    
        let originalFileName = url.lastPathComponent
        if let imageData = try? Data(contentsOf: data) {
            // write, etc.
            var destinationURL  = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
            destinationURL.appendPathComponent("fileName.png")
            try? imageData.write(to: destinationURL)
        }
    }