views:

70

answers:

1

I'm trying to figure out the track number of the MPMusicPlayerController's nowPlayingItem in its playlist. This would be super simple, except for the fact that the same song can appear multiple times in the same playlist (as in they both point to the same file). For example, if a playlist consisted of Song 1, Song 2, Song 1, Song 3, Song 2, I'm stuck on how to determine whether the the nowPlayingItem is, say, the first or the third item in the playlist.

The closest thing I've gotten to solving the problem is creating a category for MPMediaItem that adds an associated object (an NSNumber) containing a "number in playlist" value and a category for MPMusicPlayerController that sets that value for each MPMediaItem in a playlist before adding it to the queue.

MPMediaItem+playlistNumber.h

#import <Foundation/Foundation.h>
#import <MediaPlayer/MediaPlayer.h>
#import <objc/runtime.h>
@interface MPMediaItem (playlistNumber)
-(NSNumber*)numberInPlaylist;
-(void)setNumberInPlaylist:(NSNumber *)number;
@end

MPMediaItem+playlistNumber.m

@implementation MPMediaItem (playlistNumber)
static NSString * numberInPlaylistKey;
-(NSNumber*)numberInPlaylist{
    return objc_getAssociatedObject(self, &numberInPlaylistKey);
}
-(void)setNumberInPlaylist:(NSNumber *)number{
    objc_setAssociatedObject(self, &numberInPlaylistKey, number, OBJC_ASSOCIATION_RETAIN);
}

@end

MPMusicPlayerController+NumberTracks.h

#import <Foundation/Foundation.h>
#import "MPMediaItem+PlaylistNumber.h"
#include <objc/runtime.h>
@interface MPMusicPlayerController (NumberTracks)

-(void)setQueueAndAddNumbersToItemCollection:(MPMediaItemCollection*)collection;
@end

MPMusicPlayerController+NumberTracks.m

#import "MPMusicPlayerController+NumberTracks.h"
@implementation MPMusicPlayerController (NumberTracks)
-(void)setQueueAndAddNumbersToItemCollection:(MPMediaItemCollection*)collection{
    /*
    NSEnumerator *enumerator = [[collection items] objectEnumerator];
    MPMediaItem * object;
    int numberInPlaylist = 1;
    while (object = [enumerator nextObject]) {
        NSNumber * number = [[NSNumber alloc] initWithInt:numberInPlaylist];
        [object setNumberInPlaylist:number];
        NSLog(@"%@", [object numberInPlaylist]);
        NSLog(@"%@", [[[collection items] objectAtIndex:numberInPlaylist-1] numberInPlaylist]);
        NSLog(@"%@", [[[collection items] objectAtIndex:numberInPlaylist-1] valueForProperty:MPMediaItemPropertyTitle]);
        numberInPlaylist++;
    }
    */
    /*
    for (int numberInPlaylist = 1; numberInPlaylist <= collection.count; numberInPlaylist++) {
        NSNumber * number = [[NSNumber alloc] initWithInt:numberInPlaylist];
        [[[collection items] objectAtIndex:numberInPlaylist-1] setNumberInPlaylist:number];
        NSLog(@"%@", [[[collection items] objectAtIndex:numberInPlaylist-1] numberInPlaylist]);
        NSLog(@"%@", [[[collection items] objectAtIndex:numberInPlaylist-1] valueForProperty:MPMediaItemPropertyTitle]);
        [number release];
    }
    */
    NSArray * items = [collection items];
    NSUInteger number = 1;
    for (MPMediaItem * item in items) {
        [item setNumberInPlaylist:[NSNumber numberWithInt: number++]];
        NSLog(@"%@", item.numberInPlaylist);

    }
    [self setQueueWithItemCollection:collection];
    [self play];
    [self pause];
    [self skipToBeginning];
    //The play/pause/skipToBeginnng is so that the nowPlayingItem is actually the first item in the queue
}
@end

In the NumberTracks category implementation, I tried 3 different ways (the two large commented sections and the one large uncommented section) of implementing the assigning of the numberInPlaylist "property". However, when I try and get the nowPlayingItem MPMediaItem, the numberInPlaylist value always returns (null). Is it actually possible to achieve what I'm trying to do? At this point I'm slowly losing faith that it can.

A: 

There is a hidden property called indexOfNowPlayingItem in MPMusicPlayerController. Unfortunately, I can't use it because Apple will reject my app for using private property/methods.

zhbrass