jeudi 8 mars 2012

Catégorie MPMediaItemCollection

Je travaille actuellement sur le chapitre des Plus l'iPhone 3 de développement sur l'accès à la bibliothèque iPod. Je pensais que je jette un morceau de code teaser sous la forme d'une catégorie. MPMediaItemCollection est la classe qui est utilisé pour spécifier les files d'attente de chansons à jouer. Malheureusement, c'est un objet de collection immuable, et il n'ya pas de contrepartie mutables à elle. C'est pourquoi il est une sorte de douleur quand vous avez à ajouter, supprimer ou insérer des éléments dans une collection, ou lorsque vous souhaitez rejoindre les collections multiples ensemble.

Cette catégorie ajoute un tas de méthodes pour MPMediaItemCollection qui font qu'il est plus facile de manipuler les files d'attente jouer. Il ne fait pas MPMediaItemCollection mutables, mais il ne la prochaine meilleure chose. Il est plus facile de créer de nouvelles collections à partir des collections existantes. Il existe des méthodes qui créent de nouvelles collections en insérant ou supprimant des chansons à partir d'une collection existante.

Je prévois d'ajouter quelques méthodes supplémentaires pour le tri et réorganisation des collections pour la version finale de cette catégorie, alors regardez une mise à jour à cela dans les prochains jours.

Note: J'ai fixé un couple de fuites après avoir posté un premier message

MPMediaItemCollection-Utils.h
#import <Foundation/Foundation.h>
#import <MediaPlayer/MediaPlayer.h>

@interface MPMediaItemCollection(Utils)
/** Returns the first media item in the collection
**/

- (MPMediaItem *)firstMediaItem;

/** Returns the last media item in the collection
**/

- (MPMediaItem *)lastMediaItem;

/** This method will return the item in this media collection at a specific index
**/

- (MPMediaItem *)mediaItemAtIndex:(NSUInteger)index;

/** Given a particular media item, this method will return the next media item in the collection.
If there are multiple copies of the same media item in the list, it will return the one
after the first occurrence.
**/

- (MPMediaItem *)mediaItemAfterItem:(MPMediaItem *)compare;

/** Returns the title of the media item at a given index.
**/

- (NSString *)titleForMediaItemAtIndex:(NSUInteger)index;

/** Returns YES if the given media item occurs at least once in this collection
**/

- (BOOL)containsItem:(MPMediaItem *)compare;

/** Creates a new collection by appending otherCollection to the end of this collection
**/

- (MPMediaItemCollection *)collectionByAppendingCollection:(MPMediaItemCollection *)otherCollection;

/** Creates a new collection by appending an array of media items to the end of this collection
**/

- (MPMediaItemCollection *)collectionByAppendingMediaItems:(NSArray *)items;

/** Creates a new collection by appending a single media item to the end of this collection
**/

- (MPMediaItemCollection *)collectionByAppendingMediaItem:(MPMediaItem *)item;

/** Creates a new collection based on this collection, but excluding the specified items.
**/

- (MPMediaItemCollection *)collectionByDeletingMediaItems:(NSArray *)itemsToRemove;

/** Creates a new collection based on this collection, but which doesn't include the specified media item.
**/

- (MPMediaItemCollection *)collectionByDeletingMediaItem:(MPMediaItem *)itemToRemove;

/** Creates a new collection based on this collection, but excluding the media item at the specified index
**/

- (MPMediaItemCollection *)collectionByDeletingMediaItemAtIndex:(NSUInteger)index;

/** Creates a new collection, based on this collection, but excluding the media items starting with
(and including) the objects at index from and ending with (and including) to.
**/

- (MPMediaItemCollection *)collectionByDeletingMediaItemsFromIndex:(NSUInteger)from toIndex:(NSUInteger)to;
@end



MPMediaItemCollection-Utils.m
#import "Simple_PlayerViewController.h"
#import "MPMediaItemCollection-Utils.h"

@implementation Simple_PlayerViewController
@synthesize titleSearch;
@synthesize playPauseButton;
@synthesize tableView;
@synthesize player;
@synthesize collection;
@synthesize nowPlaying;

#pragma mark -
- (IBAction)doTitleSearch {
if ([titleSearch.text length] == 0)
return;
MPMediaPropertyPredicate *titlePredicate =
[MPMediaPropertyPredicate predicateWithValue: titleSearch.text
forProperty: MPMediaItemPropertyTitle
comparisonType:MPMediaPredicateComparisonContains
]
;
MPMediaQuery *query = [[MPMediaQuery alloc] initWithFilterPredicates:[NSSet setWithObject:titlePredicate]];

if ([[query items] count] > 0) {
if (collection)
self.collection = [collection collectionByAppendingMediaItems:[query items]];
else
self.collection = [MPMediaItemCollection collectionWithItems:[query items]];

collectionModified = YES;
[self.tableView reloadData];
}

[query release];
titleSearch.text = @"";
[titleSearch resignFirstResponder];

}


- (IBAction)showMediaPicker {
MPMediaPickerController *picker = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeMusic];
picker.delegate = self;
[picker setAllowsPickingMultipleItems:YES];
picker.prompt = NSLocalizedString(@"Select items to play", @"Select items to play");
[self presentModalViewController:picker animated:YES];
[picker release];
}


- (IBAction)backgroundClick {
[titleSearch resignFirstResponder];
}


- (IBAction)previousTrack {
[player skipToPreviousItem];
}


- (IBAction)nextTrack {
[player skipToNextItem];
}


