I am able to read the DNG-file as a PHAssetResource and getting the NSData through PHAssetResourceManager.requestDataForAssetResource.The NSData holds the same amount of bytes as the filesize indicates.However, when I do UIImage(data:myLoadedData) only a very low rez thumb is loaded.I have tried the following :- using CGImageSourceCreateWithData and converting it back into an UIImage via CGImageSourceCreateImageAtIndex- the CGImageSourceGetCount( imageSource) returns 1 so there is only one image in there, not counting the thumb- saving the NSData to the documents folderand reading it witn NSImage(contentsOfFile) (the saved file is a valid DNG and TIFF when I download the app package to my mac through the Device Manager)The PHAssetResource.uniformTypeIdentifier reports the file as "com.adobe.raw-image"I get the same result with DNG-files from two different cameras, both the Leica M typ240, and the Leica Monochrom (first edition)There is a difference in thumbnail size, but I am not able to view the full resolution image.Loading large jpeg's or PNGs works fine.The "app" is running on an iPad Pro iOS 9.3What am I missing here?Any tips would be greatly appreciated.Below is the code, from the UIImagePickerController returns with a selected image URL func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
dismissViewControllerAnimated(true, completion: nil)
let url = info[UIImagePickerControllerReferenceURL] as! NSURL
getUIImagefromAsseturl(url)
}
func getUIImagefromAsseturl (url: NSURL) {
let resourceManager = PHAssetResourceManager.defaultManager()
let asset = PHAsset.fetchAssetsWithALAssetURLs([url], options: nil)[0]
let assetResource = PHAssetResource.assetResourcesForAsset(asset as! PHAsset)[0]
let totalData = NSMutableData()
resourceManager.requestDataForAssetResource(assetResource, options: nil, dataReceivedHandler:
{ (data) in
totalData.appendData( data )
print( "data.length \(data.length) \(totalData.length)" )
}, completionHandler: { (error) in
if error != nil {
print( "error: \(error)" )
}
else {
/* totalData contains the entire byte buffer from the file */
let image = UIImage(data: totalData)
/* image contains puny thumbnail */
dispatch_async(dispatch_get_main_queue(), {
self.imageView.contentMode = .ScaleAspectFit
self.imageView.image = image
})
}
})
}
Post not yet marked as solved
I'm building an app where you can take a photo, it saves the photo to the app's documents directory, and I'm wanting to pull the GPS info from those photos.What's the best way to do this?Thanks!
Post not yet marked as solved
I am interested in augmenting my application with the ability to read photos from the following accessories:https://www.apple.com/shop/product/MJYT2AM/A/lightning-to-sd-card-camera-readerhttps://www.apple.com/shop/product/MK0W2AM/A/lightning-to-usb-3-camera-adapter?fnode=97Specifically, I want to be able to access these photos without first having to download them all to the Photos app or other device memory.Is this possible? And if so, where can I find information about how to do it? Swift 3.0 strongly preferred. 🙂
Post not yet marked as solved
It was discussed in What's New in Photos APIs at WWDC that we should avoid using NSPredicate for custom fetch options if at all possible for performance purposes. In my app, I'm using NSPredicate to get only images from the user's library. I'm not seeing an API that would allow me to get assets from a specific collection filtered to just images without the use of NSPredicate though. Is there a more efficient way to perform this query that I'm not seeing?let photoLibraryFetchResult = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil)
let assetCollection = photoLibraryFetchResult.firstObject!
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
let fetchResults = PHAsset.fetchAssets(in: assetCollection, options: fetchOptions)
Post not yet marked as solved
I have a popular app and i'm seeing a sporadic crash that I don't understand:Fatal Exception: NSInternalInconsistencyException
This method can only be called from inside of -[PHPhotoLibrary performChanges:completionHandler:] or -[PHPhotoLibrary performChangesAndWait:error:]Here is the code, it crashes on line 3 (creationRequestForAssetFromImage) below: PHPhotoLibrary.shared().performChanges({
guard
let changeRequest = PHAssetChangeRequest.creationRequestForAssetFromImage(atFileURL: animatedImageFileURL),
let albumChangeRequest = PHAssetCollectionChangeRequest.init(for: album),
let placeholder = changeRequest.placeholderForCreatedAsset else {
WLog("ActionExecuter: error, couldn't init creationRequests")
completionBlock(nil)
return
}
...Clearly this IS in a performChanges block.Full stack of crash, from line 3 above onwards:Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x184da6d8c __exceptionPreprocess
1 libobjc.A.dylib 0x183f605ec objc_exception_throw
2 Photos 0x193cad220 -[PHPhotoLibrary recordInsertRequest:]
3 Photos 0x193c3cf78 -[PHChangeRequestHelper initForNewObjectWithUUID:changeRequest:]
4 Photos 0x193c6dfc4 -[PHAssetCreationRequest initForNewObjectWithUUID:]
5 Photos 0x193c699c0 +[PHAssetCreationRequest _creationRequestForAssetUsingUUID:]
6 Photos 0x193c69ce4 +[PHAssetCreationRequest creationRequestForAssetFromImageAtFileURL:]I am wondering if this is some threading issue. Is there a rule about what thread performChanges et al have to be called from?It seems to be slower devices that hit this: iOS 11 on an iPad Air 1 is the latest crash in the wild I saw of this one.Thanks for any help
Post not yet marked as solved
We have custom video composition that alters frames and everything works fine except on some videos [AVAsynchronousVideoCompositionRequest sourceFrameByTrackID] returns nil CVPixelBuffer. It happens only at specific times of that videos, usually at start, all other processing goes well and sourceFrameByTrackID returns normal buffers with pixel data in it. At the same this videos are totally ok and plays well in Photos app (for example).What reasons can cause such strange behaviour?
Post not yet marked as solved
Apple Photos has support for "Optimize iPhone Storage" within iCloud Photos that removes Videos and Photos off the device when device storage is constrained.
Is there a way to test this on simulators? Specifically, I'd like to know if it would be possible to make a Video always require a download so I can ensure my app handles downloading iCloud videos gracefully.
I've tried signing in to iCloud on the simulator but it never seems to load my photos and videos.
Thanks in advance!
If you set it, does it mean that the user will have an "old style" alert when a permission request is done?
Post not yet marked as solved
In iOS 14 beta when I tries to access photos library, it asks for the permission first time and if select "Select Photos.." and select few photos to show next time if I tries to access photos, it shows me all the photos. ideally it should show me the photos which I have selected for my app.
What is Error Domain=com.apple.photos.error Code=46104 mean?
This error appears when I try to create an album on iOS14.
case:
User first gives AddOnly authorization and then gives ReadWrite authorization.
After I get the ReadWrite authorization, create an album.
code reference:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:albumName];
albumPlaceholder = [request placeholderForCreatedAssetCollection];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
// success is NO, error is "Error Domain=com.apple.photos.error Code=46104"
}];
Post not yet marked as solved
What is Error Domain=com.apple.photos.error Code=46104 mean?
This error appears when I try to create an album on iOS14.
case:
User first gives AddOnly authorization and then gives ReadWrite authorization.
After I get the ReadWrite authorization, create an album.
code reference:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:albumName]
albumPlaceholder = [request placeholderForCreatedAssetCollection];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
// success is NO, error is "Error Domain=com.apple.photos.error Code=46104"
}];
The supplementary log information for the above question is as follows:
2020-08-17 11:28:19.470871+0800 XXXX[4255:1139139] CoreData: XPC: Unable to connect to server with options { NSXPCStoreServerEndpointFactory = "<PLXPCPhotoLibraryStoreEndpointFactory: 0x280ce8760>"; skipModelCheck = 1;}
2020-08-17 11:28:19.479533+0800 XXXX[4255:1139139] CoreData: XPC: Unable to load metadata: Error Domain=NSCocoaErrorDomain Code=134060 "关键数据出错。" UserInfo={Problem=Unable to send to server; failed after 8 attempts.}
2020-08-17 11:28:19.483149+0800 XXXXX[4255:1139139] [error] error: addPersistentStoreWithType:configuration:URL:options:error: returned error NSCocoaErrorDomain (134060)
CoreData: error: addPersistentStoreWithType:configuration:URL:options:error: returned error NSCocoaErrorDomain (134060)
CoreData: annotation: userInfo:CoreData: annotation: Problem : Unable to send to server; failed after 8 attempts.
CoreData: annotation: storeType: NSXPCStoreCoreData: annotation: configuration: (null)
CoreData: annotation: URL: file:///var/mobile/Media/PhotoData/Photos.sqlite
CoreData: annotation: options:
CoreData: annotation: NSXPCStoreServerEndpointFactory : <PLXPCPhotoLibraryStoreEndpointFactory: 0x280ce8760>CoreData: annotation: skipModelCheck : 1
2020-08-17 11:28:19.485049+0800 XXXXX[4255:1139139] [Generic] Failed to connect to XPC PhotoLibraryStore file:///var/mobile/Media/PhotoData/Photos.sqlite with options { NSXPCStoreServerEndpointFactory = "<PLXPCPhotoLibraryStoreEndpointFactory: 0x280ce8760>"; skipModelCheck = 1;}: Error Domain=NSCocoaErrorDomain Code=134060 "关键数据出错。" UserInfo={Problem=Unable to send to server; failed after 8 attempts.}
2020-08-17 11:28:19.485565+0800 XXXXX[4255:1139139] [Migration] Failed to configure PSC for library file:///var/mobile/Media/: Error Domain=NSCocoaErrorDomain Code=134060 "关键数据出错。" UserInfo={Problem=Unable to send to server; failed after 8 attempts.}
2020-08-17 11:28:19.485943+0800 XXXXX[4255:1139139] [LibraryBundle] Unable to create PLLibraryBundleLogInfo because PSC is nil
There is another problem. When saving the video, if the AddOnly permission is taken first and then the ReadWrite permission is taken, the performChanges method will freeze for more than 10 seconds before calling the completionHandler. The following is the log information:
[Generic] Failed to connect to XPC PhotoLibraryStore file:///var/mobile/Media/PhotoData/Photos.sqlite with options {
NSXPCStoreServerEndpointFactory = "<PLXPCPhotoLibraryStoreEndpointFactory: 0x280700d00>";
These problems only occur during a cold launch when the AddOnly permission is taken first and then the ReadWrite permission is taken. Whether the app only takes the AddOnly permission, only takes the ReadWrite permission, or closes the app after authorization and reopens it will not happen.
Post not yet marked as solved
I'm trying to move a video I create from images within my app from a temporary path to the photo library.
I've verified that the movie exists by downloading the app data via devices/xcode and the movie then plays fine on my macbook.
I've tried:
UISaveVideoAtPathToSavedPhotosAlbum(
videoPath,
self,
#selector(self.video(_:didFinishSavingWithError:contextInfo:)),
nil)
with Error:
Optional(Error Domain=ALAssetsLibraryErrorDomain Code=-1 "Unknown error" UserInfo={NSLocalizedDescription=Unknown error, NSUnderlyingError=0x283684570 {Error Domain=ALAssetsLibraryErrorDomain Code=-1 "Unknown error" UserInfo={NSLocalizedDescription=Unknown error, NSUnderlyingError=0x283681860 {Error Domain=ALAssetsLibraryErrorDomain Code=-1 "Unknown error" UserInfo={NSLocalizedDescription=Unknown error, NSUnderlyingError=0x28366e490 {Error Domain=com.apple.photos.error Code=42001 "(null)"}}}}}})
and
PHPhotoLibrary.requestAuthorization { status in
// Return if unauthorized
guard status == .authorized else {
print("Error saving video: unauthorized access")
return
}
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoURL as URL)
}) { success, error in
if !success {
print("Error saving video: \(String(describing: error))")
}
}
}
with Error:
Domain=ALAssetsLibraryErrorDomain Code=-1 "Unknown error" UserInfo= ...... {Error Domain=com.apple.photos.error Code=42001 "(null)"
both compile fine and are called, but end up giving me errors that do not help in the slightest.
I have a full help request on StackOverflow with a link to the project (that it does not let me post here): https://stackoverflow.com/questions/63575539/swift-ios-save-video-to-library
iPhone7 : iOS 14.0 Beta 5
Xcode-beta
Mac OS : 10.15.5 (19F101)
crash info :
** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[PHPhotoLibrary presentLimitedLibraryPickerFromViewController:]: unrecognized selector sent to instance xxxxxx'
terminating with uncaught exception of type NSException
my code:
(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (@available(iOS 14, *)) {
[[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:self];
}
}
Post not yet marked as solved
On Xcode 12 Beta 6, on Simulator, I cannot present a PHPickerViewController. I get the error message:
[Picker] Picker failed with error: Error Domain=PXErrorDomain Code=-1 "PHPickerViewController did timeout." UserInfo={NSDebugDescription=PHPickerViewController did timeout.}
And the view that is presented says, "Picker Unavailable".
This is occurring in an existing app. If I start a new project and copy the presentation code, it works as expected.
Post not yet marked as solved
I've been working in Swift on iOS to access images via UIImagePickerController, pulling the PHAsset from the picker delegate's "info" dictionary, and then pulling GPS information from the PHAsset.
For newer photos, the asset.location is populated with GPS information.
Also, with newer photos, CIImage's property dictionary has {GPS} information.
So all is good with newer photos.
But when I go back to images taken in 2017, asset.location is nil and there is no "{GPS} information in the CIImage.
However, if I export the photo from Photos app on my Mac and then view it in Preview, there *is* GPS information.
So am I missing some settings to find the GPS information in older photos using PHAsset on iOS?
Thanks,
Post not yet marked as solved
I use the following code to parse Photo metadata and this works well. However, I am unable to pull the new iOS 14 "caption" from this metadata (it worked in early iOS 14 betas, but has since stopped working in the GM.) Does anyone know how I can get the caption data from a PHAsset? Thanks!
Stephen
let options = PHContentEditingInputRequestOptions()
options.isNetworkAccessAllowed = true
asset.requestContentEditingInput(with: options, completionHandler: {(contentEditingInput, _) -> Void in
if let url = contentEditingInput?.fullSizeImageURL {
let fullImage = CIImage(contentsOf: url)
// get all the metadata
self.allPhotoMetadata = fullImage?.properties ?? [:]
// {TIFF}
if let tiffDict = self.allPhotoMetadata["{TIFF}"] as? [String:Any] {
if tiffDict["Make"] != nil {
self.cameraData[cameraKeys.make] = tiffDict["Make"]
}
if tiffDict["Model"] != nil {
self.cameraData[cameraKeys.model] = tiffDict["Model"]
}
if tiffDict["ImageDescription"] != nil {
self.imageData[imageKeys.caption] = tiffDict["ImageDescription"]
}
}
// {IPTC}
if let iptcDict = self.allPhotoMetadata["{IPTC}"] as? [String:Any] {
// if we didn't find a caption in the TIFF dict, try to get it from IPTC data
// first try, Caption/Abtract, then ArtworkContentDescription
if self.imageData[imageKeys.caption] == nil {
if iptcDict["Caption/Abstract"] != nil {
self.imageData[imageKeys.caption] = iptcDict["ArtworkContentDescription"]
} else if iptcDict["ArtworkContentDescription"] != nil {
self.imageData[imageKeys.caption] = iptcDict["ArtworkContentDescription"]
}
}
}
}
})
}
Post not yet marked as solved
New in iOS 14, we can now drag a photo up in the Photos app and add a caption.
Is it possible to access this caption via PhotoKit or any other framework?
I don't see a field for it on PHAsset. I've also tried the following snippet to see if I can see them stored on the image:
let assets = PHAsset.fetchAssets(with: .image, options: nil)
				assets.enumerateObjects { (asset, index, stop) in
						let options = PHContentEditingInputRequestOptions()
						options.isNetworkAccessAllowed = true
						asset.requestContentEditingInput(with: options) { (input, properties) in
								guard let input = input,
											let fullSizeImageURL = input.fullSizeImageURL,
											let imageSource = CGImageSourceCreateWithURL(fullSizeImageURL as CFURL, nil),
											let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) else {
										return
								}
								
								dump(imageProperties)
						}
				}
Post not yet marked as solved
We implemented the new PHPicker and have run into an issue we haven't been able to replicate on our own devices but see a lot of users running into it. The problem is an error after getting the PHPickerResults and trying to get the UIImages.
Because the user can select several images at once, what we do is get the results and iterate over each itemProvider object.
I'm following apple's guidance and checking if itemProvider canLoadObjectOfClass:UIImage.class, before executing itemProvider loadObjectOfClass:UIImage.class.
However we are getting hundreds of reports of users where this last method returns an error.
Firstly, this is how we configure our PHPickerViewController:
PHPickerConfiguration *configuration = [[PHPickerConfiguration alloc] init];
configuration.selectionLimit = self.pictureSelectionLimit;
configuration.filter = PHPickerFilter.imagesFilter;
configuration.preferredAssetRepresentationMode = PHPickerConfigurationAssetRepresentationModeCurrent;
PHPickerViewController *pickerViewController = [[PHPickerViewController alloc] initWithConfiguration:configuration];
pickerViewController.delegate = self;
pickerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[viewController presentViewController:pickerViewController
animated:YES
completion:nil];
And this is what we do with the PHPickerResult. This is a method that returns a block with an array of an object NewPicture instantiated with the UIImage I should be getting.
NSMutableArray *picArray = [[NSMutableArray alloc] init];
NSArray *itemProviders = [self.results custom_map: ^id _Nullable (PHPickerResult *_Nonnull current) {
return current.itemProvider;
}];
dispatch_group_t dispatchGroup = dispatch_group_create();
for (NSItemProvider *itemProvider in itemProviders) {
dispatch_group_enter(dispatchGroup);
/**
We cannot properly retrieve raw type images with the current authorization status.
If the image is of type raw, we ignore it.
*/
if ([itemProvider hasItemConformingToTypeIdentifier:@"public.camera-raw-image"]) {
NSException *exception = [NSException exceptionWithName:@"ImageIsTypeRaw"
reason:[NSString stringWithFormat:@"Object is type raw. ItemProvider: %@", itemProvider.description]
userInfo:nil];
// Log exception...
dispatch_group_leave(dispatchGroup);
continue;
}
if ([itemProvider canLoadObjectOfClass:UIImage.class]) {
[itemProvider loadObjectOfClass:UIImage.class completionHandler: ^(__kindof id NSItemProviderReading _Nullable object, NSError *_Nullable error) {
if ([object isKindOfClass:UIImage.class]) {
NewPicture *picture = [[NewPicture alloc]initWithImage:object];
[picArray addObject:picture];
}
if (error) {
NSException *exception = [NSException exceptionWithName:@"CouldNotLoadImage"
reason:[NSString stringWithFormat:@"Object is nil. UserInfo: %@", error.userInfo]
userInfo:error.userInfo];
// Log exception...
}
dispatch_group_leave(dispatchGroup);
}];
}
}
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^{
picturesBlock(picArray);
});
The most common error we see our users are getting is:
Object is nil. UserInfo: {
NSLocalizedDescription = "Cannot load representation of type public.jpeg";
NSUnderlyingError = "Error Domain=NSCocoaErrorDomain Code=260 \"The file \U201cversion=1&uuid=*&mode=current.jpeg\U201d couldn\U2019t be opened because there is no such file.\" UserInfo={NSURL=file:///private/var/mobile/Containers/Shared/AppGroup/*/File%20Provider%20Storage/photospicker/version=1&uuid=*&mode=current.jpeg, NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/*/File Provider Storage/photospicker/version=1&uuid=***&mode=current.jpeg, NSUnderlyingError=0x283822970 {Error Domain=NSPOSIXErrorDomain Code=2 \"No such file or directory\"}}";
}
I'm having a really hard time understanding why this sometimes fails. I'd really appreciate it if someone could give me a hand with this.
I'm attaching the stack trace:
stack_trace - https://developer.apple.com/forums/content/attachment/051f7018-05ff-4ad1-a626-29f248d0b497
Post not yet marked as solved
language
PHFetchResult *topLevelUserCollections = [PHCollectionList fetchTopLevelUserCollectionsWithOptions:nil];
for (NSInteger i = 0; i topLevelUserCollections.count; i++) {
PHCollection *collection = topLevelUserCollections[i];
id value = collection.localizedTitle;
NSLog(@"%@", value);
}
this value is bad address
Post not yet marked as solved
My app helps its user scan hundreds of photos. I want to present a PHPickerViewController so that the user doesn't have to scroll through hundreds of photos to find the next photo they want to scan. The scroll criteria could be a date or assetIdentifier.