Playlist Generator
1.0
|
00001 // 00002 // SpotifyPlayer.m 00003 // Playlist2 00004 // 00005 // Created by Max Woolf on 20/01/2012. 00006 // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 00007 // 00008 00009 #import "SpotifyPlayer.h" 00010 #import "CocoaLibSpotify.h" 00011 #import "appkey.h" 00012 #import "AddToPlaylistViewController.h" 00013 00014 @implementation SpotifyPlayer 00015 00016 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 00017 { 00018 self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 00019 if (self) { 00020 // Custom initialization 00021 } 00022 return self; 00023 } 00024 00025 - (void)didReceiveMemoryWarning 00026 { 00027 // Releases the view if it doesn't have a superview. 00028 [super didReceiveMemoryWarning]; 00029 00030 // Release any cached data, images, etc that aren't in use. 00031 } 00032 00033 -(void)setArray:(NSArray *)theArray 00034 { 00035 if(trackURIs != theArray) 00036 { 00037 trackURIs = theArray; 00038 } 00039 } 00040 00041 -(void)loginToSpotifyWithUsername:(NSString *)username andPassword:(NSString *)password 00042 { 00043 [hud setMode:MBProgressHUDModeIndeterminate]; 00044 [hud setLabelText:@"Logging in to Spotify..."]; 00045 [hud show:YES]; 00046 [SPSession initializeSharedSessionWithApplicationKey:[NSData dataWithBytes:&g_appkey length:g_appkey_size] userAgent:@"max.playlist2" error:nil]; 00047 [[SPSession sharedSession]attemptLoginWithUserName:username password:password rememberCredentials:NO]; 00048 [[SPSession sharedSession] setDelegate:self]; 00049 [[SPSession sharedSession] setPlaybackDelegate:self]; 00050 } 00051 00052 #pragma mark - Spotify Delegate 00053 - (void)session:(SPSession *)aSession didFailToLoginWithError:(NSError *)error 00054 { 00055 UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Failed to Login" message:[error localizedDescription] delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil]; 00056 [hud hide:YES]; 00057 [errorAlert show]; 00058 } 00059 00060 - (void)sessionDidLoginSuccessfully:(SPSession *)aSession 00061 { 00062 NSLog(@"Login Successful"); 00063 00064 [hud setLabelText:@"Loading track"]; 00065 //Create a playback manager 00066 manager = [[SPPlaybackManager alloc] initWithPlaybackSession:[SPSession sharedSession]]; 00067 [self playTrackAtIndex:0]; 00068 } 00069 00070 - (void)sessionDidLosePlayToken:(SPSession *)aSession 00071 { 00072 [SPSession sharedSession].playing = NO; 00073 //[playPauseButton setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal]; 00074 UIAlertView *loseTokenAlert = [[UIAlertView alloc] initWithTitle:@"Sorry" message:@"Playback was paused because this account was logged in elsewhere" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; 00075 [loseTokenAlert show]; 00076 } 00077 00078 - (void)sessionDidEndPlayback:(SPSession *)aSession 00079 { 00080 [self nextTrack:nil]; 00081 } 00082 00083 - (void)session:(SPSession *)aSession didEncounterStreamingError:(NSError *)error 00084 { 00085 UIAlertView *streamingErrorAlert = [[UIAlertView alloc] initWithTitle:@"Awww... crap." message:@"Streaming error, this isn't going to work..." delegate:self cancelButtonTitle:@"Alright" otherButtonTitles:nil]; 00086 [streamingErrorAlert show]; 00087 } 00088 00089 #pragma mark - Controls 00090 //Called to play the track at index in the preloaded array of Spotify URIs. 00091 //index should already be validated before this is called or it will throw an out of bounds exception. 00092 -(void)playTrackAtIndex:(NSNumber *)index 00093 { 00094 NSURL *trackURL = [NSURL URLWithString:[trackURIs objectAtIndex:[index intValue]]]; 00095 SPTrack *track = [[SPSession sharedSession] trackForURL:trackURL]; 00096 if (track != nil) { 00097 00098 if (!track.isLoaded) { 00099 NSLog(@"Still waiting for metadata to load... trying again."); 00100 [self performSelector:@selector(playTrackAtIndex:) withObject:index afterDelay:0.1]; 00101 return; 00102 } 00103 00104 //Set metadata 00105 SPArtist *currentArtist = [[track artists]objectAtIndex:0]; //Just get the first artist, there might be a few 00106 00107 NSString *artistName = [[NSString alloc] initWithString:currentArtist.name]; 00108 [artistLabel setText:artistName]; 00109 [trackLabel setText:[track name]]; 00110 00111 nowPlayingInfo = [[NSMutableDictionary alloc] init]; 00112 [nowPlayingInfo setValue:artistName forKey:MPMediaItemPropertyAlbumArtist]; 00113 [nowPlayingInfo setValue:[track name] forKey:MPMediaItemPropertyTitle]; 00114 00115 [self getCoverImageForTrack:track]; 00116 00117 NSError *error = nil; 00118 if (![manager playTrack:track error:&error]) { 00119 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Cannot Play Track" 00120 message:[error localizedDescription] 00121 delegate:nil 00122 cancelButtonTitle:@"OK" 00123 otherButtonTitles:nil]; 00124 [alert show]; 00125 } 00126 00127 00128 [hud hide:YES afterDelay:1]; 00129 currentTrackPlayingIndex = [index intValue]; 00130 currentTrackDuration = [track duration]; 00131 [progressMeter setMaximumValue:currentTrackDuration]; 00132 00133 timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:YES]; 00134 [[NSRunLoop currentRunLoop]addTimer:timer forMode:NSDefaultRunLoopMode]; 00135 return; 00136 } 00137 } 00138 00139 - (void)timerFireMethod:(NSTimer*)theTimer 00140 { 00141 [progressMeter setValue:[progressMeter value]+1]; 00142 } 00143 00144 -(IBAction)togglePlayPause:(id)sender 00145 { 00146 if(manager.isPlaying) 00147 { 00148 [SPSession sharedSession].playing = NO; 00149 [playPauseButton setImage:[UIImage imageNamed:@"play.png"]]; 00150 }else{ 00151 [SPSession sharedSession].playing = YES; 00152 [playPauseButton setImage:[UIImage imageNamed:@"pause.png"]]; 00153 } 00154 } 00155 00156 -(IBAction)movedSlider:(id)sender; 00157 { 00158 NSLog(@"%f", [progressMeter value]); 00159 [manager seekToTrackPosition:[progressMeter value]]; 00160 } 00161 00162 -(IBAction)nextTrack:(id)sender 00163 { 00164 if(currentTrackPlayingIndex < [trackURIs count]-1) 00165 { 00166 [hud setLabelText:@"Loading"]; 00167 [hud show:YES]; 00168 [progressMeter setValue:0]; 00169 [timer invalidate]; 00170 [self playTrackAtIndex: [NSNumber numberWithInt:currentTrackPlayingIndex+1]]; 00171 } 00172 } 00173 00174 -(IBAction)previousTrack:(id)sender 00175 { 00176 //Make sure you don't overshoot the array 00177 if(!currentTrackPlayingIndex == 0) 00178 { 00179 [hud setLabelText:@"Loading"]; 00180 [hud show:YES]; 00181 [progressMeter setValue:0]; 00182 [timer invalidate]; 00183 [self playTrackAtIndex:[NSNumber numberWithInt:currentTrackPlayingIndex-1]]; 00184 } 00185 } 00186 00187 -(void)getCoverImageForTrack:(SPTrack *)track 00188 { 00189 SPAlbum *currentAlbum = [track album]; 00190 SPImage *coverSPImage = [currentAlbum cover]; 00191 [coverSPImage beginLoading]; 00192 00193 if (!coverSPImage.loaded) { 00194 NSLog(@"Still waiting for image to load... trying again."); 00195 [self performSelector:@selector(getCoverImageForTrack:) withObject:track afterDelay:0.1]; 00196 return; 00197 } 00198 00199 UIImage *coverImage = [coverSPImage image]; 00200 [nowPlayingInfo setValue:[[MPMediaItemArtwork alloc]initWithImage:coverImage] forKey:MPMediaItemPropertyArtwork]; 00201 [nowPlaying setNowPlayingInfo:nowPlayingInfo]; 00202 [coverImageView setImage:coverImage]; 00203 } 00204 00205 #pragma mark - Action Sheet 00206 -(void)showActionSheet:(id)sender 00207 { 00208 UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Options" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Add Track to Spotify Playlist", nil]; 00209 [actionSheet showFromToolbar:bottomToolbar]; 00210 } 00211 00212 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex 00213 { 00214 if(buttonIndex == 0) 00215 { 00216 AddToPlaylistViewController *playlistController = [[AddToPlaylistViewController alloc] initWithURI:[trackURIs objectAtIndex:currentTrackPlayingIndex]]; 00217 [self presentModalViewController:playlistController animated:YES]; 00218 } 00219 } 00220 00221 -(void) initAudioSession 00222 { 00223 // Registers this class as the delegate of the audio session to listen for audio interruptions 00224 [[AVAudioSession sharedInstance] setDelegate: self]; 00225 //Set the audio category of this app to playback. 00226 NSError *setCategoryError = nil; [[AVAudioSession sharedInstance] 00227 setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError]; 00228 00229 00230 //Activate the audio session 00231 NSError *activationError = nil; 00232 [[AVAudioSession sharedInstance] setActive: YES error: &activationError]; 00233 00234 } 00235 00236 - (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent { 00237 if (receivedEvent.type == UIEventTypeRemoteControl) { 00238 switch (receivedEvent.subtype) { 00239 case UIEventSubtypeRemoteControlTogglePlayPause: { 00240 [self togglePlayPause:self]; 00241 break; 00242 } 00243 00244 case UIEventSubtypeRemoteControlNextTrack: { 00245 [self nextTrack:self]; 00246 break; 00247 } 00248 00249 case UIEventSubtypeRemoteControlPreviousTrack: { 00250 [self previousTrack:self]; 00251 break; 00252 } 00253 default: 00254 break; 00255 } 00256 } 00257 } 00258 00259 #pragma mark - View lifecycle 00260 -(void)viewDidAppear:(BOOL)animated 00261 { 00262 [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; 00263 [self becomeFirstResponder]; 00264 hud = [[MBProgressHUD alloc] initWithView:self.navigationController.view]; 00265 [self.navigationController.view addSubview:hud]; 00266 [self loginToSpotifyWithUsername:@"maxehmookau" andPassword:@"edithdora6"]; 00267 } 00268 00269 - (void)viewDidLoad 00270 { 00271 [self.navigationController setNavigationBarHidden:YES]; 00272 [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:YES]; 00273 nowPlaying = [MPNowPlayingInfoCenter defaultCenter]; 00274 00275 [self initAudioSession]; 00276 currentTrackPlayingIndex = 0; 00277 [super viewDidLoad]; 00278 // Do any additional setup after loading the view from its nib. 00279 } 00280 - (BOOL) canBecomeFirstResponder { 00281 return YES; 00282 } 00283 00284 - (void)viewDidUnload 00285 { 00286 [[UIApplication sharedApplication] endReceivingRemoteControlEvents]; 00287 [self resignFirstResponder]; 00288 [super viewDidUnload]; 00289 // Release any retained subviews of the main view. 00290 // e.g. self.myOutlet = nil; 00291 } 00292 00293 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 00294 { 00295 // Return YES for supported orientations 00296 return (interfaceOrientation == UIInterfaceOrientationPortrait); 00297 } 00298 00299 @end