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];
}
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`
}];