5

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!

daveoncode
  • 18,900
  • 15
  • 104
  • 159

2 Answers2

8

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.

Community
  • 1
  • 1
daveoncode
  • 18,900
  • 15
  • 104
  • 159
  • i had seen your blog its nice and saved a lot of time – ganesh manoj Apr 24 '13 at 13:15
  • One reason to do your very first fetch in the foreground is that if the user has not yet granted the Photos permission, it will happen via a UIAlertView. Since UIKit calls must be on main thread, this might be why. It seems like Apple could just perform that on the main thread, regardless of what background thread you are accessing the assets library on, though. The way I get around this is by accessing once on the main thread to get the photos permission, then doing every subsequent call on other threads. – Eric G Mar 05 '14 at 20:25
0

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.

Vincent Zgueb
  • 1,491
  • 11
  • 11