How to obtain photo data/metadata after being picked in PHPickerViewController?

Hi there,

In the app I work on, I am being tasked with a requirement to present the user their device photos using a PHPickerViewController.

Once selected, I need access to:
  1. The raw image data

  2. The file name of the image

  3. The creation date of the image

This is simple to do with a PHAsset if I had full access to the user's photos - I could use the PHPickerViewController result value which includes photoIdentifiers to query PhotoKit for the PHAssets. However, there is no guarantee that I have full access. Additionally if the user has granted no access or limited access, and the limited selection does not include the photos being selected in the PHPickerViewController, I won't be able to query for them. (I tried this, and as expected the result of the query is nil, which makes sense).

The UIImage that I can obtain is only a proxy of the original image data (missing things like exif data, etc), so that is not sufficient for the user case my app has. Assuming there was an item provider for data, I'd still need to get information such as file name and creation date as well though.


So, is there a way to obtain this information?

Thanks!
Post not yet marked as solved Up vote post of ZOlbrys Down vote post of ZOlbrys
5k views

Replies

If you check the NSItemProvider from PHPickerResult, you will see that it has "suggestedName" property. This will be your file name.

I don't have any additional information about raw image data and creation date, sorry.
As mentioned above you can get the suggested name for the file name.
If you want the raw image data, you can load the file representation or the data respresentation.
For some strange reason, when I use 'file representation' loading, the app does not have the proper permissions to work on the file at the returned URL. I had to copy the file to a temp location and work on the copied URL. Not sure if this is intentional or an oversight bug. Below is the sort of code I needed to use:

NSString *allFiles = @"public.item";
_ _block PHPickerResult *blockResult = result;

_ _block NSMutableArray <NSURL *>*blockFileURLArray = [NSMutableArray array];

 for (PHPickerResult *result in results){

[result.itemProvider loadFileRepresentationForTypeIdentifier: allFiles
                                                   completionHandler:^(NSURL * Nullable url,
                                                                       NSError *
Nullable error) {
            if (error) {
                    // TODO
                    // show alert

                NSLog(@"error %@", error);

            } else {

                    // for some reason, I cannot access the url for uploading
                    // need to copy the file to a temp location

                NSString *filename = url.lastPathComponent;

                NSString *path = [NSString temporaryPathByUsingFileName: [filename stringByDeletingPathExtension]
                                                          pathExtension: filename.pathExtension];

                NSURL *copyURL = [NSURL fileURLWithPath: path];

                NSError *copyError;

                [NSFileManager.defaultManager copyItemAtURL: url
                                                      toURL: copyURL
                                                      error: &copyError];

                if (copyError) {
                    NSLog(@"%@ copyError %@", self, error);
                } else {

// can now do stuff to the file at copyURL
// store it in the files array

                    [blockFileURLArray addObject: copyURL];

                }

            }
}

// do stuff on the gathered files in blockFileURLArray


Is the error only happening when running in the Simulator or also on a device?
I am also trying to get the creation date and the location of where the photo was taken. We were able to do this with access to the PHAsset. Is there a way to get this information using the PHPickerViewController?
You should be able to access the image's metadata using ImageIO.
Specifically look at CGImageSourceCopyPropertiesAtIndex(..)