Home / iPhone Tips and Tutorials

Accessing and Playing the iPod Library

When Apple opened iOS for development, they didn't initially provide a method for accessing the iPod library. This led to applications implementing their own libraries for background music and a less-than-ideal experience for the end user.

Thankfully, developers can now directly access the iPod library and play any of the available music files. Best of all, this is amazingly simple to implement!

First, you'll be using the MPMediaPickerController class to choose the music to play. There's only a single method we'll be calling from this class:

initWithMediaTypes: Initializes the media picker and filters the files that are available in the picker

We'll configure its behavior with a handful of properties that can be set on the object:

prompt: A string that is displayed to the user when choosing songs allowsPickingMultipleItems: Configures whether the user can choose one or more sound files

Like the AVAudioPlayer, we're going to conform to the

MPMediaPickerControllerDelegate protocol so that we can react when the user chooses a playlist. The method that we'll be adding as part of the protocol is mediaPicker:didPickMediaItems:.

To play back the audio, we'll take advantage of the MPMusicPlayerController class, which can use the playlist returned by the media picker. To control starting and pausing the playback, we'll use four methods:

iPodMusicPlayer: This class method initializes the music player as an "iPod" music player, capable of accessing the iPod music library.
setQueueWithItemCollection: Sets the playback queue using a playlist (MPMediaItemCollection) object returned by the media picker.
play: Starts playing music.
pause: Pauses the music playback.

As you can see, when you get the hang of one of the media classes, the others start to seem very "familiar," using similar initialization and playback control methods.

The iPod music playback features require the same Media Player framework we added previously for the MPMoviePlayerController class. If you skipped that section, return to the "Adding the Media Player Framework" section, earlier in this lesson.

Implementing the Media Picker

To use a media picker, we'll follow steps similar to the Image Picker: We'll initialize and configure the behavior of the picker, and then add the picker as a modal view. When the user is done with the picker, we'll add the playlist it returns to the music player and dismiss the picker view controller. If the user decides they don't want to pick anything, we'll simply dismiss the picker and move on.

For all of these steps to fall into place, we must already have an instance of the music player so that we can hand off the playlist. Recall that we declared an instance variable musicPlayer for the MediaPlaygroundViewController class. We'll go ahead and initialize this variable in the MediaPlaygroundViewController.m viewDidLoad method. Add the following line to the method now (the location isn't important):

musicPlayer=[MPMusicPlayerController iPodMusicPlayer];

With that small addition, our instance of the music player is ready, so we can proceed with coding the chooseiPod: method to display the media picker.

Update the MediaPlaygroundViewController implementation file with the new method in Listing-9.

LISTING-9

1: -(IBAction)chooseiPod:(id)sender {
2:     MPMediaPickerController *musicPicker;
3:
4:     [musicPlayer stop];
5:     nowPlaying.text=@"No Song Playing";
6:     [ipodPlayButton setTitle:@"Play iPod Music"
7: 			forState:UIControlStateNormal];
8:
9:     musicPicker = [[MPMediaPickerController alloc]
10: 			initWithMediaTypes: MPMediaTypeMusic];
11:
12:    musicPicker.prompt = @"Choose Songs to Play" ;
13:    musicPicker.allowsPickingMultipleItems = YES;
14:    musicPicker.delegate = self;
15:
16:     [self presentModalViewController:musicPicker animated:YES];
17:     [musicPicker release];
18: }

First, line 2 declares the instance of MPMediaPickerController, musicPicker.

Next, lines 4-7 make sure that when the picker is called, the music player will stop playing its current song, the nowPlaying label in the interface is set to the default string "No Song Playing", and the playback button is set to read "Play iPod Music". These lines aren't necessary, but they keep our interface from being out of sync with what is actually going on in the application.

Lines 9-10 allocate and initialize the media picker controller instance. It is initialized with a constant, MPMediaTypeMusic, that defines the type of files the user will be allowed to choose with the picker. You can provide any of five values listed here:

MPMediaTypeMusic 	Music files
MPMediaTypePodcast 	Podcasts
MPMediaTypeAudioBook 	Audio books
MPMediaTypeAnyAudio 	Any audio type
MPMediaTypeAny 		Any media type

Line 12 sets a message that will be displayed at the top of the music picker. In line 13, we set the allowsPickingMultipleItems property to a Boolean value (YES or NO) to configure whether the user can select one or more media files.

Line 14 sets the delegate music picker's delegate. In other words, it tells the musicPicker object to look in the MediaPlaygroundViewController for the MPMediaPickerControllerDelegate protocol methods.

Line 16 uses the musicPicker view controller to display the iPod music library over the top of our application's view.

Finally, line 17 releases the musicPicker.

If you find it confusing that you release the musicPicker in this method, I don't blame you. After the music picker is added to the modal view, its retain count is incremented, so releasing it essentially means that we aren't responsible for it anymore. When the modal view controller is dismissed later, the music picker will be autoreleased.
What's frustrating is that although this init, alloc, release pattern works well here, you may find yourself thinking that some other object can be managed similarly and end up releasing when you shouldn't. Only a thorough read of the corresponding Apple documentation will tell you with certainty how something will behave.

Getting the Playlist

To get the playlist that is returned by media picker (an object called MPMediaItem Collection) and clean up after ourselves, we'll add the mediaPicker:didPick MediaItems: protocol method from Listing 18.10 to our growing implementation.

LISTING-10

1: - (void)mediaPicker: (MPMediaPickerController *)mediaPicker
2: 		didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection {
3:     [musicPlayer setQueueWithItemCollection: mediaItemCollection];
4:     [self dismissModalViewControllerAnimated:YES];
5: }

When the user is finished picking songs in the media picker, this method is called and passed the chosen items in a MPMediaItemCollection object, mediaItemCollection. In line 3, the music player instance, musicPlayer, is subsequently configured with the playlist via the setQueueWithItemCollection: method.

To clean things up, the modal view is dismissed in line 4.

Cleaning Up After the Media Picker

We've got one more situation to account for before we can wrap up the media picker: the possibility of a user exiting the media picker without choosing anything (touching Done without picking any tracks). To cover this event, we'll add the delegate protocol method mediaPickerDidCancel. As with the image picker, we just need to dismiss the modal view controller. Add this method to the MediaPlaygroundViewController.m file:

- (void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker {
    [self dismissModalViewControllerAnimated:YES];
}

Congratulations! You're almost finished! The media picker feature is now implemented, so our only remaining task is to add the music player and make sure the corresponding song titles are displayed.

[Previous] [Contents] [Next]