I'm using a method that starts like this:
static func getMediaAssets(item: NSItemProvider, completion: @escaping (Result<UploadableMediaAssets, Error>) -> ()) {
guard item.canLoadObject(ofClass: PHLivePhoto.self) else {
logger.error("Could not load PHLivePhoto")
completion(.failure(LiveImageItemProviderError.cannotGetLivePhoto))
return
}
item.loadObject(ofClass: PHLivePhoto.self) { livePhoto, error in
guard let livePhoto = livePhoto as? PHLivePhoto else {
logger.debug("No live photo!")
completion(.failure(LiveImageItemProviderError.cannotGetLivePhoto))
return
}
let assetResources = PHAssetResource.assetResources(for: livePhoto)
guard assetResources.count == 2 else {
completion(.failure(LiveImageItemProviderError.cannotGetLivePhoto))
return
}
let filteredForMovie = assetResources.filter {$0.uniformTypeIdentifier == movieUTI}
guard filteredForMovie.count == 1 else {
logger.error("Could not find movie resource: \(movieUTI)")
completion(.failure(LiveImageItemProviderError.cannotGetLivePhoto))
return
}
let movie:PHAssetResource = filteredForMovie[0]
let filteredForOther = assetResources.filter {$0 !== movie}
guard filteredForOther.count == 1 else {
logger.error("Could not find other resource")
completion(.failure(LiveImageItemProviderError.cannotGetLivePhoto))
return
}
let image: PHAssetResource = filteredForOther[0]
let pickedImageType: ImageType
// more code ...
}
to get a live photo using the PHPickerViewController from my main app. That's working fine.
However, when I try to use this same method in a sharing extension to get a photo from the Photo's app, both item.canLoadObject and item.loadObject fail.
To be more clear on this point, for "a sharing extension to get a photo from the Photo's app", I have a sharing extension (a UIViewController) that uses the following code:
let attachments = (self.extensionContext?.inputItems.first as? NSExtensionItem)?.attachments ?? []
guard attachments.count == 1 else {
completion(.failure(HandleSharedFileError.notJustOneFile))
return
}
Using that NSItemProvider, attachment, I invoke my getMediaAssets method.
I go into the Photos app, select a live photo, use my app from the list of sharing extensions, and it invokes my sharing extension.
This is what I'm currently using in the Info.plist to select files received by the share extension:
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<string>SUBQUERY (
extensionItems,
$extensionItem,
SUBQUERY (
$extensionItem.attachments,
$attachment,
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.apple.live-photo"
).@count == $extensionItem.attachments.@count and $extensionItem.attachments.@count == 1
).@count == 1</string>
</dict>
Any suggestions?
--- Updates ----
- The error from
loadObject(if I comment out thecanLoadObjectcheck) is:
2020-12-27T15:18:40-0700 debug : No live photo: Optional(Error Domain=NSItemProviderErrorDomain Code=-1200 "Could not coerce an item to class PHLivePhoto" UserInfo={NSLocalizedDescription=Could not coerce an item to class PHLivePhoto})
With this UTI
static let livePhotoUTI = "com.apple.live-photo"
This returns true:
item.hasItemConformingToTypeIdentifier(livePhotoUTI)
in the sharing extension (where item is the NSItemProvider).
- Additional reference supporting idea that live images can't be accessed from sharing extensions: https://developer.apple.com/forums/thread/22132?login=true&page=1#654410022