- (IBAction)playOrPause {
if (player.playbackState == MPMusicPlaybackStatePlaying) {
[player pause];
[playPauseButton setBackgroundImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];
}

else {
[player play];
[playPauseButton setBackgroundImage:[UIImage imageNamed:@"pause.png"] forState:UIControlStateNormal];
}

[self.tableView reloadData];
}


- (IBAction)removeTrack:(id)sender {
NSUInteger index = [sender tag];
MPMediaItem *itemToDelete = [collection mediaItemAtIndex:index];
if ([itemToDelete isEqual:nowPlaying])
[player skipToNextItem];
MPMediaItemCollection *newCollection = [collection collectionByDeletingMediaItemAtIndex:index];
self.collection = newCollection;
collectionModified = YES;

NSUInteger indices[] = {0, index};
NSIndexPath *deletePath = [NSIndexPath indexPathWithIndexes:indices length:2];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:deletePath] withRowAnimation:UITableViewRowAnimationFade];
}


#pragma mark -
- (void)viewDidLoad {
MPMusicPlayerController *thePlayer = [MPMusicPlayerController iPodMusicPlayer];
self.player = thePlayer;
[thePlayer release];

if (player.playbackState == MPMusicPlaybackStatePlaying) {
[playPauseButton setBackgroundImage:[UIImage imageNamed:@"pause.png"] forState:UIControlStateNormal];
MPMediaItemCollection *newCollection = [MPMediaItemCollection collectionWithItems:[NSArray arrayWithObject:[player nowPlayingItem]]];
self.collection = newCollection;
self.nowPlaying = [player nowPlayingItem];
}

else {
[playPauseButton setBackgroundImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];
}





NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver: self
selector: @selector (nowPlayingItemChanged:)
name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification
object: player
]
;

[player beginGeneratingPlaybackNotifications];
}


- (void)viewDidUnload {
self.titleSearch = nil;
self.playPauseButton = nil;
self.tableView = nil;
[super viewDidUnload];
}


- (void)dealloc {
[titleSearch release];
[playPauseButton release];
[tableView release];
[player release];
[collection release];
[super dealloc];
}


#pragma mark -
#pragma mark Media Picker Delegate Methods
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker
didPickMediaItems: (MPMediaItemCollection *) theCollection
{
[self dismissModalViewControllerAnimated: YES];

if (collection == nil){
self.collection = theCollection;
[player setQueueWithItemCollection:collection];
[player setNowPlayingItem:[collection firstMediaItem]];
self.nowPlaying = [collection firstMediaItem];
[player play];
[playPauseButton setBackgroundImage:[UIImage imageNamed:@"pause.png"] forState:UIControlStateNormal];
}

else {
self.collection = [collection collectionByAppendingCollection:theCollection];
}


collectionModified = YES;
[self.tableView reloadData];
}


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


#pragma mark -
#pragma mark Player Notification Methods
- (void)nowPlayingItemChanged:(NSNotification *)notification {
if (![collection containsItem:[player nowPlayingItem]]) {
if (collectionModified) {
[player play];
[player setQueueWithItemCollection:collection];
[player setNowPlayingItem:[collection mediaItemAfterItem:nowPlaying]];
[playPauseButton setBackgroundImage:[UIImage imageNamed:@"pause.png"] forState:UIControlStateNormal];
}

else if ([player nowPlayingItem] != nil) {
MPMediaItem *nowPlayingItem = [player nowPlayingItem];
self.collection = [collection collectionByAppendingMediaItem:nowPlayingItem];
}

}

self.nowPlaying = [player nowPlayingItem];

if (nowPlaying == nil)
[playPauseButton setBackgroundImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];

collectionModified = NO;
[self.tableView reloadData];
}


#pragma mark -
#pragma mark Table View Methods
- (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section {
return [collection count];
}


- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"Music Queue Cell";
UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];

UIButton *removeButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *removeImage = [UIImage imageNamed:@"remove.png"];
[removeButton setBackgroundImage:removeImage forState:UIControlStateNormal];
[removeButton setFrame:CGRectMake(0.0, 0.0, removeImage.size.width, removeImage.size.height)];
[removeButton addTarget:self action:@selector(removeTrack:) forControlEvents:UIControlEventTouchUpInside];
cell.accessoryView = removeButton;
}

cell.textLabel.text = [collection titleForMediaItemAtIndex:[indexPath row]];
if ([nowPlaying isEqual:[collection mediaItemAtIndex:[indexPath row]]]) {
cell.textLabel.font = [UIFont boldSystemFontOfSize:21.0];
if (player.playbackState == MPMusicPlaybackStatePlaying)
cell.imageView.image = [UIImage imageNamed:@"play_small.png"];
else
cell.imageView.image = [UIImage imageNamed:@"pause_small.png"];

}

else {
cell.textLabel.font = [UIFont systemFontOfSize:21.0];
cell.imageView.image = [UIImage imageNamed:@"empty.png"];
}


cell.accessoryView.tag = [indexPath row];


return cell;
}


- (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MPMediaItem *selected = [collection mediaItemAtIndex:[indexPath row]];

if (collectionModified) {
[player setQueueWithItemCollection:collection];
}


[player setNowPlayingItem:selected];
[player play];

[playPauseButton setBackgroundImage:[UIImage imageNamed:@"pause.png"] forState:UIControlStateNormal];
[self.tableView reloadData];
}


- (CGFloat)tableView:(UITableView *)theTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 34;
}


@end



Aucun commentaire: