Here is the code snippet i tried:
[library writeImageToSavedPhotosAlbum:self.checkInImage.CGImage metadata:self.metadata
completionBlock :^(NSURL * assetURL, NSError * error) {
NSLog (@"Asset url = %@", assetURL);
NSError *err;
NSString *docDir = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *jpgFilePath = [NSString stringWithFormat:@"%@/test.jpg", docDir];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager moveItemAtURL:assetURL toURL:[NSURL URLWithString:jpgFilePath] error:&err];
NSLog(@"error is %@", err);
}];
I get the error as
Error Domain=NSCocoaErrorDomain Code=262 "The operation couldn’t be completed. (Cocoa error 262.)" UserInfo=0xb49a680 {NSURL=assets-library://asset/asset.JPG?id=6FAC823A-33CB-489B-A125-714FBA5F0EE8&ext=JPG}
Any ideas?
Docs (and Google). This error code corresponds to the NSFileReadUnsupportedSchemeError
constant - i. e. you can't just use an assets-library://
URL to move a file using NSFileManager. (The same is the case regarding ipod-library://
URLs.) You have to use the AssetsLibrary framework to get the data of the file and then write it to a file using - [NSData writeToFile:atomically:]
.
ALAssetsLibrary *lib = [ALAssetsLibrary new];
[lib assetForUrl:theURL // the asset URL you have obtained, NSURL object
resultBlock:^(ALAsset *asset) {
// get data
ALAssetRepresentation *repr = [asset defaultRepresentation];
CGImageRef cgImg = [repr fullResolutionImage];
NSString *fname = [repr fileName];
UIImage *img = [UIImage imageWithCGImage:cgImg];
NSData *data = UIImagePNGRepresentation(img);
[data writeToFile:[@"BaseDirectory/" stringByAppendingPathComponent:fname]
atomically:YES];
[lib release];
}
failureBlock:^(NSError *error) {
// recover from error, then
[lib release];
}];
This is how I solved the issue:
1) I saved the file without metadata in some location, and stored its urlpath.
2) Then used the following piece of code to save the same file with metadata. Here fileURL is the urlpath obtained from step 1.
CFURLRef url = CFURLCreateFilePathURL(NULL, (CFURLRef)fileURL, NULL);
// Creating Image source from image url
CGImageSourceRef imageSource = CGImageSourceCreateWithURL(url, NULL);
// This will be the data CGImageDestinationRef will write into
CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData(data, CFSTR("public.jpeg"), 1, NULL);
BOOL success = (imageSource != NULL);
require(success, cleanup);
success = (imageDestination != NULL);
require(success, cleanup);
// Add the image contained in the image source to the destination, overidding the old metadata with our modified metadata
NSDictionary *metadata = someObj.metadata;
CGImageDestinationAddImageFromSource(imageDestination, imageSource, 0, (CFDictionaryRef)metadata);
// Tell the destination to write the image data and metadata into our data object.
success = CGImageDestinationFinalize(imageDestination);
require(success, cleanup);
// Write the data into the url
[(NSMutableData *) data writeToURL:fileURL atomically:YES];
cleanup:
if (data) {
CFRelease(data);
data = NULL;
}
if (imageSource) {
CFRelease(imageSource);
imageSource = NULL;
}
if (imageDestination) {
CFRelease(imageDestination);
imageDestination = NULL;
}
return success;
Hope this helps. But I would like to upvote H2C03 for very helpful suggestions, which helped to arrive at this solution. Please help me how to do it. Thanks.