Potential bug with PHAsset Creation Request with photoProxy resource type.

I have noticed a problem when a PHAsset creation request is made with the resource type PHAssetResourceType.photoProxy.

let creationRequest = PHAssetCreationRequest.forAsset()
creationRequest.addResource(with: .photoProxy, data: photoData, options: nil)
creationRequest.location = location
creationRequest.isFavorite = true

After successfully saving the resulting asset through PHPhotoLibrary.shared().performChanges, I could verify it in the Photos app.

I noticed that the created photo was initially marked as Favorite and that the location was added to the info as expected. The title of the image changes from "Today" to "<Location Name>" too.

Next, the photo was refreshed, and location data was purged. However, the title remains unchanged and displays the <Location Name>. This refresh was also observed in the code. PHPhotoLibraryChangeObserver protocols func photoLibraryDidChange(_ changeInstance: PHChange) receives a change notification. The same asset has been changed, and there is no location information anymore. isFavorite information persists correctly.

After debugging for a few hours, I discovered that changing the resource type to .photo fixes this issue. Location data is not removed in the Photos app, and no refresh callback is seen in func photoLibraryDidChange(_ changeInstance: PHChange).

I initially used .photoProxy because in the AVCapturePhotoCaptureDelegate implementation class, I always get the call in func photoOutput(_ output: AVCapturePhotoOutput, didFinishCapturingDeferredPhotoProxy deferredPhotoProxy: AVCaptureDeferredPhotoProxy?, error: Error?). So here is where I am capturing the photo data as photoData = deferredPhotoProxy?.fileDataRepresentation().

Answered by Engineer in 810129022

I believe what you're seeing is that the location data is being overwritten by the metadata that is in the exif of the finalized photo after deferred processing occurs. This data will match that that is embedded in the photo proxy.

Are you setting any AVCapturePhotoSettings before capturing the photo? If you have location data for this capture I would recommend using that to set the various latitude / longitude keys in kCGImagePropertyGPSDictionary of the AVCApturePhotoSetting's metadata dictionary. If you do that then I would expect the assets location to be set via the metadata in the file and you no longer will need to set it separately on the creationRequest itself.

Accepted Answer

I believe what you're seeing is that the location data is being overwritten by the metadata that is in the exif of the finalized photo after deferred processing occurs. This data will match that that is embedded in the photo proxy.

Are you setting any AVCapturePhotoSettings before capturing the photo? If you have location data for this capture I would recommend using that to set the various latitude / longitude keys in kCGImagePropertyGPSDictionary of the AVCApturePhotoSetting's metadata dictionary. If you do that then I would expect the assets location to be set via the metadata in the file and you no longer will need to set it separately on the creationRequest itself.

This solution worked.

I was using AVCapturePhotoSettings to set a few settings, and when I added location-related key-values, I could store and maintain location information and more in the photo metadata.

Thank you!

Potential bug with PHAsset Creation Request with photoProxy resource type.
 
 
Q