PDA

View Full Version : MPMediaQuery nil right after iTunes sync (iPod library updating)




mms13
Apr 21, 2011, 03:03 PM
As you may know, right after you finish syncing your phone, if you open up the iPod app you will notice it says 'updating library' for a few seconds before you can view your music. Well, I've discovered that performing an MPMediaQuery during this span results in 0 songs being returned, and my app crashing.

My root view is a table view with all the user's playlists. So you launch my app, a splash screen appears for a few seconds, and then the populated table pops up. I do all my work for querying the library in viewDidLoad(). This is no issue, unless you try to launch my app right after a sync, in which case it will crash. Try to open it up again a few seconds later, no problem (cause the iPod library updated).

What can I do to detect this condition and have my program wait until the library is finally available? I've tried a bunch of different things, such as registering for the library change notification, waiting until the library's lastModifiedDate stops changing, and a loop that keeps querying until it get's something...but none of these have worked for me...it's like the iPod can't update while my app is waiting for it to. Perhaps because I'm doing everything on the main thread? Or does the fact I'm doing it in viewDidLoad matter?

If someone knows how to solve this problem please let me know!



chown33
Apr 21, 2011, 03:23 PM
I suggest using the debugger to find out where it's crashing. Or look at the crash log.

Then use that information to prevent it from crashing. That might be easy (adding a try/catch) or it might be harder (catching a signal).

mms13
Apr 21, 2011, 03:38 PM
I suggest using the debugger to find out where it's crashing. Or look at the crash log.

Then use that information to prevent it from crashing. That might be easy (adding a try/catch) or it might be harder (catching a signal).
I already know where it's crashing. I don't have the code in front of me but I'm doing something like:

MPMediaQuery *query = [[MPMediaQuery]alloc];
query = [MPMediaQuery songsQuery]
MPMediaItemCollection *collection = [[[MPMediaItemCollection] alloc] collectionWithItems:[query items]];


It crashes on the final statement because collectionWithItems throws an error if you feed it an empty array. [query items] is empty because the iPod library is updating after a sync. I've already deduced all that...I just need a way to have my application hold for a bit and try to set the collection after I'm positive the iPod library is loaded (and that query won't be nil).

dejo
Apr 21, 2011, 05:16 PM
I don't have the code in front of me...
Wait until you do. Then post the actual code. Please do this as a courtesy to those you seek help from.

mms13
Apr 21, 2011, 05:27 PM
Finally figured it out. Turns out it did have something to do with querying the library inside of viewDidLoad. Here's what I did in case anyone else runs into this issue.

In viewDidLoad:

if ([[[MPMediaLibrary defaultMediaLibrary] lastModifiedDate] timeIntervalSinceNow] > -120) {
NSString *init = @"0";
NSString *sync = @"1";
while (![init isEqualToString:sync]) {
init = [[[MPMediaLibrary defaultMediaLibrary] lastModifiedDate] description];
[NSThread sleepForTimeInterval:1.00];
sync = [[[MPMediaLibrary defaultMediaLibrary] lastModifiedDate] description];
}
}


If the library was modified in the past 2 minutes, this will loop until last modified date stops changing (which is the point the library is done updating).

Then, in viewDidAppear, I execute my query...

MPMediaQuery *query = [[MPMediaQuery alloc] init];
query = [MPMediaQuery songsQuery];
MPMediaItemCollection *allSongsCollection = [[MPMediaItemCollection alloc]initWithItems:[query items]];


I've tested this several times right after a sync and so far everything is working great!

dejo
Apr 21, 2011, 05:45 PM
Then, in viewDidAppear, I execute my query...

MPMediaQuery *query = [[MPMediaQuery alloc] init];
query = [MPMediaQuery songsQuery];
MPMediaItemCollection *allSongsCollection = [[MPMediaItemCollection alloc]initWithItems:[query items]];


I've tested this several times right after a sync and so far everything is working great!
Two things:
1) You're leaking memory. Reevaluate the code I highlighted.
2) What happens if the library is empty? What does query contain?

mms13
Apr 21, 2011, 07:54 PM
Two things:
1) You're leaking memory. Reevaluate the code I highlighted.
2) What happens if the library is empty? What does query contain?

Thanks for the tips! I fixed the memory leak and added some code to handle an empty library.