taber taber - 3 months ago 40
iOS Question

ALAssetsLibrary assetForURL: always returning nil for photos in "My Photo Stream" in iOS 8.1

This code worked fine in iOS 7 but in iOS 8.1 all assets located in the "My Photo Stream" album are nil from within the result block. (The failureBlock is not called.) Regular albums and shared albums work just fine.

I tried the accepted answer from: Error trying to assigning __block ALAsset from inside assetForURL:resultBlock:

That is, I'm holding a reference to an ALAssetsLibrary object, listening for the

ALAssetsLibraryChangedNotification
event (which doesn't happen btw, but oh well.) I made sure my app has permission to access photos, I'm on wi-fi, I see the photos' thumbnails just fine in my tableView. It's just when I try to load them with
assetForURL:
they're always nil.

// example URL: assets-library://asset/asset.JPG?id=1ECB69B9-DC7A-45A7-B135-F43317D3412C&ext=JPG
[self.library assetForURL:[NSURL URLWithString:url] resultBlock:^(ALAsset *asset) {
NSLog(@"Asset: %@", asset); // nil :(
} failureBlock:^(NSError *error) {
NSLog(@"Failure, wahhh!");
}];


Is anyone else seeing this issue?

Answer

I had the same problem. Switching to Photos framework is not an option for me at this moment, but fortunately I have found a workaround. You may find it a big ugly and I suspect it may work slow when Photo Stream contains a lot of photos, but it is better than nothing.

The idea is to enumerate all items in the Photo Stream asset group and compare the necessary URL with the URL of each item. Fortunately, it still works.

I have a method like this (library is ALAssetsLibrary property of the same class, you may need to initialise it inside this code):

- (void)loadItem:(NSURL *)url withSuccessBlock:(void (^)(void))successBlock andFailureBlock:(void (^)(void))failureBlock {

[library assetForURL:url
        resultBlock:^(ALAsset *asset)
        {
            if (asset){
                //////////////////////////////////////////////////////
                // SUCCESS POINT #1 - asset is what we are looking for 
                //////////////////////////////////////////////////////
                successBlock();
            }
            else {
                // On iOS 8.1 [library assetForUrl] Photo Streams always returns nil. Try to obtain it in an alternative way

                [library enumerateGroupsWithTypes:ALAssetsGroupPhotoStream
                                       usingBlock:^(ALAssetsGroup *group, BOOL *stop)
                 {
                     [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
                         if([result.defaultRepresentation.url isEqual:url])
                         {
                             ///////////////////////////////////////////////////////
                             // SUCCESS POINT #2 - result is what we are looking for
                             ///////////////////////////////////////////////////////
                             successBlock();
                             *stop = YES;
                         }
                     }];
                 }

                                     failureBlock:^(NSError *error)
                 {
                     NSLog(@"Error: Cannot load asset from photo stream - %@", [error localizedDescription]);
                     failureBlock();

                 }];
            }

        }
        failureBlock:^(NSError *error)
        {
            NSLog(@"Error: Cannot load asset - %@", [error localizedDescription]);
            failureBlock();
        }
  ];
}

Hope this helps.