Understanding Old ALAsset Code - ios

I am trying to go through and clean up some deprecation warnings by updating ALAsset with PHPhoto. I am getting confused by this code and need some help to make sure I am not missing something. I added in some comments about what is confusing me.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSURL *assetsURL = [info objectForKey:UIImagePickerControllerReferenceURL];
UIImage *pickedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
NSMutableDictionary *metadata = [NSMutableDictionary dictionary];
// This is where I am getting confused.
// What is the difference between the meta data of the else statement
// and the if statement.
if (assetsURL) {
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
[library assetForURL:assetsURL
resultBlock:^(ALAsset *asset) {
[metadata addEntriesFromDictionary:asset.defaultRepresentation.metadata];
dispatch_semaphore_signal(sema);
}
failureBlock:^(NSError *error) {
dispatch_semaphore_signal(sema);
}];
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
} else {
[metadata addEntriesFromDictionary:[info objectForKey:UIImagePickerControllerMediaMetadata]];
}
// Undocumented method guessing it rotates image to Portrait
pickedImage = [pickedImage IN_rotateToPortraitOrientation];
[metadata setImageOrientation:UIImageOrientationUp];
if (!assetsURL) {
[library writeImageToSavedPhotosAlbum:pickedImage.CGImage
metadata:metadata
completionBlock:^(NSURL *assetURL, NSError *error) {
$l(#"Saved to photo album");
}];
}
...
}
If you could help me understand the difference in meta data. If there is a difference how could I accomplish the same thing with PHPhotos.

Related

UImage get local url after save ios

