UIImagePickerControllerReferenceURL
was deprecated in iOS 11 (even though it's still returned in the info
dictionary) and was supposed to be replaced with UIImagePickerControllerPHAsset
, but I've yet to get an info
dictionary back which contains that key. Since the one is deprecated and the other is missing, is there a known solution for extracting the "date taken" from the picked image?
For reference, this is an example info
dictionary returned when and image is picked from the library:
▿ 4 elements
▿ 0 : 2 elements
- key : "UIImagePickerControllerImageURL"
- value : file:///private/var/mobile/Containers/Data/Application/EE1BA60E-2DC3-47C5-A58D-86498E95C323/tmp/3A025D4C-B378-474B-8A09-017479A3A776.jpeg
▿ 1 : 2 elements
- key : "UIImagePickerControllerMediaType"
- value : public.image
▿ 2 : 2 elements
- key : "UIImagePickerControllerReferenceURL"
- value : assets-library://asset/asset.HEIC?id=537976CD-A550-41C9-9416-92C8072112D7&ext=HEIC
▿ 3 : 2 elements
- key : "UIImagePickerControllerOriginalImage"
- value : <UIImage: 0x1d04b4760> size {3024, 4032} orientation 3 scale 1.000000
(Note that UIImagePickerControllerReferenceURL
is still present, though deprecated, and the suggested replacement, UIImagePickerControllerPHAsset
, is missing.)
If it were present, getting the date would be simple:
if let asset = info[UIImagePickerControllerPHAsset] as? PHAsset,
let resource = PHAssetResource.assetResources(for: asset).first {
let dateTaken = resource.creationDate
}
Could it be that Apple forgot to implement UIImagePickerControllerPHAsset
? Any ideas on workarounds (without using deprecated methods)?
I believe that previous solutions on Stack Overflow are deprecated, and thus won't answer the question using modern approaches.
Swift 4.1
I struggled with this for a while too. It turns out you just need user permission to access to the photo library - then info
will contain a value for the key UIImagePickerControllerPHAsset
. You can check & request access like this:
let status = PHPhotoLibrary.authorizationStatus()
switch status {
case .authorized:
// show your media picker
case .denied:
// probably alert the user that they need to grant photo access
case .notDetermined:
PHPhotoLibrary.requestAuthorization({status in
if status == .authorized {
// show your media picker
}
})
case .restricted:
// probably alert the user that photo access is restricted
}
Then you use the imagePickerController(_: didFinishPickingMediaWithInfo:)
method as usual and will have access to the UIImagePickerControllerPHAsset
You can get the date by examining the chosen photo's metadata through the ImageIO framework.
However, the claim that the PHAsset information doesn't arrive is simply bogus. It arrives just fine. You didn't show your code, so who knows what you're doing? Perhaps the problem is that you forgot to get user authorization? Without user authorization, of course you can't access the PHAsset. You'll get the UIImagePickerControllerOriginalImage and the UIImagePickerControllerImageURL and that's all.
This code works just fine for me (assuming we have the necessary user authorization before using the image picker controller in the first place):
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any]) { //
let asset = info[UIImagePickerControllerPHAsset] as? PHAsset
let url = info[UIImagePickerControllerMediaURL] as? URL
var im = info[UIImagePickerControllerOriginalImage] as? UIImage
if let ed = info[UIImagePickerControllerEditedImage] as? UIImage {
im = ed
}
let live = info[UIImagePickerControllerLivePhoto] as? PHLivePhoto
let imurl = info[UIImagePickerControllerImageURL] as? URL
self.dismiss(animated:true) {
if let style = asset?.playbackStyle { // and so on, works fine
// ....
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With