Question

The following code runs great and gives me the results I am looking for. However, I would like to run it in its own thread. Is MPMediaQuery thread safe, and what am I doing wrong, if it is?

-(NSArray*) mediaItemsFromPersistentIds:(NSArray*) mediaPersistentIds
{
    if (debug==1) {
        NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));
    }

       MPMediaQuery *mediaQuery = [MPMediaQuery new];
       NSArray *itemsmediaQuery = mediaQuery.items;
       NSPredicate *predicate   = [NSPredicate predicateWithFormat:@"%K IN %@", @"itemId", mediaPersistentIds];

    return [itemsmediaQuery filteredArrayUsingPredicate:predicate];
}

When I try the following, I get

Terminating app due to uncaught exception 'MPMediaItemCollectionInitException', reason: 'items array must not be empty'

I know the [itemsmediaQuery filteredArrayUsingPredicate:predicate] is being returned as (null)

-(NSArray*) mediaItemsFromPersistentIds:(NSArray*) mediaPersistentIds
{
    if (debug==1) {
        NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));
    }
    __block NSArray *itemsmediaQuery;
    __block NSPredicate *predicate;

    dispatch_queue_t mediaQueryQueue = dispatch_queue_create("media query", NULL);
    dispatch_async(mediaQueryQueue, ^{

        MPMediaQuery *mediaQuery      = [MPMediaQuery new];
        itemsmediaQuery = mediaQuery.items;
        predicate = [NSPredicate predicateWithFormat:@"%K IN %@", @"itemId", mediaPersistentIds];

    });

    return [itemsmediaQuery filteredArrayUsingPredicate:predicate];
}
Was it helpful?

Solution

It is safe to request these items in the background.

Right now, you're not actually running the query in the background. You could do something like this:

- (void)mediaItemsFromPersistentIds:(NSArray*)ids
                           callback:(void (^)(NSArray *items))callback {
    dispatch_queue_t mediaQueryQueue = dispatch_queue_create("media query", NULL);
    dispatch_async(mediaQueryQueue, ^{
        MPMediaQuery *mediaQuery = [MPMediaQuery new];
        itemsmediaQuery = mediaQuery.items;
        predicate = [NSPredicate predicateWithFormat:@"%K IN %@", @"itemId", ids];

        // Do the query
        NSArray *items = [itemsmediaQuery filteredArrayUsingPredicate:predicate];

        // Post the query results to the main thread in some way
        dispatch_async(dispatch_get_main_queue(), ^{
            // You could pass this off to a delegate or callback block
            if (callback)
                callback(items);
        });
    });
}

And to call it:

NSArray *ids = ...
[someObj mediaItemsFromPersistentIds:ids callback:^(NSArray *items) {
    // Do something with `items`
}];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top