I want to saved an image in my photo albums, however I had succesfully saved the image but now I want to get the URL which would be my local URL that would open the image If I passes that to UIImage. I'm unable to get the saved image url as of error that "expression not allowed". How can I get the LOCAL URL of my saved image in iOS.
My Tried:
-(NSString *) imageSave: (UIImage *)image
{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)image.imageOrientation completionBlock:^(NSURL *assetURL, NSError *error )
{
[library assetForURL:assetURL resultBlock:^(ALAsset *asset )
{
self.temp1 = [NSString stringWithFormat:#"%#",assetURL];
NSLog(#"SAVED!");
}
failureBlock:^(NSError *error )
{
self.temp1 = [NSString stringWithFormat:#"NO"];
NSLog(#"Error Saving Image!!!");
}];
}];
return self.temp1;
}
I tried by ma making a property but that returns null.
Try following code that may help you.
UIImage *viewImage = YOUR UIIMAGE // ---
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Request to save the image to camera roll
[library writeImageToSavedPhotosAlbum:[viewImage CGImage] orientation:(ALAssetOrientation)[viewImage imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
NSLog(#"error");
} else {
NSLog(#"url %#", assetURL);
NSString *myString = [assetURL absoluteString];
}
}];

Preventing UIImagePicker memory problems

I am having tough time with getting UIImagePickerController to work. It always crashes with memory error. These are the things I have done. Please advice what I can do differently.
I am using NSOperationQueue to do the save operation in a different thread.
I am not passing the UIImage which can be large, so I write the image to photo album and pass the NSURL of the asset.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self dismissViewControllerAnimated:YES completion:^{
UIImage *chosenImage = info[UIImagePickerControllerOriginalImage];
NSMutableDictionary *mutable = [[info objectForKey:UIImagePickerControllerMediaMetadata] mutableCopy];
NSBlockOperation *saveOp = [NSBlockOperation blockOperationWithBlock:^{
[[MyViewController defaultAssetsLibrary] writeImageToSavedPhotosAlbum:[chosenImage CGImage] metadata:mutable completionBlock:^(NSURL *assetURL, NSError *error) {
if ([self.delegate respondsToSelector:#selector(imageSelected:)]) {
[self.delegate imageSelected:assetURL];
}
}];
}];
[saveOp setCompletionBlock:^{
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:saveOp];
}];
}

AvSession Fail with Bad_Access_Code

Im trying to save an AvAsset with multiple videos and merging them into a single video.
That part is taken care of though when the block completes it gives me an error.
My block:
-(void)exportDidFinish:(AVAssetExportSession*)session withCompletionBlock:(void(^)(BOOL success))completion {
self.exportSession = nil;
__block id weakSelf = self;
//delete stored pieces
[self.assets enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(AVAsset *asset, NSUInteger idx, BOOL *stop) {
NSURL *fileURL = nil;
if ([asset isKindOfClass:AVURLAsset.class])
{
AVURLAsset *urlAsset = (AVURLAsset*)asset;
fileURL = urlAsset.URL;
}
if (fileURL)
[weakSelf removeFile:fileURL];
NSLog(#"File Url: %#", fileURL);
}];
[self.assets removeAllObjects];
//[self.delegate removeProgress];
if (session.status == AVAssetExportSessionStatusCompleted) {
NSURL *outputURL = session.outputURL;
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:outputURL]) {
[library writeVideoAtPathToSavedPhotosAlbum:outputURL completionBlock:^(NSURL *assetURL, NSError *error){
//delete file from documents after saving to camera roll
[weakSelf removeFile:outputURL];
if (error) {
completion (NO);
} else {
completion (YES);
}
}];
}
}
//Upload service
completion(YES);
[self.assets removeAllObjects];
}
This is the exact error I am receiving:
I would like to say I have a lot of experience with AVFoundation and the Assets though I do not and cant figure out why the completion block is failing.
What could be the issue and if you need anymore information let me know and i can update the question.
Turns out i had named my IBAction for the save button the name of the completionBlock so it was calling itself and failing.
Changed the name, and now it all works very good.

How to edit Image metadata in iOS?

I am using following code to modify the metadata of Gallery Image.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)mediaInfo
{
ALAssetsLibrary *library =nil;
void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *) = ^(ALAsset *asset)
{
NSDictionary *metadata = asset.defaultRepresentation.metadata;
NSLog(#"Image Meta Data: %#",metadata);
NSMutableDictionary* dict=[[NSMutableDictionary alloc] initWithDictionary:metadata];
[dict setValue:#"sdfdfsfsfsfdsfsf" forKey:(NSString*)kCGImagePropertyIPTCKeywords];
UIImage *anImage = [mediaInfo valueForKey:UIImagePickerControllerOriginalImage];
NSData *imageData = UIImageJPEGRepresentation(anImage, 1.0);
[asset writeModifiedImageDataToSavedPhotosAlbum:imageData metadata:dict completionBlock:^(NSURL *assetURL, NSError *error) {
}];
};
NSURL *assetURL = [mediaInfo objectForKey:UIImagePickerControllerReferenceURL];
library = [[ALAssetsLibrary alloc] init];
[library assetForURL:assetURL
resultBlock:ALAssetsLibraryAssetForURLResultBlock
failureBlock:^(NSError *error) {
}];
}
But it is not working. Please help.
Here is a minimal example to do it:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *imageToSave = (UIImage *) [info objectForKey:UIImagePickerControllerOriginalImage];
/* modify metadata dict */
NSMutableDictionary *imageMetadata = [[info objectForKey: UIImagePickerControllerMediaMetadata] mutableCopy];
NSLog(#"Inspect current metadata: %#", imageMetadata);
NSDictionary *iptc = #{(id)kCGImagePropertyIPTCKeywords: #"awesome photo"};
[imageMetadata setObject:iptc forKey:(id)kCGImagePropertyIPTCDictionary];
/* Save to the Camera Roll with modified medatadata */
[[ALAssetsLibrary new] writeImageToSavedPhotosAlbum:imageToSave.CGImage
metadata:imageMetadata
completionBlock:NULL];
[self performDismiss];
}
If you use a metadata viewer (OS X's Preview is good enough) you'll see something like this:
But, as pawan suggests, use an existing library to do it more easily. Google around, there are quite a few options out there.

Saving image to Photo Library and get the URL of the saved image

I'm trying to save an image from camera to Photo Library and then store the URL of the saved image. My code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc]init];
[library writeImageToSavedPhotosAlbum:(__bridge CGImageRef)([info objectForKey:UIImagePickerControllerOriginalImage])
orientation:ALAssetOrientationUp completionBlock:^(NSURL *assetURL, NSError *error) {
if(error == nil) {
_myImageUrl = [NSString stringWithFormat:#"%#",assetURL];
NSLog(#"%#",assetURL);
} else NSLog(#"%#",error);
}];
[picker dismissViewControllerAnimated:YES completion:nil];}
My problem is that assetUrl is always NULL. Any ideas?
Thank you!
Finally, after reading more, I found out the answer: the first parameter of the function is of CGImageRef type and (__bridge CGImageRef) doesn't do what I expected; but if I call the CGImage method of UIImage object, it works. The correct way to do this is:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc]init];
CGImageRef image = [[info objectForKey:UIImagePickerControllerOriginalImage] CGImage];
[library writeImageToSavedPhotosAlbum:image
orientation:ALAssetOrientationUp
completionBlock:^(NSURL *assetURL, NSError *error) {
if(error == nil) {
_myImageUrl = [NSString stringWithFormat:#"%#",assetURL];
NSLog(#"%#",assetURL);
} else NSLog(#"%#",error);
}];
self.toDoImage.image = [info objectForKey:UIImagePickerControllerOriginalImage];
[picker dismissViewControllerAnimated:YES completion:nil];
}

Resources