iosnskeyedarchivermpmediaitemmpmediaitemcollectionnskeyedunarchiver

NSKeyedArchiver Doesn't Seem Properly Save an MPMediaItemCollection Object


I am trying to save a playlist of songs created with the media picker. I tried to use the suggestion provided in Persist a MPMediaItemCollection Object Using NSUserDefaults. This solution uses NSKeyedArchiver as follows:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:mediaItemCollection];

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:data forKey:@"someKey"];
[defaults synchronize];

Then when the MPMediaItemCollection needs to be retrieved, the following is performed:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:@"someKey"];
MPMediaItemCollection *mediaItemCollection = [NSKeyedUnarchiver unarchiveObjectWithData:data];

While this seemed to work at first, I found that it doesn't work consistently over time. It seems that after my app is loaded after a new software release, some of the media items in the playlist are corrupted. For example, when I try to load the song title from the retrieved MPMediaItemCollection for display in a tableView as follows:

MPMediaItem *anItem = (MPMediaItem *)[mediaItemCollection.items objectAtIndex: row];

if (anItem) {
    cell.textLabel.text = [anItem valueForProperty:MPMediaItemPropertyTitle];

    if (cell.textLabel.text == nil) {
        NSString * persistentID = [anItem valueForProperty:MPMediaItemPropertyPersistentID];
        ...
}

the song title is nil for some of the entries. If I try to grab the persistentID for the song at this index in the queue, there is a persistentID, but it doesn't point to a valid song (so its probably just garbage).

SO THE QUESTION IS: Is it possible to save a MPMediaItemCollection that I can be sure is valid across all launches and software upgrades (both my upgrades and iOS upgrades). If so, how?


Solution

  • The answer is not this way! the MPMediaItemCollection object cannot be converted to either NSArray, NSDictionary or any other object that we can archive in NSUserDefaults.

    My suggestion is to enumerate through the collection, save an array of [anItem valueForProperty:MPMediaItemPropertyPersistentID] s. save it in the NSUserDefaults

    then on the next run of the application, you read and enumerate through the NSArray and create the MPMediaItemCollection back with items with persistentIDs.

    I hope it helps