assetforurl blocks never called - iphone

I am trying to retrieve an image from the ALAssets library using a URL, calling assetforURL, but neither the result nor completion blocks are ever called. Something like this:
[library assetForURL:assetURL
resultBlock:^(ALAsset *myasset){
NSLog(#"asset found");
}
failureBlock:^(NSError *error){
NSLog(#"error");
}];
I know that assetforURL is asynchronous and that the blocks will be called sometime later. But they seem to be never called. I never see the output from the NSLog, and if I put in breakpoints, they are never reached.
What I'm really trying to do is associate images with items in a database. I store the asset URLs in the database, and then use the code above to retrieve them. Is there a different way of doing this? I havn't been able to find any examples of anything like this.
Thanks!

Related

Can I save an image to a specific album with the camera roll when saving via writeImageToSavedPhotosAlbum:metadata:completionBlock:?

I have an app that edits a photo's exif data then saves that image to the camera roll via:
[library writeImageToSavedPhotosAlbum:[newTestImage CGImage] metadata:metadata completionBlock:^(NSURL *assetURL, NSError *error) {
//error
}];
This works fine, but is there a way that I can save the image to a specific (ideally new) album within the camera roll? I have searched extensively here and elsewhere and I'm aware of addAssetsGroupAlbumWithName: but as that won't add the new image metadata I don't think I can use it.
Thanks for any help.
There is a great category out there that helps you easily save a photo to a custom album.
Here it is on GitHub
https://github.com/Kjuly/ALAssetsLibrary-CustomPhotoAlbum
You'll need to make some adjustments to support saving the metadata as well, but it should be as simple as replacing the above code's use of
- (void)writeImageToSavedPhotosAlbum:(CGImageRef)imageRef orientation:(ALAssetOrientation)orientation completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock
and using this instead after passing in the metadata
- (void)writeImageToSavedPhotosAlbum:(CGImageRef)imageRef metadata:(NSDictionary *)metadata completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock

Multiple downloading of files wihtout locking the UI in ios

I am having an array that contains different urls, and a set of buttons, each link is assigned to each buttons. When clicking on a button, the content in the url which is assigned to that particular button will be downloaded. The user can click on multiple buttons at the same time so that multiple download can perform at the same time. And at the same time user should have the provision to navigate through another views, so that the downloading process should not lock the UI. Which would be the best and easiest way to implement this? Please share your ideas.
Thanks
Just fetch the data asynchronously:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// The code here is executed when the response from the request comes back.
// The variable "data" will contain the response from the data.
// So you can do something like:
UIImage *anImage = [[UIImage alloc] initWithData:data]];
}];
Luke, use AFNetworking or ASIHTTPRequest lib with asynchronous requests.
You could easily implement a Asynchronous NSURLConnection
i.e. each time the user hits that button you fire up an async connection to do the dirty work.
There are plenty of examples - One of the easiest blog style examples to understand is Matt Gallagher's Cocoa With Love. Here is a link.
The gist of the technique is the delegate methods are easy to work with and you can capture each file that you download inside them.
Don't be tempted by the Synchronous style connection as it is not as flexible and you will struggle to make an easy solution for downloading multiple files using that technique.

detect no disk space iPhone SDK

Suppose I need to write many images to iPhone file system. And I need to find I have enough space to write image to disk. Is it possible using iPhone SDK?
Yes, it is possible. See the following tutorial (found using the powerful "google" search engine) ;)
http://iphoneincubator.com/blog/device-information/how-to-obtain-total-and-available-disk-space-on-your-iphone-or-ipod-touch
Edit: added response re: writing UIImage to disk, with unknown available disk space:
Try-Catch a bad way of doing things. Exceptions in cocoa are only for truly exceptionally circumstances (i.e. crash-worthy). If you write your image using
NSData *imageData = [myImage UIImageJPEGRepresentation];
(or UIImagePNGRepresentation)
and then
NSError *error;
BOOL success = [imageData writeToFile:(NSString *)path options:(NSDataWritingOptions)mask error:&error];
Your BOOL failed will tell you if it worked, and error will contain an NSError object with a description of the error (don't test for error != nil though, that'll crash occasionally).

Is ALAssetsLibrary's enumerateGroupsWithTypes:usingBlock:failureBlock: "broken" in iOS 4.3.4?

I'm developing an iOS app that is based on ALAssetsLibrary api (available since 4.0), I use it to retrieve all the images and videos saved on the device and it's been pretty simple to do that. Anyway as soon I installed iOS 4.3.4 on my iPhone 4, my code stopped working. The line which invokes the fetching does nothing! The code is the following (and it works fine on iOS 4.3.3):
ALAssetsLibrary *library = [[[ALAssetsLibrary alloc] init] autorelease];
ALAssetsGroupEnumerationResultsBlock assetsEnumerator = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
// handle asset
};
ALAssetsLibraryGroupsEnumerationResultsBlock groupsEnumerator = ^(ALAssetsGroup *group, BOOL *stop) {
// handle group
};
ALAssetsLibraryAccessFailureBlock failHandler = ^(NSError *error) {
// handle error
};
[library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:groupsEnumerator failureBlock:failHandler];
it seems that enumerateGroupsWithTypes:usingBlock:failureBlock: never get called, because none of my blocks are executed... and no error is raised! Why? What can I do?
ps: I tried to change "types" argument, but that's not the problem!
I don't understand why (Apple in this moment I'm hating you!), but ALAssetsLibrary in iOS 4.3.4 does not allow fetching in a background thread (I was running a series of NSOperations in a NSOperationQueue).
I solved by creating a little wrapper using performSelectorOnMainThread.
EDIT:
After a code refactoring and the upgrade to iOS 5, I finally realized that the problem is actually related to how ALAssetsLibrary works, there is no need to use performSelectorOnMainThread. I wrote a post on it here.
Something very important:
The user must allow location services for your app.
As written in apple doc for enumerateGroupsWithTypes:usingBlock:failureBlock method.
Special Considerations
This method will fail with error
ALAssetsLibraryAccessGloballyDeniedError if the user has not enabled
Location Services (in Settings > General).
Maybe you should handle this case by displaying an alert to the user.

iOS Core data - problem saving new value to existing objects

I'm trying to save new value for an existing core data object:
[object setValue:Value forKey:NotificationKey];
NSError *error;
[object.managedObjectContext save:&error];
It's not saving the new data. Without any warning but maybe there is a problem with the save method. The process is going on background and invoking local notification at the end. After trying to find what's wrong, I've tried to make the save method before invoking the notification and it didn't rise.
Anyone sees the problem?
Thank you!
If the save occurs on a background thread/operation, you must merge the foreground and background threads/operations before changes made in one are available to the other.