Merge lp:~rockstar/ubuntuone-ios-music/storyboard-20api-views into lp:ubuntuone-ios-music

Proposed by Paul Hummer
Status: Merged
Approved by: Paul Hummer
Approved revision: 249
Merged at revision: 241
Proposed branch: lp:~rockstar/ubuntuone-ios-music/storyboard-20api-views
Merge into: lp:ubuntuone-ios-music
Diff against target: 4631 lines (+3809/-252)
52 files modified
Music/Models/Album.h (+29/-0)
Music/Models/Album.m (+94/-0)
Music/Models/Artist.h (+24/-0)
Music/Models/Artist.m (+61/-0)
Music/Models/Playlist.h (+21/-0)
Music/Models/Playlist.m (+52/-0)
Music/Models/Song.h (+45/-0)
Music/Models/Song.m (+179/-0)
Music/Models/UOModel.h (+25/-0)
Music/Models/UOModel.m (+66/-0)
Music/Storyboard_iPhone.storyboard (+892/-0)
Music/UOAppDelegate.h (+28/-0)
Music/UOAppDelegate.m (+208/-0)
Music/UOMusic.xcdatamodeld/UOMusic.xcdatamodel/contents (+60/-0)
Music/Utilities/UOWebServiceController.h (+39/-0)
Music/Utilities/UOWebServiceController.m (+208/-0)
Music/View Controllers/AlbumViewController.h (+17/-0)
Music/View Controllers/AlbumViewController.m (+149/-0)
Music/View Controllers/AlbumsViewController.h (+12/-0)
Music/View Controllers/AlbumsViewController.m (+60/-0)
Music/View Controllers/ArtistViewController.h (+17/-0)
Music/View Controllers/ArtistViewController.m (+140/-0)
Music/View Controllers/ArtistsViewController.h (+12/-0)
Music/View Controllers/ArtistsViewController.m (+64/-0)
Music/View Controllers/PlayerViewController.h (+31/-0)
Music/View Controllers/PlayerViewController.m (+118/-0)
Music/View Controllers/PlaylistsViewController.h (+12/-0)
Music/View Controllers/PlaylistsViewController.m (+48/-0)
Music/View Controllers/SettingsAboutViewController.h (+13/-0)
Music/View Controllers/SettingsAboutViewController.m (+42/-0)
Music/View Controllers/SettingsAuthenticationViewController.h (+13/-0)
Music/View Controllers/SettingsAuthenticationViewController.m (+117/-0)
Music/View Controllers/SettingsViewController.h (+13/-0)
Music/View Controllers/SettingsViewController.m (+60/-0)
Music/View Controllers/SongsViewController.h (+12/-0)
Music/View Controllers/SongsViewController.m (+70/-0)
Music/View Controllers/UOIndexedViewController.h (+31/-0)
Music/View Controllers/UOIndexedViewController.m (+169/-0)
Music/Views/PlayerHeaderView.h (+21/-0)
Music/Views/PlayerHeaderView.m (+25/-0)
Music/Views/Table Cells/AlbumCell.h (+14/-0)
Music/Views/Table Cells/AlbumCell.m (+32/-0)
Music/Views/Table Cells/ArtistCell.h (+14/-0)
Music/Views/Table Cells/ArtistCell.m (+37/-0)
Music/Views/Table Cells/PlaylistCell.h (+14/-0)
Music/Views/Table Cells/PlaylistCell.m (+26/-0)
Music/Views/Table Cells/SongCell.h (+14/-0)
Music/Views/Table Cells/SongCell.m (+32/-0)
Music/main.m (+2/-2)
U1Music-Info.plist (+3/-3)
U1Music.xcodeproj/project.pbxproj (+320/-247)
U1Music_Prefix.pch (+4/-0)
To merge this branch: bzr merge lp:~rockstar/ubuntuone-ios-music/storyboard-20api-views
Reviewer Review Type Date Requested Status
Michał Karnicki (community) Approve
Review via email: mp+144754@code.launchpad.net

Commit message

Use 2.0 Music API

To post a comment you must log in.
Revision history for this message
Michał Karnicki (karni) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'Music'
2=== added directory 'Music/Models'
3=== added file 'Music/Models/Album.h'
4--- Music/Models/Album.h 1970-01-01 00:00:00 +0000
5+++ Music/Models/Album.h 2013-01-24 17:06:42 +0000
6@@ -0,0 +1,29 @@
7+//
8+// Album.h
9+// U1Music
10+//
11+// Created by Paul Hummer on 11/17/12.
12+// Copyright (c) 2012 Canonical. All rights reserved.
13+//
14+
15+#import <Foundation/Foundation.h>
16+#import "Artist.h"
17+#import "UOModel.h"
18+
19+@class RKObjectManager;
20+
21+@interface Album : UOModel
22+@property (nonatomic, retain) NSString *albumId;
23+@property (nonatomic, retain) NSString *title;
24+@property (nonatomic, retain) NSString *url;
25+@property (nonatomic, retain) NSString *artHash;
26+
27+@property (nonatomic, retain, readonly) NSString *dearticlizedTitle;
28+@property (nonatomic, retain, readonly) NSString *index;
29+
30+@property (nonatomic, retain) NSString *artistId;
31+@property (nonatomic, retain, readonly) Artist *artist;
32+
33+@property (nonatomic, retain) NSSet *songs;
34+
35+@end
36
37=== added file 'Music/Models/Album.m'
38--- Music/Models/Album.m 1970-01-01 00:00:00 +0000
39+++ Music/Models/Album.m 2013-01-24 17:06:42 +0000
40@@ -0,0 +1,94 @@
41+//
42+// Album.m
43+// U1Music
44+//
45+// Created by Paul Hummer on 11/17/12.
46+// Copyright (c) 2012 Canonical. All rights reserved.
47+//
48+
49+#import "Album.h"
50+#import <RestKit/RestKit.h>
51+#import <RestKit/CoreData.h>
52+#import "Artist.h"
53+#import "NSString+Extras.h"
54+#import "UOAppDelegate.h"
55+
56+@implementation Album
57+@dynamic albumId;
58+@dynamic title;
59+@dynamic url;
60+@dynamic artHash;
61+@dynamic dearticlizedTitle;
62+
63+@synthesize index;
64+
65+@synthesize artistId;
66+@dynamic artist;
67+
68+@dynamic songs;
69+
70+#pragma mark - UOModel methods
71+
72++ (RKEntityMapping *)objectMapping {
73+ RKObjectManager *manager = [RKObjectManager sharedManager];
74+
75+ RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Album" inManagedObjectStore:manager.managedObjectStore];
76+ [mapping setIdentificationAttributes:@[@"albumId"]];
77+ [mapping addAttributeMappingsFromDictionary:@{
78+ @"id": @"albumId",
79+ @"album_url": @"url",
80+ @"cover_art": @"artHash",
81+ @"album_art_url": @"artUrl",
82+ @"title": @"title",
83+ @"artist_id": @"artistId"
84+ }];
85+
86+ return mapping;
87+}
88+
89++ (NSString *)keyPath {
90+ return @"response.albums";
91+}
92+
93+- (NSString *)artPath {
94+ return [[[[UOAppDelegate delegate] albumArtDirectory] URLByAppendingPathComponent:[NSString stringWithFormat:@"album-%@.jpg", self.albumId]] path];
95+}
96+
97+#pragma mark - Model specific methods
98+
99+- (void)setTitle:(NSString *)title {
100+ [self setPrimitiveValue:title forKey:@"title"];
101+ [self setValue:[[title dearticlizedString] uppercaseString] forKey:@"dearticlizedTitle"];
102+}
103+
104+- (void)setArtistId:(NSString *)_artistId {
105+ NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
106+ NSEntityDescription *entity = [NSEntityDescription entityForName:@"Artist" inManagedObjectContext:self.managedObjectContext];
107+ [fetchRequest setEntity:entity];
108+
109+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(artistId = %@)", _artistId];
110+ [fetchRequest setPredicate:predicate];
111+
112+ NSError *error;
113+ NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
114+ if (error || [results count] != 1) {
115+ abort();
116+ }
117+
118+ Artist *_artist = [results objectAtIndex:0];
119+ [self setPrimitiveValue:_artist forKey:@"artist"];
120+}
121+
122+- (NSString *)artistId {
123+ return self.artist.artistId;
124+}
125+
126+- (NSString *)index {
127+ [self willAccessValueForKey:@"index"];
128+ NSString *_index = [[self.title dearticlizedIndex] uppercaseString];
129+ [self didAccessValueForKey:@"index"];
130+ return _index;
131+}
132+
133+
134+@end
135
136=== added file 'Music/Models/Artist.h'
137--- Music/Models/Artist.h 1970-01-01 00:00:00 +0000
138+++ Music/Models/Artist.h 2013-01-24 17:06:42 +0000
139@@ -0,0 +1,24 @@
140+//
141+// Artist.h
142+// U1Music
143+//
144+// Created by Paul Hummer on 11/16/12.
145+// Copyright (c) 2012 Canonical. All rights reserved.
146+//
147+
148+#import <Foundation/Foundation.h>
149+#import "UOModel.h"
150+
151+@class RKObjectManager;
152+
153+@interface Artist : UOModel
154+@property (nonatomic, retain) NSString *artistId;
155+@property (nonatomic, retain) NSString *name;
156+@property (nonatomic, retain) NSString *url;
157+
158+@property (nonatomic, retain, readonly) NSString *dearticlizedName;
159+@property (nonatomic, retain, readonly) NSString *index;
160+
161+@property (nonatomic, retain) NSSet *albums;
162+
163+@end
164
165=== added file 'Music/Models/Artist.m'
166--- Music/Models/Artist.m 1970-01-01 00:00:00 +0000
167+++ Music/Models/Artist.m 2013-01-24 17:06:42 +0000
168@@ -0,0 +1,61 @@
169+//
170+// Artist.m
171+// U1Music
172+//
173+// Created by Paul Hummer on 11/16/12.
174+// Copyright (c) 2012 Canonical. All rights reserved.
175+//
176+
177+#import "Artist.h"
178+#import <RestKit/RestKit.h>
179+#import "NSString+Extras.h"
180+#import "UOAppDelegate.h"
181+
182+@implementation Artist
183+@dynamic artistId;
184+@dynamic name;
185+@dynamic url;
186+@dynamic albums;
187+@dynamic dearticlizedName;
188+
189+@synthesize index;
190+
191+#pragma mark - UOModel methods
192+
193++ (RKEntityMapping *)objectMapping {
194+ RKObjectManager *manager = [RKObjectManager sharedManager];
195+
196+ RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Artist" inManagedObjectStore:manager.managedObjectStore];
197+ [mapping setIdentificationAttributes:@[@"artistId"]];
198+ [mapping addAttributeMappingsFromDictionary:@{
199+ @"id" : @"artistId",
200+ @"artist": @"name",
201+ @"artist_url": @"url",
202+ @"artist_art_url": @"artUrl",
203+ }];
204+ return mapping;
205+}
206+
207++ (NSString *)keyPath {
208+ return @"response.artists";
209+}
210+
211+- (NSString *)artPath {
212+ return [[[[UOAppDelegate delegate] albumArtDirectory] URLByAppendingPathComponent:[NSString stringWithFormat:@"artist-%@.jpg", self.artistId]] path];
213+}
214+
215+#pragma mark - Model specific methods
216+
217+- (void)setName:(NSString *)name {
218+ [self setPrimitiveValue:name forKey:@"name"];
219+ [self setValue:[[name dearticlizedString] uppercaseString] forKey:@"dearticlizedName"];
220+}
221+
222+- (NSString *)index {
223+ [self willAccessValueForKey:@"index"];
224+ NSString *_index = [[self.name dearticlizedIndex] uppercaseString];
225+ [self didAccessValueForKey:@"index"];
226+ return _index;
227+}
228+
229+@end
230
231=== added file 'Music/Models/Playlist.h'
232--- Music/Models/Playlist.h 1970-01-01 00:00:00 +0000
233+++ Music/Models/Playlist.h 2013-01-24 17:06:42 +0000
234@@ -0,0 +1,21 @@
235+//
236+// Playlist.h
237+// U1Music
238+//
239+// Created by Paul Hummer on 11/17/12.
240+// Copyright (c) 2012 Canonical. All rights reserved.
241+//
242+
243+#import <Foundation/Foundation.h>
244+#import "UOModel.h"
245+
246+@interface Playlist : UOModel
247+@property (nonatomic, retain) NSString *playlistId;
248+@property (nonatomic, retain) NSString *title;
249+@property (nonatomic, retain) NSString *url;
250+@property (nonatomic, retain) NSNumber *songCount;
251+
252+@property (nonatomic, retain, readonly) NSString *dearticlizedTitle;
253+@property (nonatomic, retain, readonly) NSString *index;
254+
255+@end
256
257=== added file 'Music/Models/Playlist.m'
258--- Music/Models/Playlist.m 1970-01-01 00:00:00 +0000
259+++ Music/Models/Playlist.m 2013-01-24 17:06:42 +0000
260@@ -0,0 +1,52 @@
261+//
262+// Playlist.m
263+// U1Music
264+//
265+// Created by Paul Hummer on 11/17/12.
266+// Copyright (c) 2012 Canonical. All rights reserved.
267+//
268+
269+#import "Playlist.h"
270+#import <RestKit/RestKit.h>
271+#import "NSString+Extras.h"
272+
273+@implementation Playlist
274+@dynamic playlistId;
275+@dynamic title;
276+@dynamic url;
277+@dynamic songCount;
278+@dynamic dearticlizedTitle;
279+
280+@synthesize index;
281+
282++ (RKEntityMapping *)objectMapping {
283+ RKObjectManager *manager = [RKObjectManager sharedManager];
284+
285+ RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Playlist" inManagedObjectStore:manager.managedObjectStore];
286+ [mapping setIdentificationAttributes:@[@"playlistId"]];
287+ [mapping addAttributeMappingsFromDictionary:@{
288+ @"id": @"playlistId",
289+ @"playlist_url": @"url",
290+ @"name": @"title",
291+ @"song_count": @"songCount",
292+ }];
293+ return mapping;
294+}
295+
296++ (NSString *)keyPath {
297+ return @"response.playlists";
298+}
299+
300+- (void)setTitle:(NSString *)_title {
301+ [self setPrimitiveValue:_title forKey:@"title"];
302+ [self setValue:[[_title dearticlizedString] uppercaseString] forKey:@"dearticlizedTitle"];
303+}
304+
305+- (NSString *)index {
306+ [self willAccessValueForKey:@"index"];
307+ NSString *_index = [[self.title dearticlizedIndex] uppercaseString];
308+ [self didAccessValueForKey:@"index"];
309+ return _index;
310+}
311+
312+@end
313
314=== added file 'Music/Models/Song.h'
315--- Music/Models/Song.h 1970-01-01 00:00:00 +0000
316+++ Music/Models/Song.h 2013-01-24 17:06:42 +0000
317@@ -0,0 +1,45 @@
318+//
319+// Song.h
320+// U1Music
321+//
322+// Created by Paul Hummer on 11/17/12.
323+// Copyright (c) 2012 Canonical. All rights reserved.
324+//
325+
326+#import <Foundation/Foundation.h>
327+#import "UOModel.h"
328+
329+@class Album;
330+@class Artist;
331+
332+@interface Song : UOModel
333+
334+@property (nonatomic, retain) NSString *url;
335+@property (nonatomic, retain) NSString *suffix;
336+@property (nonatomic, retain) NSString *track;
337+@property (nonatomic, retain) NSString *title;
338+@property (nonatomic, retain) NSString *bitRate;
339+@property (nonatomic, retain) NSString *songId;
340+@property (nonatomic, retain) NSString *duration;
341+@property (nonatomic, retain) NSString *discNumber;
342+@property (nonatomic, retain) NSString *streamUrl;
343+@property (nonatomic, retain) NSString *contentType;
344+@property (nonatomic, retain) NSString *year;
345+@property (nonatomic, retain) NSString *genre;
346+@property (nonatomic, retain) NSString *path;
347+@property (nonatomic, retain) NSString *size;
348+
349+@property (nonatomic, retain, readonly) NSString *dearticlizedTitle;
350+@property (nonatomic, retain, readonly) NSString *index;
351+
352+@property (nonatomic, retain) NSString *artistId;
353+@property (nonatomic, retain) NSString *albumId;
354+@property (nonatomic, retain) NSString *albumArtistId;
355+
356+@property (nonatomic, retain, readonly) Artist *artist;
357+@property (nonatomic, retain, readonly) Album *album;
358+@property (nonatomic, retain, readonly) Artist *albumArtist;
359+
360+@property (nonatomic, retain, readonly) NSString *idPath;
361+
362+@end
363
364=== added file 'Music/Models/Song.m'
365--- Music/Models/Song.m 1970-01-01 00:00:00 +0000
366+++ Music/Models/Song.m 2013-01-24 17:06:42 +0000
367@@ -0,0 +1,179 @@
368+//
369+// Song.m
370+// U1Music
371+//
372+// Created by Paul Hummer on 11/17/12.
373+// Copyright (c) 2012 Canonical. All rights reserved.
374+//
375+
376+#import "Song.h"
377+#import <RestKit/RestKit.h>
378+#import "Artist.h"
379+#import "Album.h"
380+#import "NSString+Extras.h"
381+#import "UOAppDelegate.h"
382+
383+@implementation Song
384+
385+@dynamic url;
386+@dynamic suffix;
387+@dynamic track;
388+@dynamic title;
389+@dynamic bitRate;
390+@dynamic songId;
391+@dynamic duration;
392+@dynamic discNumber;
393+@dynamic streamUrl;
394+@dynamic contentType;
395+@dynamic year;
396+@dynamic genre;
397+@dynamic path;
398+@dynamic size;
399+@dynamic dearticlizedTitle;
400+
401+@synthesize index;
402+/* Override to fall through to album's artUrl */
403+@synthesize artUrl;
404+
405+@dynamic album;
406+@dynamic artist;
407+@dynamic albumArtist;
408+
409+#pragma mark - UOModel methods
410+
411++ (RKEntityMapping *)objectMapping {
412+ RKObjectManager *manager = [RKObjectManager sharedManager];
413+
414+ RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Song" inManagedObjectStore:manager.managedObjectStore];
415+ [mapping setIdentificationAttributes:@[@"songId"]];
416+ [mapping addAttributeMappingsFromDictionary:@{
417+ @"song_url": @"url",
418+ /* Disabled, since we want to fall through to album's art.
419+ @"song_art_url": @"artUrl",
420+ */
421+ @"suffix": @"suffix",
422+ @"track": @"track",
423+ @"title": @"title",
424+ @"album_artist_id": @"albumArtistId",
425+ @"bit_rate": @"bitRate",
426+ @"id": @"songId",
427+ @"duration": @"duration",
428+ @"disc_number": @"discNumber",
429+ @"song_stream_url": @"streamUrl",
430+ @"content_type": @"contentType",
431+ @"year": @"year",
432+ @"genre": @"genre",
433+ @"path": @"path",
434+ @"artist_id": @"artistId",
435+ @"album_id": @"albumId",
436+ @"size": @"size"
437+ }];
438+ return mapping;
439+}
440+
441++ (NSString *)keyPath {
442+ return @"response.songs";
443+}
444+
445+- (NSString *)artPath {
446+ return self.album.artPath;
447+}
448+
449+#pragma mark - Model specific methods
450+
451+- (NSString *)artUrl {
452+ return self.album.artUrl;
453+}
454+
455+- (void)setTitle:(NSString *)_title {
456+ [self setPrimitiveValue:_title forKey:@"title"];
457+ [self setValue:[[_title dearticlizedString] uppercaseString] forKey:@"dearticlizedTitle"];
458+}
459+
460+- (NSString *)index {
461+ [self willAccessValueForKey:@"index"];
462+ NSString *_index = [[self.title dearticlizedIndex] uppercaseString];
463+ [self didAccessValueForKey:@"index"];
464+ return _index;
465+}
466+
467+- (void)setArtistId:(NSString *)_artistId {
468+ NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
469+ NSEntityDescription *entity = [NSEntityDescription entityForName:@"Artist" inManagedObjectContext:self.managedObjectContext];
470+ [fetchRequest setEntity:entity];
471+
472+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(artistId = %@)", _artistId];
473+ [fetchRequest setPredicate:predicate];
474+
475+ NSError *error;
476+ NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
477+ if (error || [results count] != 1) {
478+ abort();
479+ }
480+
481+ Artist *_artist = [results objectAtIndex:0];
482+ [self setPrimitiveValue:_artist forKey:@"artist"];
483+}
484+
485+- (NSString *)artistId {
486+ return self.artist.artistId;
487+}
488+
489+- (void)setAlbumId:(NSString *)_albumId {
490+ NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
491+ NSEntityDescription *entity = [NSEntityDescription entityForName:@"Album" inManagedObjectContext:self.managedObjectContext];
492+ [fetchRequest setEntity:entity];
493+
494+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(albumId = %@)", _albumId];
495+ [fetchRequest setPredicate:predicate];
496+
497+ NSError *error;
498+ NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
499+ if (error || [results count] != 1) {
500+ abort();
501+ }
502+
503+ Artist *_artist = [results objectAtIndex:0];
504+ [self setPrimitiveValue:_artist forKey:@"album"];
505+}
506+
507+- (NSString *)albumId {
508+ return self.album.albumId;
509+}
510+
511+- (void)setAlbumArtistId:(NSString *)_albumArtistId {
512+ NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
513+ NSEntityDescription *entity = [NSEntityDescription entityForName:@"Artist" inManagedObjectContext:self.managedObjectContext];
514+ [fetchRequest setEntity:entity];
515+
516+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(artistId = %@)", _albumArtistId];
517+ [fetchRequest setPredicate:predicate];
518+
519+ NSError *error;
520+ NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
521+ if (error || [results count] != 1) {
522+ abort();
523+ }
524+
525+ Artist *_artist = [results objectAtIndex:0];
526+ [self setPrimitiveValue:_artist forKey:@"albumArtist"];
527+}
528+
529+- (NSString *)albumArtistId {
530+ return self.albumArtist.artistId;
531+}
532+
533+/* This method exists for historical reasons currently, but should be deprecated soon. It formulates a path to send to the
534+ local auth server, and that auth server then disassembles the path to get the needed info out of it. I think it'd be much
535+ more efficient to just pass the song id currently.
536+ */
537+- (NSString *)idPath {
538+ NSArray *components = [NSArray arrayWithObjects:
539+ self.artist.name,
540+ self.album.title,
541+ self.songId,
542+ nil];
543+ return [NSString pathWithComponents:components];
544+}
545+
546+@end
547
548=== added file 'Music/Models/UOModel.h'
549--- Music/Models/UOModel.h 1970-01-01 00:00:00 +0000
550+++ Music/Models/UOModel.h 2013-01-24 17:06:42 +0000
551@@ -0,0 +1,25 @@
552+//
553+// UOModel.h
554+// U1Music
555+//
556+// Created by Paul Hummer on 11/20/12.
557+// Copyright (c) 2012 Canonical. All rights reserved.
558+//
559+
560+#import <CoreData/CoreData.h>
561+
562+@class RKEntityMapping;
563+
564+@interface UOModel : NSManagedObject
565++ (void)registerMapping;
566++ (RKEntityMapping *)objectMapping;
567++ (NSString *)keyPath;
568+
569+/* Not used for playlist */
570+@property (nonatomic, retain) NSString *artUrl;
571+
572+/* Used for fetching art */
573+@property (nonatomic, readonly) UIImage *art;
574+- (NSString *)artPath;
575+- (void)fetchArt:(void (^)(UIImage *))completionBlock;
576+@end
577
578=== added file 'Music/Models/UOModel.m'
579--- Music/Models/UOModel.m 1970-01-01 00:00:00 +0000
580+++ Music/Models/UOModel.m 2013-01-24 17:06:42 +0000
581@@ -0,0 +1,66 @@
582+//
583+// UOModel.m
584+// U1Music
585+//
586+// Created by Paul Hummer on 11/20/12.
587+// Copyright (c) 2012 Canonical. All rights reserved.
588+//
589+
590+#import "UOModel.h"
591+#import <RestKit/RestKit.h>
592+#import "UOAppDelegate.h"
593+#import "UOAuthManager.h"
594+
595+@implementation UOModel
596+
597+@dynamic artUrl;
598+
599++ (void)registerMapping {
600+ RKObjectManager *manager = [RKObjectManager sharedManager];
601+
602+ RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[self objectMapping]
603+ pathPattern:nil
604+ keyPath:[self keyPath]
605+ statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
606+ [manager addResponseDescriptor:responseDescriptor];
607+}
608+
609++ (RKEntityMapping *)objectMapping {
610+ RKObjectManager *manager = [RKObjectManager sharedManager];
611+
612+ RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"" inManagedObjectStore:manager.managedObjectStore];
613+ return mapping;
614+}
615+
616++ (NSString *)keyPath {
617+ return @"";
618+}
619+
620+- (UIImage *)art {
621+ NSString *path = [self artPath];
622+ if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
623+ return nil;
624+ }
625+ return [UIImage imageWithContentsOfFile:path];
626+}
627+
628+- (void)fetchArt:(void (^)(UIImage *))completionBlock {
629+ NSOperationQueue *queue = [[UOAppDelegate delegate] queue];
630+ NSString *path = [self artPath];
631+ NSURLRequest *echo = [UOAuthManager oauthRequestForPath:self.artUrl];
632+ NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:self.artUrl]];
633+ [request setHTTPMethod:@"GET"];
634+ [request addValue:[echo valueForHTTPHeaderField:@"Authorization"] forHTTPHeaderField:@"Authorization"];
635+
636+ [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
637+ UIImage *image = [UIImage imageWithData:data];
638+ [UIImageJPEGRepresentation(image, 1) writeToFile:path atomically:YES];
639+ completionBlock(image);
640+ }];
641+}
642+
643+- (NSString *)artPath {
644+ return nil;
645+}
646+
647+@end
648
649=== added file 'Music/Storyboard_iPhone.storyboard'
650--- Music/Storyboard_iPhone.storyboard 1970-01-01 00:00:00 +0000
651+++ Music/Storyboard_iPhone.storyboard 2013-01-24 17:06:42 +0000
652@@ -0,0 +1,892 @@
653+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
654+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="2844" systemVersion="12C60" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="pWo-yt-KiV">
655+ <dependencies>
656+ <deployment version="1280" identifier="iOS"/>
657+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="1930"/>
658+ </dependencies>
659+ <scenes>
660+ <!--Tab Bar Controller-->
661+ <scene sceneID="55E-Pc-3z2">
662+ <objects>
663+ <tabBarController definesPresentationContext="YES" id="pWo-yt-KiV" sceneMemberID="viewController">
664+ <nil key="simulatedBottomBarMetrics"/>
665+ <simulatedScreenMetrics key="simulatedDestinationMetrics"/>
666+ <tabBar key="tabBar" contentMode="scaleToFill" id="nJQ-wP-JMb">
667+ <rect key="frame" x="129" y="330" width="163" height="49"/>
668+ <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
669+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
670+ </tabBar>
671+ <connections>
672+ <segue destination="4Hc-hN-hrq" kind="relationship" relationship="viewControllers" id="klJ-qc-fFf"/>
673+ <segue destination="zZR-vq-p7Z" kind="relationship" relationship="viewControllers" id="bF5-F8-6QW"/>
674+ <segue destination="o0z-jC-7D9" kind="relationship" relationship="viewControllers" id="Ewf-uJ-ZyV"/>
675+ <segue destination="LSp-29-1PS" kind="relationship" relationship="viewControllers" id="57I-h2-A9b"/>
676+ <segue destination="1UW-CE-b1Y" kind="relationship" relationship="viewControllers" id="P7v-9L-Gv7"/>
677+ </connections>
678+ </tabBarController>
679+ <placeholder placeholderIdentifier="IBFirstResponder" id="geL-Sh-VEU" userLabel="First Responder" sceneMemberID="firstResponder"/>
680+ </objects>
681+ <point key="canvasLocation" x="-25" y="1265"/>
682+ </scene>
683+ <!--Artists View Controller - Artists-->
684+ <scene sceneID="dWt-kO-2fd">
685+ <objects>
686+ <tableViewController storyboardIdentifier="ArtistsViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="clT-Xi-JZg" customClass="ArtistsViewController" sceneMemberID="viewController">
687+ <tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="Ggv-lp-34h">
688+ <rect key="frame" x="0.0" y="64" width="320" height="367"/>
689+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
690+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
691+ <prototypes>
692+ <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Cell" textLabel="Wy4-11-qhh" detailTextLabel="PUO-bG-eLt" imageView="EvX-DO-a8s" style="IBUITableViewCellStyleSubtitle" id="TCk-Kb-c61" customClass="ArtistCell">
693+ <rect key="frame" x="0.0" y="22" width="320" height="44"/>
694+ <autoresizingMask key="autoresizingMask"/>
695+ <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
696+ <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
697+ <autoresizingMask key="autoresizingMask"/>
698+ <subviews>
699+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Wy4-11-qhh">
700+ <rect key="frame" x="53" y="2" width="38" height="22"/>
701+ <autoresizingMask key="autoresizingMask"/>
702+ <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
703+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
704+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
705+ </label>
706+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="PUO-bG-eLt">
707+ <rect key="frame" x="53" y="24" width="47" height="18"/>
708+ <autoresizingMask key="autoresizingMask"/>
709+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
710+ <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
711+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
712+ </label>
713+ <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="default-album-art-120.png" id="EvX-DO-a8s">
714+ <rect key="frame" x="0.0" y="0.0" width="43" height="43"/>
715+ <autoresizingMask key="autoresizingMask"/>
716+ </imageView>
717+ </subviews>
718+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
719+ </view>
720+ <connections>
721+ <segue destination="EDS-Dj-fjS" kind="push" id="m0f-2h-dTn"/>
722+ </connections>
723+ </tableViewCell>
724+ </prototypes>
725+ </tableView>
726+ <navigationItem key="navigationItem" title="Artists" id="2F6-a9-yaC">
727+ <barButtonItem key="rightBarButtonItem" title="Now Playing" id="Czg-eS-bhH">
728+ <connections>
729+ <segue destination="hRX-A4-gMJ" kind="modal" id="jOy-gZ-ehE"/>
730+ </connections>
731+ </barButtonItem>
732+ </navigationItem>
733+ <connections>
734+ <outlet property="nowPlayingButton" destination="Czg-eS-bhH" id="1d7-GI-ZFe"/>
735+ </connections>
736+ </tableViewController>
737+ <placeholder placeholderIdentifier="IBFirstResponder" id="0Gf-dy-qEu" userLabel="First Responder" sceneMemberID="firstResponder"/>
738+ </objects>
739+ <point key="canvasLocation" x="1047" y="-56"/>
740+ </scene>
741+ <!--Artist View Controller-->
742+ <scene sceneID="Y3A-G3-aF2">
743+ <objects>
744+ <viewController storyboardIdentifier="ArtistViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="EDS-Dj-fjS" customClass="ArtistViewController" sceneMemberID="viewController">
745+ <view key="view" contentMode="scaleToFill" id="Uhs-fF-mn0">
746+ <rect key="frame" x="0.0" y="64" width="320" height="367"/>
747+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
748+ <subviews>
749+ <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="iCb-IM-Bgp">
750+ <rect key="frame" x="0.0" y="120" width="320" height="247"/>
751+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
752+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
753+ <prototypes>
754+ <tableViewCell contentMode="scaleToFill" selectionStyle="blue" indentationWidth="10" reuseIdentifier="Cell" textLabel="G72-IX-jh9" detailTextLabel="VIc-Rn-YXm" imageView="F2l-py-JAO" style="IBUITableViewCellStyleSubtitle" id="Y5x-0G-rno" customClass="AlbumCell">
755+ <rect key="frame" x="0.0" y="22" width="320" height="44"/>
756+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
757+ <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
758+ <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
759+ <autoresizingMask key="autoresizingMask"/>
760+ <subviews>
761+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="G72-IX-jh9">
762+ <rect key="frame" x="53" y="2" width="38" height="22"/>
763+ <autoresizingMask key="autoresizingMask"/>
764+ <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
765+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
766+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
767+ </label>
768+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="VIc-Rn-YXm">
769+ <rect key="frame" x="53" y="24" width="47" height="18"/>
770+ <autoresizingMask key="autoresizingMask"/>
771+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
772+ <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
773+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
774+ </label>
775+ <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="default-album-art-120.png" id="F2l-py-JAO">
776+ <rect key="frame" x="0.0" y="0.0" width="43" height="43"/>
777+ <autoresizingMask key="autoresizingMask"/>
778+ </imageView>
779+ </subviews>
780+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
781+ </view>
782+ <connections>
783+ <segue destination="8Ya-S8-w02" kind="push" id="jMd-4K-zoU"/>
784+ </connections>
785+ </tableViewCell>
786+ </prototypes>
787+ </tableView>
788+ <imageView userInteractionEnabled="NO" contentMode="scaleToFill" id="7CD-jP-Egt">
789+ <rect key="frame" x="0.0" y="0.0" width="120" height="120"/>
790+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
791+ </imageView>
792+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Artist" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="00M-r3-Ezp">
793+ <rect key="frame" x="128" y="15" width="192" height="26"/>
794+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
795+ <fontDescription key="fontDescription" type="system" pointSize="18"/>
796+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
797+ <nil key="highlightedColor"/>
798+ <color key="shadowColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
799+ </label>
800+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="6 Albums" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="25K-Tf-YSQ">
801+ <rect key="frame" x="128" y="49" width="63" height="21"/>
802+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
803+ <fontDescription key="fontDescription" type="system" pointSize="15"/>
804+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
805+ <color key="highlightedColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
806+ </label>
807+ </subviews>
808+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
809+ </view>
810+ <navigationItem key="navigationItem" id="OM6-Kh-nGV">
811+ <barButtonItem key="rightBarButtonItem" title="Now Playing" id="tdG-O0-4fc">
812+ <connections>
813+ <segue destination="hRX-A4-gMJ" kind="modal" id="dlu-4W-myG"/>
814+ </connections>
815+ </barButtonItem>
816+ </navigationItem>
817+ <connections>
818+ <outlet property="albumArt" destination="7CD-jP-Egt" id="8PQ-jz-GxK"/>
819+ <outlet property="artistDescription" destination="25K-Tf-YSQ" id="1Zc-jA-3M0"/>
820+ <outlet property="artistName" destination="00M-r3-Ezp" id="Y9a-3a-Wat"/>
821+ <outlet property="nowPlayingButton" destination="tdG-O0-4fc" id="wcQ-K4-4i8"/>
822+ <outlet property="tableView" destination="iCb-IM-Bgp" id="vAl-VU-ljX"/>
823+ </connections>
824+ </viewController>
825+ <placeholder placeholderIdentifier="IBFirstResponder" id="Ihn-hD-5SH" userLabel="First Responder" sceneMemberID="firstResponder"/>
826+ </objects>
827+ <point key="canvasLocation" x="1515" y="-56"/>
828+ </scene>
829+ <!--Album View Controller-->
830+ <scene sceneID="24B-tK-YA0">
831+ <objects>
832+ <viewController storyboardIdentifier="AlbumViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="8Ya-S8-w02" customClass="AlbumViewController" sceneMemberID="viewController">
833+ <view key="view" contentMode="scaleToFill" id="D1T-MH-iJA">
834+ <rect key="frame" x="0.0" y="64" width="320" height="367"/>
835+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
836+ <subviews>
837+ <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="ffU-2e-oYZ">
838+ <rect key="frame" x="0.0" y="120" width="320" height="247"/>
839+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
840+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
841+ <prototypes>
842+ <tableViewCell contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="0Be-Uu-e1M" detailTextLabel="cgX-vu-iNg" imageView="xX5-x4-y65" style="IBUITableViewCellStyleSubtitle" id="vAU-q1-3Z9" customClass="SongCell">
843+ <rect key="frame" x="0.0" y="22" width="320" height="44"/>
844+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
845+ <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
846+ <rect key="frame" x="0.0" y="0.0" width="300" height="43"/>
847+ <autoresizingMask key="autoresizingMask"/>
848+ <subviews>
849+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="0Be-Uu-e1M">
850+ <rect key="frame" x="53" y="2" width="38" height="22"/>
851+ <autoresizingMask key="autoresizingMask"/>
852+ <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
853+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
854+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
855+ </label>
856+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="cgX-vu-iNg">
857+ <rect key="frame" x="53" y="24" width="47" height="18"/>
858+ <autoresizingMask key="autoresizingMask"/>
859+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
860+ <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
861+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
862+ </label>
863+ <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="default-album-art-120.png" id="xX5-x4-y65">
864+ <rect key="frame" x="0.0" y="0.0" width="43" height="43"/>
865+ <autoresizingMask key="autoresizingMask"/>
866+ </imageView>
867+ </subviews>
868+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
869+ </view>
870+ <connections>
871+ <segue destination="hRX-A4-gMJ" kind="modal" identifier="SongSelectSegue" id="kr6-1e-khR"/>
872+ </connections>
873+ </tableViewCell>
874+ </prototypes>
875+ </tableView>
876+ <imageView userInteractionEnabled="NO" contentMode="scaleToFill" id="1ZL-7v-l7S">
877+ <rect key="frame" x="0.0" y="0.0" width="120" height="120"/>
878+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
879+ </imageView>
880+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Album" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dwO-gw-nTE">
881+ <rect key="frame" x="128" y="15" width="192" height="26"/>
882+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
883+ <fontDescription key="fontDescription" type="system" pointSize="18"/>
884+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
885+ <nil key="highlightedColor"/>
886+ <color key="shadowColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
887+ </label>
888+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Artist" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="G01-4v-qdB">
889+ <rect key="frame" x="128" y="49" width="63" height="21"/>
890+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
891+ <fontDescription key="fontDescription" type="system" pointSize="15"/>
892+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
893+ <color key="highlightedColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
894+ </label>
895+ </subviews>
896+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
897+ </view>
898+ <navigationItem key="navigationItem" id="a61-1v-dxt">
899+ <barButtonItem key="rightBarButtonItem" title="Now Playing" id="wGH-uZ-TGk">
900+ <connections>
901+ <segue destination="hRX-A4-gMJ" kind="modal" identifier="NowPlayingSegue" id="YJd-qV-EXm"/>
902+ </connections>
903+ </barButtonItem>
904+ </navigationItem>
905+ <connections>
906+ <outlet property="albumArt" destination="1ZL-7v-l7S" id="2Xf-yw-js8"/>
907+ <outlet property="albumDescription" destination="G01-4v-qdB" id="Pog-jn-LaT"/>
908+ <outlet property="albumTitle" destination="dwO-gw-nTE" id="ofi-52-Vcd"/>
909+ <outlet property="nowPlayingButton" destination="wGH-uZ-TGk" id="29Y-w6-iea"/>
910+ <outlet property="tableView" destination="ffU-2e-oYZ" id="hvr-96-k3y"/>
911+ </connections>
912+ </viewController>
913+ <placeholder placeholderIdentifier="IBFirstResponder" id="UKU-A2-Ftv" userLabel="First Responder" sceneMemberID="firstResponder"/>
914+ </objects>
915+ <point key="canvasLocation" x="1997" y="-56"/>
916+ </scene>
917+ <!--Player View Controller-->
918+ <scene sceneID="x1s-7w-DiN">
919+ <objects>
920+ <viewController storyboardIdentifier="PlayerViewController" hidesBottomBarWhenPushed="YES" useStoryboardIdentifierAsRestorationIdentifier="YES" id="hRX-A4-gMJ" customClass="PlayerViewController" sceneMemberID="viewController">
921+ <view key="view" contentMode="scaleToFill" id="hdM-iJ-YAa">
922+ <rect key="frame" x="0.0" y="20" width="320" height="460"/>
923+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
924+ <subviews>
925+ <toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" barStyle="blackTranslucent" id="uGB-Cu-Aav">
926+ <rect key="frame" x="0.0" y="416" width="320" height="44"/>
927+ <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
928+ <items>
929+ <barButtonItem style="plain" systemItem="flexibleSpace" id="cZy-dZ-TvC"/>
930+ <barButtonItem style="plain" systemItem="rewind" id="1xR-vh-5t6">
931+ <connections>
932+ <action selector="previous:" destination="hRX-A4-gMJ" id="aVK-zi-YOW"/>
933+ </connections>
934+ </barButtonItem>
935+ <barButtonItem width="42" style="plain" systemItem="fixedSpace" id="qpi-Go-lLw"/>
936+ <barButtonItem style="plain" systemItem="play" id="1LC-YT-al7">
937+ <connections>
938+ <action selector="play:" destination="hRX-A4-gMJ" id="KUH-IZ-uoJ"/>
939+ </connections>
940+ </barButtonItem>
941+ <barButtonItem style="plain" systemItem="pause" id="DQV-3Q-HbM">
942+ <connections>
943+ <action selector="pause:" destination="hRX-A4-gMJ" id="2FO-Lh-W8V"/>
944+ </connections>
945+ </barButtonItem>
946+ <barButtonItem width="42" style="plain" systemItem="fixedSpace" id="5vO-YI-vrC"/>
947+ <barButtonItem style="plain" systemItem="fastForward" id="QEO-UP-PKx">
948+ <connections>
949+ <action selector="next:" destination="hRX-A4-gMJ" id="ZmL-lU-0ds"/>
950+ </connections>
951+ </barButtonItem>
952+ <barButtonItem style="plain" systemItem="flexibleSpace" id="MBV-c6-BMY"/>
953+ </items>
954+ </toolbar>
955+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Yam-lV-Vc9">
956+ <rect key="frame" x="0.0" y="58" width="320" height="321"/>
957+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
958+ <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
959+ <state key="normal" backgroundImage="default-album-art-640.png">
960+ <color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
961+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
962+ </state>
963+ <state key="disabled" backgroundImage="default-album-art-640.png"/>
964+ <state key="selected" backgroundImage="default-album-art-640.png"/>
965+ <state key="highlighted" backgroundImage="default-album-art-640.png">
966+ <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
967+ </state>
968+ </button>
969+ <navigationBar contentMode="scaleToFill" barStyle="blackTranslucent" id="oeU-qV-gKe">
970+ <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
971+ <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
972+ <items>
973+ <navigationItem id="nkk-jO-edR">
974+ <nil key="title"/>
975+ <view key="titleView" contentMode="scaleToFill" restorationIdentifier="" id="Pu1-tL-kcl" customClass="PlayerHeaderView">
976+ <rect key="frame" x="96" y="6" width="128" height="33"/>
977+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
978+ <subviews>
979+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Artist" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="h2R-82-j69">
980+ <rect key="frame" x="0.0" y="-6" width="128" height="21"/>
981+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
982+ <fontDescription key="fontDescription" type="boldSystem" pointSize="12"/>
983+ <color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
984+ <nil key="highlightedColor"/>
985+ </label>
986+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Title" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="eua-we-ECS">
987+ <rect key="frame" x="0.0" y="12" width="128" height="21"/>
988+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
989+ <fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
990+ <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
991+ <nil key="highlightedColor"/>
992+ </label>
993+ </subviews>
994+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
995+ </view>
996+ <barButtonItem key="rightBarButtonItem" title="Hide" id="Uea-fD-AuL">
997+ <connections>
998+ <action selector="hide:" destination="hRX-A4-gMJ" id="YjZ-v5-qzj"/>
999+ </connections>
1000+ </barButtonItem>
1001+ </navigationItem>
1002+ </items>
1003+ </navigationBar>
1004+ </subviews>
1005+ <color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/>
1006+ </view>
1007+ <nil key="simulatedBottomBarMetrics"/>
1008+ <simulatedScreenMetrics key="simulatedDestinationMetrics"/>
1009+ <connections>
1010+ <outlet property="albumart" destination="Yam-lV-Vc9" id="5e5-A4-rMc"/>
1011+ <outlet property="artistLabel" destination="h2R-82-j69" id="Juf-cx-6ta"/>
1012+ <outlet property="controlBar" destination="uGB-Cu-Aav" id="Wgb-Ct-TjW"/>
1013+ <outlet property="nextButton" destination="QEO-UP-PKx" id="ZgA-sN-VU1"/>
1014+ <outlet property="pauseButton" destination="DQV-3Q-HbM" id="nKw-2H-EHB"/>
1015+ <outlet property="playButton" destination="1LC-YT-al7" id="2PE-Uy-AbM"/>
1016+ <outlet property="previousButton" destination="1xR-vh-5t6" id="ekr-RG-Qqb"/>
1017+ <outlet property="titleLabel" destination="eua-we-ECS" id="XMu-px-khb"/>
1018+ </connections>
1019+ </viewController>
1020+ <placeholder placeholderIdentifier="IBFirstResponder" id="ase-Pp-0S0" userLabel="First Responder" sceneMemberID="firstResponder"/>
1021+ </objects>
1022+ <point key="canvasLocation" x="1997" y="1265"/>
1023+ </scene>
1024+ <!--Navigation Controller - Artists-->
1025+ <scene sceneID="wAh-VA-Bcp">
1026+ <objects>
1027+ <navigationController definesPresentationContext="YES" id="4Hc-hN-hrq" sceneMemberID="viewController">
1028+ <tabBarItem key="tabBarItem" title="Artists" image="artists.png" id="UKS-lS-c29"/>
1029+ <simulatedNavigationBarMetrics key="simulatedTopBarMetrics" barStyle="blackOpaque" prompted="NO"/>
1030+ <navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="blackOpaque" id="bnN-Eu-OdY">
1031+ <rect key="frame" x="0.0" y="0.0" width="0.0" height="44"/>
1032+ <autoresizingMask key="autoresizingMask"/>
1033+ </navigationBar>
1034+ <connections>
1035+ <segue destination="clT-Xi-JZg" kind="relationship" relationship="rootViewController" id="gtU-kt-ZW0"/>
1036+ </connections>
1037+ </navigationController>
1038+ <placeholder placeholderIdentifier="IBFirstResponder" id="dBo-wL-pzl" userLabel="First Responder" sceneMemberID="firstResponder"/>
1039+ </objects>
1040+ <point key="canvasLocation" x="513" y="-56"/>
1041+ </scene>
1042+ <!--Albums View Controller - Albums-->
1043+ <scene sceneID="ZG3-yC-c5Q">
1044+ <objects>
1045+ <tableViewController storyboardIdentifier="AlbumsViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="xcy-KE-FMg" customClass="AlbumsViewController" sceneMemberID="viewController">
1046+ <tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="Gt1-6s-YaG">
1047+ <rect key="frame" x="0.0" y="64" width="320" height="367"/>
1048+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1049+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
1050+ <prototypes>
1051+ <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Cell" textLabel="lHq-bS-Zm9" detailTextLabel="03B-YT-E7s" imageView="apM-jL-xHe" style="IBUITableViewCellStyleSubtitle" id="5s2-Qn-BOB" customClass="AlbumCell">
1052+ <rect key="frame" x="0.0" y="22" width="320" height="44"/>
1053+ <autoresizingMask key="autoresizingMask"/>
1054+ <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
1055+ <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
1056+ <autoresizingMask key="autoresizingMask"/>
1057+ <subviews>
1058+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="lHq-bS-Zm9">
1059+ <rect key="frame" x="53" y="2" width="38" height="22"/>
1060+ <autoresizingMask key="autoresizingMask"/>
1061+ <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
1062+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
1063+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
1064+ </label>
1065+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="03B-YT-E7s">
1066+ <rect key="frame" x="53" y="24" width="47" height="18"/>
1067+ <autoresizingMask key="autoresizingMask"/>
1068+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
1069+ <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
1070+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
1071+ </label>
1072+ <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="default-album-art-120.png" id="apM-jL-xHe">
1073+ <rect key="frame" x="0.0" y="0.0" width="43" height="43"/>
1074+ <autoresizingMask key="autoresizingMask"/>
1075+ </imageView>
1076+ </subviews>
1077+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
1078+ </view>
1079+ <connections>
1080+ <segue destination="8Ya-S8-w02" kind="push" id="vss-nE-Iks"/>
1081+ </connections>
1082+ </tableViewCell>
1083+ </prototypes>
1084+ </tableView>
1085+ <navigationItem key="navigationItem" title="Albums" id="hkW-z1-Fu2">
1086+ <barButtonItem key="rightBarButtonItem" title="Now Playing" id="wdZ-Iw-xrr">
1087+ <connections>
1088+ <segue destination="hRX-A4-gMJ" kind="modal" id="VVE-Ue-HgA"/>
1089+ </connections>
1090+ </barButtonItem>
1091+ </navigationItem>
1092+ <connections>
1093+ <outlet property="nowPlayingButton" destination="wdZ-Iw-xrr" id="QrW-J1-lC8"/>
1094+ </connections>
1095+ </tableViewController>
1096+ <placeholder placeholderIdentifier="IBFirstResponder" id="HV5-Sk-U9p" userLabel="First Responder" sceneMemberID="firstResponder"/>
1097+ </objects>
1098+ <point key="canvasLocation" x="1047" y="603"/>
1099+ </scene>
1100+ <!--Songs View Controller - Songs-->
1101+ <scene sceneID="c5e-Kz-pSi">
1102+ <objects>
1103+ <tableViewController storyboardIdentifier="SongsViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="GZ4-Ef-jEy" customClass="SongsViewController" sceneMemberID="viewController">
1104+ <tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="oMr-dT-itP">
1105+ <rect key="frame" x="0.0" y="64" width="320" height="367"/>
1106+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1107+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
1108+ <prototypes>
1109+ <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Cell" textLabel="OwY-7W-CUV" detailTextLabel="ORO-PT-T6b" imageView="Ynd-vW-pQI" style="IBUITableViewCellStyleSubtitle" id="jpK-Yt-5Y9" customClass="SongCell">
1110+ <rect key="frame" x="0.0" y="22" width="320" height="44"/>
1111+ <autoresizingMask key="autoresizingMask"/>
1112+ <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
1113+ <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
1114+ <autoresizingMask key="autoresizingMask"/>
1115+ <subviews>
1116+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="OwY-7W-CUV">
1117+ <rect key="frame" x="53" y="2" width="38" height="22"/>
1118+ <autoresizingMask key="autoresizingMask"/>
1119+ <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
1120+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
1121+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
1122+ </label>
1123+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ORO-PT-T6b">
1124+ <rect key="frame" x="53" y="24" width="47" height="18"/>
1125+ <autoresizingMask key="autoresizingMask"/>
1126+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
1127+ <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
1128+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
1129+ </label>
1130+ <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="default-album-art-120.png" id="Ynd-vW-pQI">
1131+ <rect key="frame" x="0.0" y="0.0" width="43" height="43"/>
1132+ <autoresizingMask key="autoresizingMask"/>
1133+ </imageView>
1134+ </subviews>
1135+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
1136+ </view>
1137+ <connections>
1138+ <segue destination="hRX-A4-gMJ" kind="modal" id="cRF-Ex-krh"/>
1139+ </connections>
1140+ </tableViewCell>
1141+ </prototypes>
1142+ </tableView>
1143+ <navigationItem key="navigationItem" title="Songs" id="xSn-ff-tyF">
1144+ <barButtonItem key="rightBarButtonItem" title="Now Playing" id="VT1-ho-rrY">
1145+ <connections>
1146+ <segue destination="hRX-A4-gMJ" kind="modal" id="e8X-Xp-0ra"/>
1147+ </connections>
1148+ </barButtonItem>
1149+ </navigationItem>
1150+ <connections>
1151+ <outlet property="nowPlayingButton" destination="VT1-ho-rrY" id="Lvj-nv-Qod"/>
1152+ </connections>
1153+ </tableViewController>
1154+ <placeholder placeholderIdentifier="IBFirstResponder" id="Ryd-Wn-8Fr" userLabel="First Responder" sceneMemberID="firstResponder"/>
1155+ </objects>
1156+ <point key="canvasLocation" x="1047" y="1265"/>
1157+ </scene>
1158+ <!--Playlists View Controller - Playlists-->
1159+ <scene sceneID="lYB-MX-vJE">
1160+ <objects>
1161+ <tableViewController storyboardIdentifier="PlaylistsViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="3pv-m5-N7g" customClass="PlaylistsViewController" sceneMemberID="viewController">
1162+ <tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="5h4-j3-j1b">
1163+ <rect key="frame" x="0.0" y="64" width="320" height="367"/>
1164+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1165+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
1166+ <prototypes>
1167+ <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Cell" textLabel="JsP-i0-8FD" detailTextLabel="tKX-ZD-fxt" style="IBUITableViewCellStyleSubtitle" id="B41-VB-iYU" customClass="PlaylistCell">
1168+ <rect key="frame" x="0.0" y="22" width="320" height="44"/>
1169+ <autoresizingMask key="autoresizingMask"/>
1170+ <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
1171+ <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
1172+ <autoresizingMask key="autoresizingMask"/>
1173+ <subviews>
1174+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="JsP-i0-8FD">
1175+ <rect key="frame" x="10" y="2" width="38" height="22"/>
1176+ <autoresizingMask key="autoresizingMask"/>
1177+ <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
1178+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
1179+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
1180+ </label>
1181+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="tKX-ZD-fxt">
1182+ <rect key="frame" x="10" y="24" width="47" height="18"/>
1183+ <autoresizingMask key="autoresizingMask"/>
1184+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
1185+ <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
1186+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
1187+ </label>
1188+ </subviews>
1189+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
1190+ </view>
1191+ </tableViewCell>
1192+ </prototypes>
1193+ </tableView>
1194+ <navigationItem key="navigationItem" title="Playlists" id="vZb-BX-Uz8">
1195+ <barButtonItem key="rightBarButtonItem" title="Now Playing" id="vcz-Uz-Uw5">
1196+ <connections>
1197+ <segue destination="hRX-A4-gMJ" kind="modal" id="OOo-AD-VSC"/>
1198+ </connections>
1199+ </barButtonItem>
1200+ </navigationItem>
1201+ <connections>
1202+ <outlet property="nowPlayingButton" destination="vcz-Uz-Uw5" id="sRY-Tm-IjP"/>
1203+ </connections>
1204+ </tableViewController>
1205+ <placeholder placeholderIdentifier="IBFirstResponder" id="Lsu-wW-VCH" userLabel="First Responder" sceneMemberID="firstResponder"/>
1206+ </objects>
1207+ <point key="canvasLocation" x="1047" y="1944"/>
1208+ </scene>
1209+ <!--Navigation Controller - Playlists-->
1210+ <scene sceneID="LmT-Va-mHV">
1211+ <objects>
1212+ <navigationController definesPresentationContext="YES" id="LSp-29-1PS" sceneMemberID="viewController">
1213+ <tabBarItem key="tabBarItem" title="Playlists" image="playlists.png" id="MgK-Bt-XIX"/>
1214+ <simulatedNavigationBarMetrics key="simulatedTopBarMetrics" barStyle="blackOpaque" prompted="NO"/>
1215+ <navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="blackOpaque" id="chg-Il-gK7">
1216+ <rect key="frame" x="0.0" y="0.0" width="0.0" height="44"/>
1217+ <autoresizingMask key="autoresizingMask"/>
1218+ </navigationBar>
1219+ <connections>
1220+ <segue destination="3pv-m5-N7g" kind="relationship" relationship="rootViewController" id="0Z0-Wn-amn"/>
1221+ </connections>
1222+ </navigationController>
1223+ <placeholder placeholderIdentifier="IBFirstResponder" id="Ho5-GE-ejp" userLabel="First Responder" sceneMemberID="firstResponder"/>
1224+ </objects>
1225+ <point key="canvasLocation" x="513" y="1944"/>
1226+ </scene>
1227+ <!--Settings View Controller - Settings-->
1228+ <scene sceneID="zr0-a1-yay">
1229+ <objects>
1230+ <viewController storyboardIdentifier="SettingsViewController" title="Settings" useStoryboardIdentifierAsRestorationIdentifier="YES" id="1UW-CE-b1Y" customClass="SettingsViewController" sceneMemberID="viewController">
1231+ <view key="view" contentMode="scaleToFill" id="PeO-DV-fCR">
1232+ <rect key="frame" x="0.0" y="20" width="320" height="411"/>
1233+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
1234+ <subviews>
1235+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="2qY-Nn-ktN">
1236+ <rect key="frame" x="64" y="68" width="193" height="44"/>
1237+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
1238+ <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
1239+ <state key="normal" title="Sign out of Ubuntu One">
1240+ <color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
1241+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
1242+ </state>
1243+ <state key="highlighted">
1244+ <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
1245+ </state>
1246+ <connections>
1247+ <action selector="deleteCredentials:" destination="1UW-CE-b1Y" eventType="touchUpInside" id="dMs-la-BSc"/>
1248+ </connections>
1249+ </button>
1250+ <navigationBar contentMode="scaleToFill" barStyle="blackOpaque" id="fi9-Gu-y7h">
1251+ <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
1252+ <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
1253+ <items>
1254+ <navigationItem title="Settings" id="1OL-cf-ieJ">
1255+ <barButtonItem key="rightBarButtonItem" title="About" id="5t4-pZ-HZ3">
1256+ <connections>
1257+ <segue destination="XwX-yD-gmZ" kind="modal" identifier="AboutSegue" id="q67-cb-9ch"/>
1258+ </connections>
1259+ </barButtonItem>
1260+ </navigationItem>
1261+ </items>
1262+ </navigationBar>
1263+ </subviews>
1264+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
1265+ </view>
1266+ <tabBarItem key="tabBarItem" title="Settings" image="settings.png" id="PuB-gs-lxg"/>
1267+ <connections>
1268+ <segue destination="iRB-yQ-1TX" kind="modal" identifier="AuthenticationSegue" id="HlT-h9-MTb"/>
1269+ </connections>
1270+ </viewController>
1271+ <placeholder placeholderIdentifier="IBFirstResponder" id="nwB-mO-Qdu" userLabel="First Responder" sceneMemberID="firstResponder"/>
1272+ </objects>
1273+ <point key="canvasLocation" x="513" y="2638"/>
1274+ </scene>
1275+ <!--Settings Authentication View Controller - Log In-->
1276+ <scene sceneID="bJR-Ac-mSb">
1277+ <objects>
1278+ <viewController storyboardIdentifier="SettingsAuthenticationViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="iRB-yQ-1TX" customClass="SettingsAuthenticationViewController" sceneMemberID="viewController">
1279+ <view key="view" contentMode="scaleToFill" id="apk-8c-wHl">
1280+ <rect key="frame" x="0.0" y="64" width="320" height="504"/>
1281+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
1282+ <subviews>
1283+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Username" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ZEC-2H-d7Z">
1284+ <rect key="frame" x="121" y="20" width="79" height="21"/>
1285+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
1286+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
1287+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
1288+ <nil key="highlightedColor"/>
1289+ </label>
1290+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Password" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="UfC-eE-bcj">
1291+ <rect key="frame" x="123" y="87" width="75" height="21"/>
1292+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
1293+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
1294+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
1295+ <nil key="highlightedColor"/>
1296+ </label>
1297+ <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" minimumFontSize="17" id="waC-mM-MFm">
1298+ <rect key="frame" x="20" y="116" width="280" height="30"/>
1299+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
1300+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
1301+ <textInputTraits key="textInputTraits" returnKeyType="done" secureTextEntry="YES"/>
1302+ </textField>
1303+ <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" minimumFontSize="17" id="9eo-83-zSr">
1304+ <rect key="frame" x="20" y="49" width="280" height="30"/>
1305+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
1306+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
1307+ <textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="emailAddress" returnKeyType="next"/>
1308+ </textField>
1309+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="du9-HJ-oTk">
1310+ <rect key="frame" x="126" y="154" width="69" height="44"/>
1311+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
1312+ <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
1313+ <state key="normal" title="Log In">
1314+ <color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
1315+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
1316+ </state>
1317+ <state key="highlighted">
1318+ <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
1319+ </state>
1320+ <connections>
1321+ <action selector="authenticate:" destination="iRB-yQ-1TX" eventType="touchUpInside" id="Sfs-XA-OBI"/>
1322+ </connections>
1323+ </button>
1324+ <view hidden="YES" alpha="0.70000000000000007" contentMode="scaleToFill" id="KV8-kp-weQ">
1325+ <rect key="frame" x="0.0" y="0.0" width="320" height="504"/>
1326+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
1327+ <subviews>
1328+ <activityIndicatorView contentMode="scaleToFill" animating="YES" style="whiteLarge" id="ixc-ts-ry3">
1329+ <rect key="frame" x="142" y="233" width="37" height="37"/>
1330+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
1331+ </activityIndicatorView>
1332+ </subviews>
1333+ <color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
1334+ </view>
1335+ </subviews>
1336+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
1337+ </view>
1338+ <navigationItem key="navigationItem" title="Log In" id="lZr-l9-Rd0"/>
1339+ <simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
1340+ <connections>
1341+ <outlet property="passwordField" destination="waC-mM-MFm" id="J4I-c0-hPj"/>
1342+ <outlet property="shade" destination="KV8-kp-weQ" id="HgB-zm-dOv"/>
1343+ <outlet property="spinner" destination="ixc-ts-ry3" id="Zjn-Dn-l1x"/>
1344+ <outlet property="usernameField" destination="9eo-83-zSr" id="k5m-z6-dNf"/>
1345+ </connections>
1346+ </viewController>
1347+ <placeholder placeholderIdentifier="IBFirstResponder" id="Oct-dr-Jot" userLabel="First Responder" sceneMemberID="firstResponder"/>
1348+ </objects>
1349+ <point key="canvasLocation" x="1047" y="2638"/>
1350+ </scene>
1351+ <!--Settings About View Controller - Ubuntu One Music-->
1352+ <scene sceneID="DCB-cK-aCY">
1353+ <objects>
1354+ <viewController storyboardIdentifier="SettingsAboutViewController" title="Ubuntu One Music" useStoryboardIdentifierAsRestorationIdentifier="YES" id="XwX-yD-gmZ" customClass="SettingsAboutViewController" sceneMemberID="viewController">
1355+ <view key="view" contentMode="scaleToFill" id="ezs-Zb-PEL">
1356+ <rect key="frame" x="0.0" y="64" width="320" height="504"/>
1357+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
1358+ <subviews>
1359+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="4sj-Hk-nsd">
1360+ <rect key="frame" x="130" y="248" width="62" height="44"/>
1361+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
1362+ <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
1363+ <state key="normal" title="Done">
1364+ <color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
1365+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
1366+ </state>
1367+ <state key="highlighted">
1368+ <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
1369+ </state>
1370+ <connections>
1371+ <action selector="close:" destination="XwX-yD-gmZ" eventType="touchUpInside" id="GOR-Ec-Jnn"/>
1372+ </connections>
1373+ </button>
1374+ </subviews>
1375+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
1376+ </view>
1377+ <navigationItem key="navigationItem" title="Ubuntu One Music" id="mZO-nv-iEf">
1378+ <barButtonItem key="rightBarButtonItem" title="Done" id="sDu-OP-vCU">
1379+ <connections>
1380+ <action selector="close:" destination="XwX-yD-gmZ" id="3kP-cf-7xQ"/>
1381+ </connections>
1382+ </barButtonItem>
1383+ </navigationItem>
1384+ <simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
1385+ </viewController>
1386+ <placeholder placeholderIdentifier="IBFirstResponder" id="Gk9-4p-GpB" userLabel="First Responder" sceneMemberID="firstResponder"/>
1387+ </objects>
1388+ <point key="canvasLocation" x="1047" y="3324"/>
1389+ </scene>
1390+ <!--Navigation Controller - Songs-->
1391+ <scene sceneID="H5C-K6-iJr">
1392+ <objects>
1393+ <navigationController definesPresentationContext="YES" id="o0z-jC-7D9" sceneMemberID="viewController">
1394+ <tabBarItem key="tabBarItem" title="Songs" image="songs.png" id="qgg-Ad-elr"/>
1395+ <simulatedNavigationBarMetrics key="simulatedTopBarMetrics" barStyle="blackOpaque" prompted="NO"/>
1396+ <navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="blackOpaque" id="8kw-rr-pbe">
1397+ <rect key="frame" x="0.0" y="0.0" width="0.0" height="44"/>
1398+ <autoresizingMask key="autoresizingMask"/>
1399+ </navigationBar>
1400+ <connections>
1401+ <segue destination="GZ4-Ef-jEy" kind="relationship" relationship="rootViewController" id="ic2-F6-xIN"/>
1402+ </connections>
1403+ </navigationController>
1404+ <placeholder placeholderIdentifier="IBFirstResponder" id="M42-t1-44p" userLabel="First Responder" sceneMemberID="firstResponder"/>
1405+ </objects>
1406+ <point key="canvasLocation" x="513" y="1265"/>
1407+ </scene>
1408+ <!--Navigation Controller - Albums-->
1409+ <scene sceneID="6cl-I1-xDI">
1410+ <objects>
1411+ <navigationController definesPresentationContext="YES" id="zZR-vq-p7Z" sceneMemberID="viewController">
1412+ <tabBarItem key="tabBarItem" title="Albums" image="albums.png" id="lUy-zw-8Vo"/>
1413+ <simulatedNavigationBarMetrics key="simulatedTopBarMetrics" barStyle="blackOpaque" prompted="NO"/>
1414+ <navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="blackOpaque" id="PP9-8N-9lk">
1415+ <rect key="frame" x="0.0" y="0.0" width="0.0" height="44"/>
1416+ <autoresizingMask key="autoresizingMask"/>
1417+ </navigationBar>
1418+ <connections>
1419+ <segue destination="xcy-KE-FMg" kind="relationship" relationship="rootViewController" id="qDG-ce-1Yz"/>
1420+ </connections>
1421+ </navigationController>
1422+ <placeholder placeholderIdentifier="IBFirstResponder" id="B8o-9H-15l" userLabel="First Responder" sceneMemberID="firstResponder"/>
1423+ </objects>
1424+ <point key="canvasLocation" x="513" y="603"/>
1425+ </scene>
1426+ </scenes>
1427+ <resources>
1428+ <image name="albums.png" width="30" height="30"/>
1429+ <image name="artists.png" width="30" height="30"/>
1430+ <image name="default-album-art-120.png" width="60" height="60"/>
1431+ <image name="default-album-art-640.png" width="320" height="320"/>
1432+ <image name="playlists.png" width="30" height="30"/>
1433+ <image name="settings.png" width="30" height="30"/>
1434+ <image name="songs.png" width="30" height="30"/>
1435+ </resources>
1436+ <classes>
1437+ <class className="AlbumCell" superclassName="UITableViewCell">
1438+ <source key="sourceIdentifier" type="project" relativePath="./Classes/AlbumCell.h"/>
1439+ </class>
1440+ <class className="AlbumViewController" superclassName="SubsonicTableViewController">
1441+ <source key="sourceIdentifier" type="project" relativePath="./Classes/AlbumViewController.h"/>
1442+ <relationships>
1443+ <relationship kind="outlet" name="albumArt" candidateClass="UIImageView"/>
1444+ <relationship kind="outlet" name="albumDescription" candidateClass="UILabel"/>
1445+ <relationship kind="outlet" name="albumTitle" candidateClass="UILabel"/>
1446+ <relationship kind="outlet" name="tableView" candidateClass="UITableView"/>
1447+ </relationships>
1448+ </class>
1449+ <class className="AlbumsViewController" superclassName="UOIndexedViewController">
1450+ <source key="sourceIdentifier" type="project" relativePath="./Classes/AlbumsViewController.h"/>
1451+ </class>
1452+ <class className="ArtistCell" superclassName="UITableViewCell">
1453+ <source key="sourceIdentifier" type="project" relativePath="./Classes/ArtistCell.h"/>
1454+ </class>
1455+ <class className="ArtistViewController" superclassName="UIViewController">
1456+ <source key="sourceIdentifier" type="project" relativePath="./Classes/ArtistViewController.h"/>
1457+ <relationships>
1458+ <relationship kind="outlet" name="albumArt" candidateClass="UIImageView"/>
1459+ <relationship kind="outlet" name="artistDescription" candidateClass="UILabel"/>
1460+ <relationship kind="outlet" name="artistName" candidateClass="UILabel"/>
1461+ <relationship kind="outlet" name="nowPlayingButton" candidateClass="UIBarButtonItem"/>
1462+ <relationship kind="outlet" name="tableView" candidateClass="UITableView"/>
1463+ </relationships>
1464+ </class>
1465+ <class className="ArtistsViewController" superclassName="UOIndexedViewController">
1466+ <source key="sourceIdentifier" type="project" relativePath="./Classes/ArtistsViewController.h"/>
1467+ </class>
1468+ <class className="PlayerHeaderView" superclassName="UIView">
1469+ <source key="sourceIdentifier" type="project" relativePath="./Classes/PlayerHeaderView.h"/>
1470+ <relationships>
1471+ <relationship kind="outlet" name="album" candidateClass="UILabel"/>
1472+ <relationship kind="outlet" name="artist" candidateClass="UILabel"/>
1473+ <relationship kind="outlet" name="title" candidateClass="UILabel"/>
1474+ </relationships>
1475+ </class>
1476+ <class className="PlayerViewController" superclassName="UIViewController">
1477+ <source key="sourceIdentifier" type="project" relativePath="./Classes/PlayerViewController.h"/>
1478+ <relationships>
1479+ <relationship kind="action" name="hide:"/>
1480+ <relationship kind="action" name="next:"/>
1481+ <relationship kind="action" name="pause:"/>
1482+ <relationship kind="action" name="play:"/>
1483+ <relationship kind="action" name="previous:"/>
1484+ <relationship kind="outlet" name="albumart" candidateClass="UIButton"/>
1485+ <relationship kind="outlet" name="artistLabel" candidateClass="UILabel"/>
1486+ <relationship kind="outlet" name="controlBar" candidateClass="UIToolbar"/>
1487+ <relationship kind="outlet" name="nextButton" candidateClass="UIBarButtonItem"/>
1488+ <relationship kind="outlet" name="pauseButton" candidateClass="UIBarButtonItem"/>
1489+ <relationship kind="outlet" name="playButton" candidateClass="UIBarButtonItem"/>
1490+ <relationship kind="outlet" name="previousButton" candidateClass="UIBarButtonItem"/>
1491+ <relationship kind="outlet" name="titleLabel" candidateClass="UILabel"/>
1492+ </relationships>
1493+ </class>
1494+ <class className="PlaylistCell" superclassName="UITableViewCell">
1495+ <source key="sourceIdentifier" type="project" relativePath="./Classes/PlaylistCell.h"/>
1496+ </class>
1497+ <class className="PlaylistsViewController" superclassName="UOIndexedViewController">
1498+ <source key="sourceIdentifier" type="project" relativePath="./Classes/PlaylistsViewController.h"/>
1499+ </class>
1500+ <class className="SettingsAboutViewController" superclassName="UIViewController">
1501+ <source key="sourceIdentifier" type="project" relativePath="./Classes/SettingsAboutViewController.h"/>
1502+ <relationships>
1503+ <relationship kind="action" name="close:"/>
1504+ </relationships>
1505+ </class>
1506+ <class className="SettingsAuthenticationViewController" superclassName="UIViewController">
1507+ <source key="sourceIdentifier" type="project" relativePath="./Classes/SettingsAuthenticationViewController.h"/>
1508+ <relationships>
1509+ <relationship kind="action" name="authenticate:"/>
1510+ <relationship kind="outlet" name="passwordField" candidateClass="UITextField"/>
1511+ <relationship kind="outlet" name="shade" candidateClass="UIView"/>
1512+ <relationship kind="outlet" name="spinner" candidateClass="UIActivityIndicatorView"/>
1513+ <relationship kind="outlet" name="usernameField" candidateClass="UITextField"/>
1514+ </relationships>
1515+ </class>
1516+ <class className="SettingsViewController" superclassName="UIViewController">
1517+ <source key="sourceIdentifier" type="project" relativePath="./Classes/SettingsViewController.h"/>
1518+ <relationships>
1519+ <relationship kind="action" name="deleteCredentials:"/>
1520+ </relationships>
1521+ </class>
1522+ <class className="SongCell" superclassName="UITableViewCell">
1523+ <source key="sourceIdentifier" type="project" relativePath="./Classes/SongCell.h"/>
1524+ </class>
1525+ <class className="SongsViewController" superclassName="UOIndexedViewController">
1526+ <source key="sourceIdentifier" type="project" relativePath="./Classes/SongsViewController.h"/>
1527+ </class>
1528+ <class className="UOIndexedViewController" superclassName="UITableViewController">
1529+ <source key="sourceIdentifier" type="project" relativePath="./Classes/UOIndexedViewController.h"/>
1530+ <relationships>
1531+ <relationship kind="outlet" name="nowPlayingButton" candidateClass="UIBarButtonItem"/>
1532+ </relationships>
1533+ </class>
1534+ </classes>
1535+ <simulatedMetricsContainer key="defaultSimulatedMetrics">
1536+ <simulatedStatusBarMetrics key="statusBar"/>
1537+ <simulatedOrientationMetrics key="orientation"/>
1538+ <simulatedScreenMetrics key="destination" type="retina4"/>
1539+ </simulatedMetricsContainer>
1540+ <inferredMetricsTieBreakers>
1541+ <segue reference="VVE-Ue-HgA"/>
1542+ <segue reference="vss-nE-Iks"/>
1543+ </inferredMetricsTieBreakers>
1544+</document>
1545\ No newline at end of file
1546
1547=== added file 'Music/UOAppDelegate.h'
1548--- Music/UOAppDelegate.h 1970-01-01 00:00:00 +0000
1549+++ Music/UOAppDelegate.h 2013-01-24 17:06:42 +0000
1550@@ -0,0 +1,28 @@
1551+//
1552+// UOAppDelegate.h
1553+// U1Music
1554+//
1555+// Created by Paul Hummer on 1/21/13.
1556+// Copyright (c) 2013 Canonical. All rights reserved.
1557+//
1558+
1559+#import <UIKit/UIKit.h>
1560+
1561+@interface UOAppDelegate : UIResponder <UIApplicationDelegate>
1562+
1563+@property (strong, nonatomic) UIWindow *window;
1564+
1565+@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
1566+@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
1567+@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
1568+
1569+@property (nonatomic, retain) NSOperationQueue *queue;
1570+
1571+- (void)saveContext;
1572+- (NSURL *)applicationDocumentsDirectory;
1573+- (NSURL *)applicationCachesDirectory;
1574+- (NSURL *)albumArtDirectory;
1575+
1576++ (UOAppDelegate *)delegate;
1577+
1578+@end
1579
1580=== added file 'Music/UOAppDelegate.m'
1581--- Music/UOAppDelegate.m 1970-01-01 00:00:00 +0000
1582+++ Music/UOAppDelegate.m 2013-01-24 17:06:42 +0000
1583@@ -0,0 +1,208 @@
1584+//
1585+// UOAppDelegate.m
1586+// U1Music
1587+//
1588+// Created by Paul Hummer on 1/21/13.
1589+// Copyright (c) 2013 Canonical. All rights reserved.
1590+//
1591+// Redistribution and use in source and binary forms, with or without modification,
1592+// are permitted provided that the following conditions are met:
1593+//
1594+// * Redistributions of source code must retain the above copyright notice, this
1595+// list of conditions and the following disclaimer.
1596+// * Redistributions in binary form must reproduce the above copyright notice,
1597+// this list of conditions and the following disclaimer in the documentation
1598+// and/or other materials provided with the distribution.
1599+// * Neither the my name nor the names of my contributors may be used to endorse
1600+// or promote products derived from this software without specific prior written
1601+// permission.
1602+//
1603+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
1604+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1605+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
1606+// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
1607+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
1608+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1609+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1610+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
1611+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1612+// DAMAGE.
1613+
1614+#import "UOAppDelegate.h"
1615+#import "UOAuthManager.h"
1616+#import "U1LocalMusicServer.h"
1617+#import "StreamingPlayer.h"
1618+#import "Subsonic.h"
1619+
1620+#if TARGET_IPHONE_SIMULATOR
1621+@implementation NSURLRequest(AllowAllCerts)
1622++ (BOOL) allowsAnyHTTPSCertificateForHost:(NSString *)host {
1623+ return YES;
1624+}
1625+@end
1626+#endif
1627+
1628+@interface UOAppDelegate ()
1629+@property (readonly, strong, nonatomic) UIStoryboard *storyboard;
1630+@property (readonly, strong, nonatomic) U1LocalMusicServer *musicServer;
1631+@end
1632+
1633+@implementation UOAppDelegate
1634+@synthesize managedObjectContext = _managedObjectContext;
1635+@synthesize managedObjectModel = _managedObjectModel;
1636+@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
1637+@synthesize storyboard = _storyboard;
1638+@synthesize musicServer = _musicServer;
1639+
1640+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
1641+
1642+ self.queue = [[NSOperationQueue alloc] init];
1643+ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds ]];
1644+
1645+ /* rockstar - WTF? This should just work with the target settings. */
1646+ _storyboard = [UIStoryboard storyboardWithName:@"Storyboard_iPhone" bundle: nil];
1647+ [self.window setRootViewController:[_storyboard instantiateInitialViewController]];
1648+
1649+ /* Set up the local music server for serving music */
1650+ _musicServer = [U1LocalMusicServer new];
1651+ [[StreamingPlayer sharedStreamingPlayer] recoverState];
1652+
1653+ [self checkAuthentication];
1654+ return YES;
1655+}
1656+
1657+- (void)applicationWillTerminate:(UIApplication *)application {
1658+ // Saves changes in the application's managed object context before the application terminates.
1659+ [self saveContext];
1660+}
1661+
1662+- (void)saveContext {
1663+ NSError *error = nil;
1664+ NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
1665+ if (managedObjectContext != nil) {
1666+ if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
1667+ // Replace this implementation with code to handle the error appropriately.
1668+ // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.-
1669+ NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
1670+ abort();
1671+ }
1672+ }
1673+}
1674+
1675+#pragma mark - Core Data stack
1676+
1677+// Returns the managed object context for the application.
1678+// If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
1679+- (NSManagedObjectContext *)managedObjectContext
1680+{
1681+ if (_managedObjectContext != nil) {
1682+ return _managedObjectContext;
1683+ }
1684+
1685+ NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
1686+ if (coordinator != nil) {
1687+ _managedObjectContext = [[NSManagedObjectContext alloc] init];
1688+ [_managedObjectContext setPersistentStoreCoordinator:coordinator];
1689+ }
1690+ return _managedObjectContext;
1691+}
1692+
1693+// Returns the managed object model for the application.
1694+// If the model doesn't already exist, it is created from the application's model.
1695+- (NSManagedObjectModel *)managedObjectModel
1696+{
1697+ if (_managedObjectModel != nil) {
1698+ return _managedObjectModel;
1699+ }
1700+ NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"UOMusic" withExtension:@"momd"];
1701+ _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
1702+ return _managedObjectModel;
1703+}
1704+
1705+// Returns the persistent store coordinator for the application.
1706+// If the coordinator doesn't already exist, it is created and the application's store added to it.
1707+- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
1708+{
1709+ if (_persistentStoreCoordinator != nil) {
1710+ return _persistentStoreCoordinator;
1711+ }
1712+
1713+ NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"UOMusic.sqlite"];
1714+
1715+ NSError *error = nil;
1716+ _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
1717+ if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
1718+ /*
1719+ Replace this implementation with code to handle the error appropriately.
1720+
1721+ abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
1722+
1723+ Typical reasons for an error here include:
1724+ * The persistent store is not accessible;
1725+ * The schema for the persistent store is incompatible with current managed object model.
1726+ Check the error message to determine what the actual problem was.
1727+
1728+
1729+ If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.
1730+
1731+ If you encounter schema incompatibility errors during development, you can reduce their frequency by:
1732+ * Simply deleting the existing store:
1733+ [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]
1734+
1735+ * Performing automatic lightweight migration by passing the following dictionary as the options parameter:
1736+ @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES}
1737+
1738+ Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
1739+
1740+ */
1741+ NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
1742+ abort();
1743+ }
1744+
1745+ return _persistentStoreCoordinator;
1746+}
1747+
1748+#pragma mark - Convenience methods
1749+
1750++ (UOAppDelegate *)delegate {
1751+ return (UOAppDelegate *)[UIApplication sharedApplication].delegate;
1752+}
1753+
1754+#pragma mark - Application's Documents directory
1755+
1756+// Returns the URL to the application's Documents directory.
1757+- (NSURL *)applicationDocumentsDirectory {
1758+ return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
1759+}
1760+
1761+- (NSURL *)applicationCachesDirectory {
1762+ return [[[NSFileManager defaultManager] URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
1763+}
1764+
1765+- (NSURL *)albumArtDirectory {
1766+ NSURL *path = [[self applicationCachesDirectory] URLByAppendingPathComponent:@"albumArt"];
1767+ if (![[NSFileManager defaultManager] fileExistsAtPath:[path path]]) {
1768+ NSError *error;
1769+ [[NSFileManager defaultManager] createDirectoryAtPath:[path path] withIntermediateDirectories:YES attributes:nil error:&error];
1770+ if (error) {
1771+ abort();
1772+ }
1773+ }
1774+ return path;
1775+}
1776+
1777+#pragma mark - Private methods
1778+
1779+- (void)checkAuthentication {
1780+ if (![[UOAuthManager sharedAuthManager] hasCredentials]) {
1781+ UITabBarController *rootViewController = (UITabBarController *)self.window.rootViewController;
1782+ rootViewController.selectedIndex = 4;
1783+ } else {
1784+ [[Subsonic sharedSubsonic] setDefaultUserName:[[UOAuthManager sharedAuthManager] subsonicUsername]];
1785+ [[Subsonic sharedSubsonic] setDefaultPassword:[[UOAuthManager sharedAuthManager] subsonicPassword]];
1786+ }
1787+
1788+ [self.window makeKeyAndVisible];
1789+}
1790+
1791+@end
1792
1793=== added directory 'Music/UOMusic.xcdatamodeld'
1794=== added directory 'Music/UOMusic.xcdatamodeld/UOMusic.xcdatamodel'
1795=== added file 'Music/UOMusic.xcdatamodeld/UOMusic.xcdatamodel/contents'
1796--- Music/UOMusic.xcdatamodeld/UOMusic.xcdatamodel/contents 1970-01-01 00:00:00 +0000
1797+++ Music/UOMusic.xcdatamodeld/UOMusic.xcdatamodel/contents 2013-01-24 17:06:42 +0000
1798@@ -0,0 +1,60 @@
1799+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1800+<model name="" userDefinedModelVersionIdentifier="UOMusic0" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1811" systemVersion="12C60" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic">
1801+ <entity name="Album" representedClassName="Album" syncable="YES">
1802+ <attribute name="albumId" attributeType="String" indexed="YES" syncable="YES"/>
1803+ <attribute name="artHash" optional="YES" attributeType="String" syncable="YES"/>
1804+ <attribute name="artUrl" optional="YES" attributeType="String" syncable="YES"/>
1805+ <attribute name="dearticlizedTitle" attributeType="String" syncable="YES"/>
1806+ <attribute name="index" optional="YES" transient="YES" attributeType="String" syncable="YES"/>
1807+ <attribute name="title" attributeType="String" syncable="YES"/>
1808+ <attribute name="url" attributeType="String" syncable="YES"/>
1809+ <relationship name="artist" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="Artist" inverseName="albums" inverseEntity="Artist" syncable="YES"/>
1810+ <relationship name="songs" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Song" inverseName="album" inverseEntity="Song" syncable="YES"/>
1811+ </entity>
1812+ <entity name="Artist" representedClassName="Artist" syncable="YES">
1813+ <attribute name="art" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/>
1814+ <attribute name="artistId" attributeType="String" indexed="YES" syncable="YES"/>
1815+ <attribute name="artUrl" optional="YES" attributeType="String" syncable="YES"/>
1816+ <attribute name="dearticlizedName" attributeType="String" syncable="YES"/>
1817+ <attribute name="index" optional="YES" transient="YES" attributeType="String" syncable="YES"/>
1818+ <attribute name="name" attributeType="String" syncable="YES"/>
1819+ <attribute name="url" attributeType="String" syncable="YES"/>
1820+ <relationship name="albums" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Album" inverseName="artist" inverseEntity="Album" syncable="YES"/>
1821+ <relationship name="songs" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Song" inverseName="albumArtist" inverseEntity="Song" syncable="YES"/>
1822+ </entity>
1823+ <entity name="Playlist" representedClassName="Playlist" syncable="YES">
1824+ <attribute name="dearticlizedTitle" attributeType="String" syncable="YES"/>
1825+ <attribute name="index" optional="YES" transient="YES" attributeType="String" syncable="YES"/>
1826+ <attribute name="playlistId" attributeType="String" indexed="YES" syncable="YES"/>
1827+ <attribute name="songCount" attributeType="Integer 16" defaultValueString="0" syncable="YES"/>
1828+ <attribute name="title" attributeType="String" syncable="YES"/>
1829+ <attribute name="url" attributeType="String" syncable="YES"/>
1830+ </entity>
1831+ <entity name="Song" representedClassName="Song" syncable="YES">
1832+ <attribute name="bitRate" optional="YES" attributeType="String" syncable="YES"/>
1833+ <attribute name="contentType" optional="YES" attributeType="String" syncable="YES"/>
1834+ <attribute name="dearticlizedTitle" attributeType="String" syncable="YES"/>
1835+ <attribute name="discNumber" optional="YES" attributeType="String" syncable="YES"/>
1836+ <attribute name="duration" optional="YES" attributeType="String" syncable="YES"/>
1837+ <attribute name="genre" optional="YES" attributeType="String" syncable="YES"/>
1838+ <attribute name="index" optional="YES" transient="YES" attributeType="String" syncable="YES"/>
1839+ <attribute name="path" attributeType="String" syncable="YES"/>
1840+ <attribute name="size" optional="YES" attributeType="String" syncable="YES"/>
1841+ <attribute name="songId" attributeType="String" indexed="YES" syncable="YES"/>
1842+ <attribute name="streamUrl" attributeType="String" syncable="YES"/>
1843+ <attribute name="suffix" optional="YES" attributeType="String" syncable="YES"/>
1844+ <attribute name="title" attributeType="String" syncable="YES"/>
1845+ <attribute name="track" optional="YES" attributeType="String" syncable="YES"/>
1846+ <attribute name="url" attributeType="String" syncable="YES"/>
1847+ <attribute name="year" optional="YES" attributeType="String" syncable="YES"/>
1848+ <relationship name="album" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="Album" inverseName="songs" inverseEntity="Album" syncable="YES"/>
1849+ <relationship name="albumArtist" optional="YES" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="Artist" inverseName="songs" inverseEntity="Artist" syncable="YES"/>
1850+ <relationship name="artist" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="Artist" inverseName="songs" inverseEntity="Artist" syncable="YES"/>
1851+ </entity>
1852+ <elements>
1853+ <element name="Album" positionX="468" positionY="180" width="128" height="180"/>
1854+ <element name="Artist" positionX="160" positionY="195" width="128" height="180"/>
1855+ <element name="Playlist" positionX="160" positionY="192" width="128" height="135"/>
1856+ <element name="Song" positionX="160" positionY="192" width="128" height="330"/>
1857+ </elements>
1858+</model>
1859\ No newline at end of file
1860
1861=== added directory 'Music/Utilities'
1862=== added file 'Music/Utilities/UOWebServiceController.h'
1863--- Music/Utilities/UOWebServiceController.h 1970-01-01 00:00:00 +0000
1864+++ Music/Utilities/UOWebServiceController.h 2013-01-24 17:06:42 +0000
1865@@ -0,0 +1,39 @@
1866+//
1867+// UOWebServiceController.h
1868+// U1Music
1869+//
1870+// Created by Paul Hummer on 12/12/12.
1871+// Copyright (c) 2012 Canonical. All rights reserved.
1872+//
1873+
1874+#import <Foundation/Foundation.h>
1875+#import <RestKit/RestKit.h>
1876+
1877+#define ALBUMS_LAST_UPDATED @"albumsLastUpdated"
1878+#define ARTISTS_LAST_UPDATED @"artistsLastUpdated"
1879+#define PLAYLISTS_LAST_UPDATED @"playlistsLastUpdated"
1880+#define SONGS_LAST_UPDATED @"songsLastUpdated"
1881+
1882+@protocol UOWebServiceDelegate <NSObject>
1883+
1884+- (void)webserviceUpdateComplete;
1885+- (void)webserviceUpdateError:(NSError *)error;
1886+
1887+@end
1888+
1889+@interface UOWebServiceController : NSObject
1890++ (UOWebServiceController *)controller;
1891+
1892+- (void)updateAlbums:(id<UOWebServiceDelegate>)delegate;
1893+- (void)updateAlbums:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache;
1894+
1895+- (void)updateArtists:(id<UOWebServiceDelegate>)delegate;
1896+- (void)updateArtists:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache;
1897+
1898+- (void)updatePlaylists:(id<UOWebServiceDelegate>)delegate;
1899+- (void)updatePlaylists:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache;
1900+
1901+- (void)updateSongs:(id<UOWebServiceDelegate>)delegate;
1902+- (void)updateSongs:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache;
1903+
1904+@end
1905
1906=== added file 'Music/Utilities/UOWebServiceController.m'
1907--- Music/Utilities/UOWebServiceController.m 1970-01-01 00:00:00 +0000
1908+++ Music/Utilities/UOWebServiceController.m 2013-01-24 17:06:42 +0000
1909@@ -0,0 +1,208 @@
1910+//
1911+// UOWebServiceController.m
1912+// U1Music
1913+//
1914+// Created by Paul Hummer on 12/12/12.
1915+// Copyright (c) 2012 Canonical. All rights reserved.
1916+//
1917+
1918+#import "UOWebServiceController.h"
1919+#import <RestKit/RestKit.h>
1920+#import <RestKit/CoreData.h>
1921+#import "UONetworkStatusCoordinator.h"
1922+#import "UOAuthManager.h"
1923+#import "UOAppDelegate.h"
1924+
1925+#import "Album.h"
1926+#import "Artist.h"
1927+#import "Playlist.h"
1928+#import "Song.h"
1929+
1930+@interface UOWebServiceController ()
1931+- (void)updateAlbumsWithBlock:(void(^)(void))completionBlock;
1932+- (void)updateArtistsWithBlock:(void(^)(void))completionBlock;
1933+- (void)updateSongsWithBlock:(void(^)(void))completionBlock;
1934+@end
1935+
1936+@implementation UOWebServiceController
1937+
1938+- (id)init {
1939+ self = [super init];
1940+ [self initRestKit];
1941+ return self;
1942+}
1943+
1944+#pragma mark - Static methods
1945+
1946++ (UOWebServiceController *)controller {
1947+ static UOWebServiceController *instance = nil;
1948+ static dispatch_once_t once;
1949+ dispatch_once(&once, ^{
1950+ instance = [[UOWebServiceController alloc] init];
1951+ });
1952+ return instance;
1953+}
1954+
1955+#pragma mark - Network operations
1956+
1957+- (void)updateAlbums:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache {
1958+ if (clearCache || [self needsUpdating:ALBUMS_LAST_UPDATED]) {
1959+ [self updateArtistsWithBlock:^(void) {
1960+ [[RKObjectManager sharedManager] getObjectsAtPath:@"albums/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
1961+ [delegate webserviceUpdateComplete];
1962+ } failure:^(RKObjectRequestOperation *operation, NSError *error) {
1963+ [[NSUserDefaults standardUserDefaults] setObject:nil forKey:ALBUMS_LAST_UPDATED];
1964+ [delegate webserviceUpdateError:error];
1965+ }];
1966+ }];
1967+ }
1968+}
1969+
1970+- (void)updateAlbums:(id<UOWebServiceDelegate>)delegate {
1971+ [self updateAlbums:delegate clearCache:NO];
1972+}
1973+
1974+- (void)updateAlbumsWithBlock:(void (^)(void))completionBlock {
1975+ if ([self needsUpdating:ALBUMS_LAST_UPDATED]) {
1976+ [self updateArtistsWithBlock:^(void) {
1977+ [[RKObjectManager sharedManager] getObjectsAtPath:@"albums/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
1978+ [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:ALBUMS_LAST_UPDATED];
1979+ completionBlock();
1980+ } failure:^(RKObjectRequestOperation *operation, NSError *error) {
1981+ [[NSUserDefaults standardUserDefaults] setObject:nil forKey:ALBUMS_LAST_UPDATED];
1982+ }];
1983+ }];
1984+ } else {
1985+ completionBlock();
1986+ }
1987+}
1988+
1989+- (void)updateArtists:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache {
1990+ if (clearCache || [self needsUpdating:ARTISTS_LAST_UPDATED]) {
1991+ [[RKObjectManager sharedManager] getObjectsAtPath:@"artists/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
1992+ [delegate webserviceUpdateComplete];
1993+ } failure:^(RKObjectRequestOperation *operation, NSError *error) {
1994+ [[NSUserDefaults standardUserDefaults] setObject:nil forKey:ARTISTS_LAST_UPDATED];
1995+ [delegate webserviceUpdateError:error];
1996+ }];
1997+ }
1998+}
1999+
2000+- (void)updateArtists:(id<UOWebServiceDelegate>)delegate {
2001+ [self updateArtists:delegate clearCache:NO];
2002+}
2003+
2004+- (void)updateArtistsWithBlock:(void(^)(void))completionBlock {
2005+ if ([self needsUpdating:ARTISTS_LAST_UPDATED]) {
2006+ [[RKObjectManager sharedManager] getObjectsAtPath:@"artists/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
2007+ [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:ARTISTS_LAST_UPDATED];
2008+ completionBlock();
2009+ } failure:^(RKObjectRequestOperation *operation, NSError *error) {
2010+ [[NSUserDefaults standardUserDefaults] setObject:nil forKey:ARTISTS_LAST_UPDATED];
2011+ }];
2012+ } else {
2013+ completionBlock();
2014+ }
2015+}
2016+
2017+- (void)updatePlaylists:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache {
2018+ if (clearCache || [self needsUpdating:PLAYLISTS_LAST_UPDATED]) {
2019+ [self updateSongsWithBlock:^(void) {
2020+ [[RKObjectManager sharedManager] getObjectsAtPath:@"playlists/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
2021+ [delegate webserviceUpdateComplete];
2022+ } failure:^(RKObjectRequestOperation *operation, NSError *error) {
2023+ [[NSUserDefaults standardUserDefaults] setObject:nil forKey:PLAYLISTS_LAST_UPDATED];
2024+ [delegate webserviceUpdateError:error];
2025+ }];
2026+ }];
2027+ }
2028+}
2029+
2030+- (void)updatePlaylists:(id<UOWebServiceDelegate>)delegate {
2031+ [self updatePlaylists:delegate clearCache:NO];
2032+}
2033+
2034+- (void)updateSongs:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache {
2035+ if (clearCache || [self needsUpdating:SONGS_LAST_UPDATED]) {
2036+ [self updateAlbumsWithBlock:^(void) {
2037+ [[RKObjectManager sharedManager] getObjectsAtPath:@"songs/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
2038+ [delegate webserviceUpdateComplete];
2039+ } failure:^(RKObjectRequestOperation *operation, NSError *error) {
2040+ [[NSUserDefaults standardUserDefaults] setObject:nil forKey:SONGS_LAST_UPDATED];
2041+ [delegate webserviceUpdateError:error];
2042+ }];
2043+ }];
2044+ }
2045+}
2046+
2047+- (void)updateSongs:(id<UOWebServiceDelegate>)delegate {
2048+ [self updateSongs:delegate clearCache:NO];
2049+}
2050+
2051+- (void)updateSongsWithBlock:(void (^)(void))completionBlock {
2052+ if ([self needsUpdating:SONGS_LAST_UPDATED]) {
2053+ [self updateAlbumsWithBlock:^(void) {
2054+ [[RKObjectManager sharedManager] getObjectsAtPath:@"songs/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
2055+ [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:SONGS_LAST_UPDATED];
2056+ completionBlock();
2057+ } failure:^(RKObjectRequestOperation *operation, NSError *error) {
2058+ [[NSUserDefaults standardUserDefaults] setObject:nil forKey:SONGS_LAST_UPDATED];
2059+ }];
2060+ }];
2061+ } else {
2062+ completionBlock();
2063+ }
2064+}
2065+
2066+#pragma mark - Private methods
2067+
2068+- (BOOL)needsUpdating:(NSString *)key {
2069+ int interval = -(60*60*24*5); // 5 days ago
2070+ NSDate *freshInterval = [NSDate dateWithTimeIntervalSinceNow:interval];
2071+ NSDate *lastUpdatedAt = [[NSUserDefaults standardUserDefaults] objectForKey:key];
2072+
2073+ BOOL updateNeeded = (lastUpdatedAt == nil || [freshInterval compare:lastUpdatedAt] == NSOrderedDescending);
2074+ if (updateNeeded) {
2075+ [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:key];
2076+ }
2077+ return updateNeeded;
2078+}
2079+
2080+- (void)initRestKit {
2081+ RKLogConfigureByName("RestKit/Network", RKLogLevelWarning);
2082+
2083+ NSURL *baseUrl = [NSURL URLWithString:@"https://one.ubuntu.com/api/music/v2/"];
2084+ RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseUrl];
2085+
2086+ /* Handle Plaintext auth */
2087+ NSURLRequest *echo = [UOAuthManager oauthRequestForPath:[baseUrl path]];
2088+ [objectManager.HTTPClient setDefaultHeader:@"Authorization" value:[echo valueForHTTPHeaderField:@"Authorization"]];
2089+ [objectManager.HTTPClient setDefaultHeader:@"Accept-Encoding" value:[echo valueForHTTPHeaderField:@"Accept-Encoding"]];
2090+ [objectManager.HTTPClient setDefaultHeader:@"User-Agent" value:[echo valueForHTTPHeaderField:@"User-Agent"]];
2091+
2092+ /* Show animated network I/O indicator when doing network I/O */
2093+ [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
2094+
2095+ /* Set up managed object store */
2096+ NSManagedObjectModel *managedObjectModel = [[UOAppDelegate delegate] managedObjectModel];
2097+ RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
2098+
2099+ /* Why the hell is RestKit not smart enough to do this automatically? Annoy. */
2100+ NSError *error;
2101+ [managedObjectStore addSQLitePersistentStoreAtPath:[RKApplicationDataDirectory() stringByAppendingPathComponent:@"UOMusic.sqlite"] fromSeedDatabaseAtPath:nil withConfiguration:nil options:nil error:&error];
2102+ if (error) {
2103+ NSLog(@"Database model is out of date");
2104+ abort();
2105+ }
2106+ [objectManager setManagedObjectStore:managedObjectStore];
2107+ [managedObjectStore createManagedObjectContexts];
2108+
2109+ [Album registerMapping];
2110+ [Artist registerMapping];
2111+ [Playlist registerMapping];
2112+ [Song registerMapping];
2113+
2114+ [RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"application/json"];
2115+}
2116+
2117+@end
2118
2119=== added directory 'Music/View Controllers'
2120=== added file 'Music/View Controllers/AlbumViewController.h'
2121--- Music/View Controllers/AlbumViewController.h 1970-01-01 00:00:00 +0000
2122+++ Music/View Controllers/AlbumViewController.h 2013-01-24 17:06:42 +0000
2123@@ -0,0 +1,17 @@
2124+//
2125+// AlbumViewController.h
2126+// U1Music
2127+//
2128+// Created by Paul Hummer on 11/15/12.
2129+// Copyright (c) 2012 Canonical. All rights reserved.
2130+//
2131+
2132+#import <UIKit/UIKit.h>
2133+
2134+@class Album;
2135+
2136+@interface AlbumViewController : UIViewController
2137+@property (nonatomic, retain) NSString *albumId;
2138+
2139+@property (strong, nonatomic) IBOutlet UIBarButtonItem *nowPlayingButton;
2140+@end
2141
2142=== added file 'Music/View Controllers/AlbumViewController.m'
2143--- Music/View Controllers/AlbumViewController.m 1970-01-01 00:00:00 +0000
2144+++ Music/View Controllers/AlbumViewController.m 2013-01-24 17:06:42 +0000
2145@@ -0,0 +1,149 @@
2146+//
2147+// AlbumViewController.m
2148+// U1Music
2149+//
2150+// Created by Paul Hummer on 11/15/12.
2151+// Copyright (c) 2012 Canonical. All rights reserved.
2152+//
2153+
2154+#import "AlbumViewController.h"
2155+#import "Album.h"
2156+#import <RestKit/RestKit.h>
2157+#import "SongCell.h"
2158+#import "Song.h"
2159+#import "UOWebServiceController.h"
2160+
2161+#import "StreamingPlayer.h"
2162+
2163+@interface AlbumViewController () <UITableViewDataSource, UOWebServiceDelegate> {
2164+ NSArray *tableData;
2165+
2166+ Album *album;
2167+}
2168+@property (weak, nonatomic) IBOutlet UIImageView *albumArt;
2169+@property (weak, nonatomic) IBOutlet UILabel *albumTitle;
2170+@property (weak, nonatomic) IBOutlet UILabel *albumDescription;
2171+@property (weak, nonatomic) IBOutlet UITableView *tableView;
2172+
2173+@end
2174+
2175+@implementation AlbumViewController
2176+@synthesize albumId = _albumId;
2177+
2178+- (void)viewDidLoad {
2179+ [self.tableView setDataSource:self];
2180+}
2181+
2182+- (void)viewWillAppear:(BOOL)animated {
2183+ [self fetchAlbum];
2184+
2185+ if (![[StreamingPlayer sharedStreamingPlayer] currentSong]) {
2186+ self.navigationItem.rightBarButtonItem = nil;
2187+ } else {
2188+ self.navigationItem.rightBarButtonItem = self.nowPlayingButton;
2189+ }
2190+
2191+ [_albumTitle setText:album.title];
2192+ [_albumDescription setText:album.artist.name];
2193+ if (!album.art) {
2194+ [album fetchArt:^(UIImage *image) {
2195+ [self.albumArt setImage:image];
2196+ [self.albumArt setNeedsDisplay];
2197+ }];
2198+ } else {
2199+ [self.albumArt setImage:album.art];
2200+ }
2201+
2202+ if ([album.songs count]) {
2203+ NSArray *sortDescriptors = [NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"track" ascending:NO], nil];
2204+ tableData = [album.songs sortedArrayUsingDescriptors:sortDescriptors];
2205+ [self.tableView reloadData];
2206+ } else {
2207+ [[UOWebServiceController controller] updateSongs:self];
2208+ }
2209+}
2210+
2211+- (void)viewDidUnload {
2212+ [self setAlbumArt:nil];
2213+ [self setAlbumTitle:nil];
2214+ [self setAlbumDescription:nil];
2215+ [self setTableView:nil];
2216+ [self setNowPlayingButton:nil];
2217+ [super viewDidUnload];
2218+}
2219+
2220+#pragma mark - UITableViewDelegate methods
2221+
2222+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
2223+ return [tableData count];
2224+}
2225+
2226+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
2227+ static NSString *CellIndentifier = @"Cell";
2228+ SongCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIndentifier forIndexPath:indexPath];
2229+ Song *song = [tableData objectAtIndex:indexPath.row];
2230+ [cell setSong:song];
2231+ return cell;
2232+}
2233+
2234+#pragma mark - Private methods
2235+
2236+- (void)fetchAlbum {
2237+ NSManagedObjectContext *managedObjectContext = [[[RKObjectManager sharedManager] managedObjectStore] persistentStoreManagedObjectContext];
2238+
2239+ NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
2240+ NSEntityDescription *entity = [NSEntityDescription entityForName:@"Album" inManagedObjectContext:managedObjectContext];
2241+ [fetchRequest setEntity:entity];
2242+
2243+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(albumId = %@)", _albumId];
2244+ [fetchRequest setPredicate:predicate];
2245+
2246+ NSError *error;
2247+ NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
2248+ if (error || [results count] != 1) {
2249+ abort();
2250+ }
2251+ album = [results objectAtIndex:0];
2252+}
2253+
2254+#pragma mark - UOWebServiceDelegate methods
2255+
2256+- (void)webserviceUpdateComplete {
2257+ NSManagedObjectContext *managedObjectContext = [[[RKObjectManager sharedManager] managedObjectStore] persistentStoreManagedObjectContext];
2258+ [managedObjectContext refreshObject:album mergeChanges:NO];
2259+
2260+ NSArray *sortDescriptors = [NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"dearticlizedTitle" ascending:YES], nil];
2261+ tableData = [album.songs sortedArrayUsingDescriptors:sortDescriptors];
2262+
2263+ [self.tableView reloadData];
2264+}
2265+
2266+- (void)webserviceUpdateError:(NSError *)error {
2267+ if ([error code] == 2) { // Network is down.
2268+ return;
2269+ }
2270+ NSLog(@"Error: %@", [error localizedDescription]);
2271+}
2272+
2273+#pragma mark - Storyboard methods
2274+
2275+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
2276+ NSArray *songs = [tableData copy];
2277+ if (![sender respondsToSelector:@selector(song)]) {
2278+ return; // Hit 'Now Playing'
2279+ }
2280+ Song *song = ((SongCell *)sender).song;
2281+
2282+ StreamingPlayer *player = [StreamingPlayer sharedStreamingPlayer];
2283+ player.currentSong = song;
2284+ player.currentPlaylist = songs;
2285+ player.isNewSong = YES;
2286+ player.isShuffle = NO;
2287+
2288+ if (player.streamer) {
2289+ [player.streamer stop];
2290+ }
2291+ [player playPauseSong];
2292+}
2293+
2294+@end
2295
2296=== added file 'Music/View Controllers/AlbumsViewController.h'
2297--- Music/View Controllers/AlbumsViewController.h 1970-01-01 00:00:00 +0000
2298+++ Music/View Controllers/AlbumsViewController.h 2013-01-24 17:06:42 +0000
2299@@ -0,0 +1,12 @@
2300+//
2301+// AlbumsViewController.h
2302+// U1Music
2303+//
2304+// Created by Paul Hummer on 11/15/12.
2305+// Copyright (c) 2012 Canonical. All rights reserved.
2306+//
2307+
2308+#import "UOIndexedViewController.h"
2309+
2310+@interface AlbumsViewController : UOIndexedViewController
2311+@end
2312
2313=== added file 'Music/View Controllers/AlbumsViewController.m'
2314--- Music/View Controllers/AlbumsViewController.m 1970-01-01 00:00:00 +0000
2315+++ Music/View Controllers/AlbumsViewController.m 2013-01-24 17:06:42 +0000
2316@@ -0,0 +1,60 @@
2317+//
2318+// AlbumsViewController.m
2319+// U1Music
2320+//
2321+// Created by Paul Hummer on 11/15/12.
2322+// Copyright (c) 2012 Canonical. All rights reserved.
2323+//
2324+
2325+#import "AlbumsViewController.h"
2326+#import "UONetworkStatusCoordinator.h"
2327+#import "NSString+Extras.h"
2328+#import "Album.h"
2329+#import "AlbumCell.h"
2330+#import "AlbumViewController.h"
2331+#import "UOWebServiceController.h"
2332+
2333+@interface AlbumsViewController ()
2334+
2335+@end
2336+
2337+@implementation AlbumsViewController
2338+
2339+#pragma mark - UOIndexedViewControllers methods
2340+
2341+- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
2342+ Album *album = [self.fetchedResultsController objectAtIndexPath:indexPath];
2343+ AlbumCell *albumCell = (AlbumCell *)cell;
2344+ [albumCell setAlbum:album];
2345+}
2346+
2347+- (NSString *)entityName {
2348+ return @"Album";
2349+}
2350+
2351+- (NSString *)lastUpdatedKey {
2352+ return ALBUMS_LAST_UPDATED;
2353+}
2354+
2355+- (NSArray *)sortDescriptors {
2356+ return [NSArray arrayWithObjects:
2357+ [[NSSortDescriptor alloc] initWithKey:@"dearticlizedTitle" ascending:YES],
2358+ nil];
2359+}
2360+
2361+- (void)update {
2362+ [[UOWebServiceController controller] updateAlbums:self];
2363+}
2364+
2365+#pragma mark - Storyboard methods
2366+
2367+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
2368+ if (![sender respondsToSelector:@selector(album)]) {
2369+ return; // Hit 'Now Playing'
2370+ }
2371+ AlbumViewController *albumViewController = [segue destinationViewController];
2372+ Album *album = ((AlbumCell *)sender).album;
2373+ albumViewController.albumId = album.albumId;
2374+}
2375+
2376+@end
2377
2378=== added file 'Music/View Controllers/ArtistViewController.h'
2379--- Music/View Controllers/ArtistViewController.h 1970-01-01 00:00:00 +0000
2380+++ Music/View Controllers/ArtistViewController.h 2013-01-24 17:06:42 +0000
2381@@ -0,0 +1,17 @@
2382+//
2383+// ArtistViewController.h
2384+// U1Music
2385+//
2386+// Created by Paul Hummer on 11/15/12.
2387+// Copyright (c) 2012 Canonical. All rights reserved.
2388+//
2389+
2390+#import <UIKit/UIKit.h>
2391+
2392+@class Artist;
2393+
2394+@interface ArtistViewController : UIViewController
2395+@property (nonatomic, retain) NSString *artistId;
2396+
2397+@property (strong, nonatomic) IBOutlet UIBarButtonItem *nowPlayingButton;
2398+@end
2399
2400=== added file 'Music/View Controllers/ArtistViewController.m'
2401--- Music/View Controllers/ArtistViewController.m 1970-01-01 00:00:00 +0000
2402+++ Music/View Controllers/ArtistViewController.m 2013-01-24 17:06:42 +0000
2403@@ -0,0 +1,140 @@
2404+//
2405+// ArtistViewController.m
2406+// U1Music
2407+//
2408+// Created by Paul Hummer on 11/15/12.
2409+// Copyright (c) 2012 Canonical. All rights reserved.
2410+//
2411+
2412+#import "ArtistViewController.h"
2413+#import "UONetworkStatusCoordinator.h"
2414+#import <RestKit/RestKit.h>
2415+
2416+#import "Artist.h"
2417+#import "Album.h"
2418+#import "AlbumCell.h"
2419+#import "AlbumViewController.h"
2420+#import "UOWebServiceController.h"
2421+#import "UOAppDelegate.h"
2422+#import "StreamingPlayer.h"
2423+
2424+@interface ArtistViewController () <UITableViewDataSource, UOWebServiceDelegate> {
2425+ NSArray *tableData;
2426+
2427+ Artist *artist;
2428+}
2429+@property (weak, nonatomic) IBOutlet UIImageView *albumArt;
2430+@property (weak, nonatomic) IBOutlet UILabel *artistName;
2431+@property (weak, nonatomic) IBOutlet UILabel *artistDescription;
2432+@property (weak, nonatomic) IBOutlet UITableView *tableView;
2433+
2434+@end
2435+
2436+@implementation ArtistViewController
2437+@synthesize artistId = _artistId;
2438+
2439+- (void)viewDidLoad {
2440+ [self.tableView setDataSource:self];
2441+}
2442+
2443+- (void)viewWillAppear:(BOOL)animated {
2444+ [[UOWebServiceController controller] updateAlbums:self];
2445+ [self fetchArtist];
2446+
2447+ [_artistName setText:artist.name];
2448+ if (!artist.art) {
2449+ [artist fetchArt:^(UIImage *image) {
2450+ [self.albumArt setImage:image];
2451+ [self.albumArt setNeedsDisplay];
2452+ }];
2453+ } else {
2454+ [self.albumArt setImage:artist.art];
2455+ }
2456+
2457+ if (![[StreamingPlayer sharedStreamingPlayer] currentSong]) {
2458+ self.navigationItem.rightBarButtonItem = nil;
2459+ } else {
2460+ self.navigationItem.rightBarButtonItem = self.nowPlayingButton;
2461+ }
2462+
2463+ NSString *pluralizedNoun = @"albums";
2464+ if ([artist.albums count] == 1) {
2465+ pluralizedNoun = @"album";
2466+ }
2467+ [_artistDescription setText:[NSString stringWithFormat:@"%d %@", [artist.albums count], pluralizedNoun]];
2468+ NSArray *sortDescriptors = [NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"dearticlizedTitle" ascending:YES], nil];
2469+ tableData = [artist.albums sortedArrayUsingDescriptors:sortDescriptors];
2470+ [self.tableView reloadData];
2471+}
2472+
2473+- (void)viewDidUnload {
2474+ [self setAlbumArt:nil];
2475+ [self setArtistName:nil];
2476+ [self setArtistDescription:nil];
2477+ [self setTableView:nil];
2478+ [super viewDidUnload];
2479+}
2480+
2481+#pragma mark - UITableViewDelegate methods
2482+
2483+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
2484+ return [tableData count];
2485+}
2486+
2487+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
2488+ static NSString *CellIndentifier = @"Cell";
2489+ AlbumCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIndentifier forIndexPath:indexPath];
2490+ Album *album = [tableData objectAtIndex:indexPath.row];
2491+ [cell setAlbum:album];
2492+ return cell;
2493+}
2494+
2495+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
2496+ if (![sender respondsToSelector:@selector(album)]) {
2497+ return; // Hit 'Now Playing'
2498+ }
2499+ AlbumViewController *albumViewController = [segue destinationViewController];
2500+ Album *album = ((AlbumCell *)sender).album;
2501+ albumViewController.albumId = album.albumId;
2502+}
2503+
2504+#pragma mark - UOWebServiceDelegate methods
2505+
2506+- (void)webserviceUpdateComplete {
2507+ NSManagedObjectContext *managedObjectContext = [[[RKObjectManager sharedManager] managedObjectStore] persistentStoreManagedObjectContext];
2508+ [managedObjectContext refreshObject:artist mergeChanges:NO];
2509+
2510+ NSArray *sortDescriptors = [NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"dearticlizedTitle" ascending:YES], nil];
2511+ tableData = [artist.albums sortedArrayUsingDescriptors:sortDescriptors];
2512+
2513+ [self.tableView reloadData];
2514+}
2515+
2516+- (void)webserviceUpdateError:(NSError *)error {
2517+ if ([error code] == 2) { // Network is down.
2518+ return;
2519+ }
2520+ NSLog(@"Error: %@", [error localizedDescription]);
2521+}
2522+
2523+#pragma mark - Private methods
2524+
2525+- (void)fetchArtist {
2526+ NSManagedObjectContext *managedObjectContext = [[[RKObjectManager sharedManager] managedObjectStore] persistentStoreManagedObjectContext];
2527+
2528+ NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
2529+ NSEntityDescription *entity = [NSEntityDescription entityForName:@"Artist" inManagedObjectContext:managedObjectContext];
2530+ [fetchRequest setEntity:entity];
2531+
2532+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(artistId = %@)", _artistId];
2533+ [fetchRequest setPredicate:predicate];
2534+
2535+ NSError *error;
2536+ NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
2537+ if (error || [results count] != 1) {
2538+ abort();
2539+ }
2540+ artist = [results objectAtIndex:0];
2541+}
2542+
2543+@end
2544
2545=== added file 'Music/View Controllers/ArtistsViewController.h'
2546--- Music/View Controllers/ArtistsViewController.h 1970-01-01 00:00:00 +0000
2547+++ Music/View Controllers/ArtistsViewController.h 2013-01-24 17:06:42 +0000
2548@@ -0,0 +1,12 @@
2549+//
2550+// ArtistsViewController.h
2551+// U1Music
2552+//
2553+// Created by Paul Hummer on 11/15/12.
2554+// Copyright (c) 2012 Canonical. All rights reserved.
2555+//
2556+
2557+#import "UOIndexedViewController.h"
2558+
2559+@interface ArtistsViewController : UOIndexedViewController
2560+@end
2561
2562=== added file 'Music/View Controllers/ArtistsViewController.m'
2563--- Music/View Controllers/ArtistsViewController.m 1970-01-01 00:00:00 +0000
2564+++ Music/View Controllers/ArtistsViewController.m 2013-01-24 17:06:42 +0000
2565@@ -0,0 +1,64 @@
2566+//
2567+// ArtistsViewController.m
2568+// U1Music
2569+//
2570+// Created by Paul Hummer on 11/15/12.
2571+// Copyright (c) 2012 Canonical. All rights reserved.
2572+//
2573+
2574+#import "ArtistsViewController.h"
2575+#import <RestKit/RestKit.h>
2576+#import "NSString+Extras.h"
2577+
2578+#import "Artist.h"
2579+#import "ArtistCell.h"
2580+
2581+#import "UONetworkStatusCoordinator.h"
2582+#import "ArtistViewController.h"
2583+#import "UOWebServiceController.h"
2584+
2585+@interface ArtistsViewController ()
2586+@end
2587+
2588+@implementation ArtistsViewController
2589+
2590+#pragma mark - UOIndexedViewController methods
2591+
2592+- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
2593+ Artist *artist = [self.fetchedResultsController objectAtIndexPath:indexPath];
2594+ ArtistCell *artistCell = (ArtistCell *)cell;
2595+
2596+ [artistCell setArtist:artist];
2597+}
2598+
2599+- (NSString *)entityName {
2600+ return @"Artist";
2601+}
2602+
2603+- (NSString *)lastUpdatedKey {
2604+return ARTISTS_LAST_UPDATED;
2605+}
2606+
2607+- (NSArray *)sortDescriptors {
2608+ return [NSArray arrayWithObjects:
2609+ [[NSSortDescriptor alloc] initWithKey:@"dearticlizedName" ascending:YES],
2610+ nil];
2611+}
2612+
2613+- (void)update {
2614+ [[UOWebServiceController controller] updateArtists:self];
2615+}
2616+
2617+#pragma mark - Storyboard methods
2618+
2619+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
2620+ if (![sender respondsToSelector:@selector(artist)]) {
2621+ return; // Hit 'Now Playing'
2622+ }
2623+
2624+ ArtistViewController *artistViewController = [segue destinationViewController];
2625+ Artist *artist = ((ArtistCell *)sender).artist;
2626+ artistViewController.artistId = artist.artistId;
2627+}
2628+
2629+@end
2630
2631=== added file 'Music/View Controllers/PlayerViewController.h'
2632--- Music/View Controllers/PlayerViewController.h 1970-01-01 00:00:00 +0000
2633+++ Music/View Controllers/PlayerViewController.h 2013-01-24 17:06:42 +0000
2634@@ -0,0 +1,31 @@
2635+//
2636+// PlayerViewController.h
2637+// U1Music
2638+//
2639+// Created by Paul Hummer on 1/14/13.
2640+// Copyright (c) 2013 Canonical. All rights reserved.
2641+//
2642+
2643+#import <UIKit/UIKit.h>
2644+
2645+@interface PlayerViewController : UIViewController
2646+
2647+
2648+@property (weak, nonatomic) IBOutlet UIToolbar *controlBar;
2649+
2650+@property (weak, nonatomic) IBOutlet UIButton *albumart;
2651+@property (weak, nonatomic) IBOutlet UIBarButtonItem *previousButton;
2652+@property (strong, nonatomic) IBOutlet UIBarButtonItem *playButton;
2653+@property (strong, nonatomic) IBOutlet UIBarButtonItem *pauseButton;
2654+@property (weak, nonatomic) IBOutlet UIBarButtonItem *nextButton;
2655+
2656+- (IBAction)hide:(id)sender;
2657+
2658+- (IBAction)previous:(id)sender;
2659+- (IBAction)play:(id)sender;
2660+- (IBAction)pause:(id)sender;
2661+- (IBAction)next:(id)sender;
2662+
2663+@property (weak, nonatomic) IBOutlet UILabel *artistLabel;
2664+@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
2665+@end
2666
2667=== added file 'Music/View Controllers/PlayerViewController.m'
2668--- Music/View Controllers/PlayerViewController.m 1970-01-01 00:00:00 +0000
2669+++ Music/View Controllers/PlayerViewController.m 2013-01-24 17:06:42 +0000
2670@@ -0,0 +1,118 @@
2671+//
2672+// PlayerViewController.m
2673+// U1Music
2674+//
2675+// Created by Paul Hummer on 1/14/13.
2676+// Copyright (c) 2013 Canonical. All rights reserved.
2677+//
2678+
2679+#import "PlayerViewController.h"
2680+#import "Song.h"
2681+#import "Artist.h"
2682+#import "Album.h"
2683+
2684+#import "StreamingPlayer.h"
2685+
2686+@interface PlayerViewController ()
2687+
2688+@end
2689+
2690+@implementation PlayerViewController
2691+
2692+- (void)viewDidLoad {
2693+ [super viewDidLoad];
2694+ NSMutableArray *controlItems = [[self.controlBar items] mutableCopy];
2695+ [controlItems removeObjectAtIndex:[controlItems indexOfObject:self.pauseButton]];
2696+ [self.controlBar setItems:controlItems];
2697+}
2698+
2699+- (void)viewWillAppear:(BOOL)animated {
2700+ [super viewWillAppear:animated];
2701+ [[StreamingPlayer sharedStreamingPlayer] addObserver:self forKeyPath:@"currentSong" options:0 context:NULL];
2702+ [[StreamingPlayer sharedStreamingPlayer] addObserver:self forKeyPath:@"isPlaying" options:0 context:NULL];
2703+
2704+ [self updatePlayPause];
2705+ [self updateCurrentSong];
2706+}
2707+
2708+- (void)viewWillDisappear:(BOOL)animated {
2709+ [super viewWillDisappear:animated];
2710+
2711+ [[StreamingPlayer sharedStreamingPlayer] removeObserver:self forKeyPath:@"currentSong"];
2712+ [[StreamingPlayer sharedStreamingPlayer] removeObserver:self forKeyPath:@"isPlaying"];
2713+}
2714+
2715+- (void)viewDidUnload {
2716+ [self setAlbumart:nil];
2717+ [self setPreviousButton:nil];
2718+ [self setPlayButton:nil];
2719+ [self setPauseButton:nil];
2720+ [self setNextButton:nil];
2721+ [self setControlBar:nil];
2722+ [self setArtistLabel:nil];
2723+ [self setTitleLabel:nil];
2724+ [super viewDidUnload];
2725+}
2726+
2727+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
2728+ if ([keyPath isEqual:@"currentSong"]) {
2729+ [self updateCurrentSong];
2730+ } else if ([keyPath isEqual:@"isPlaying"]) {
2731+ [self updatePlayPause];
2732+ }
2733+}
2734+
2735+#pragma mark - IBAction methods
2736+
2737+- (IBAction)hide:(id)sender {
2738+ [self dismissModalViewControllerAnimated:YES];
2739+}
2740+
2741+- (IBAction)previous:(id)sender {
2742+ [[StreamingPlayer sharedStreamingPlayer] prevSong];
2743+}
2744+
2745+- (IBAction)play:(id)sender {
2746+ [[StreamingPlayer sharedStreamingPlayer] playPauseSong];
2747+ [self updatePlayPause];
2748+}
2749+
2750+- (IBAction)next:(id)sender {
2751+ [[StreamingPlayer sharedStreamingPlayer] nextSong];
2752+}
2753+
2754+- (IBAction)pause:(id)sender {
2755+ [[StreamingPlayer sharedStreamingPlayer] playPauseSong];
2756+ [self updatePlayPause];
2757+}
2758+
2759+#pragma mark - Private methods
2760+
2761+- (void)updatePlayPause {
2762+ NSMutableArray *controlItems = [[self.controlBar items] mutableCopy];
2763+ if ([[StreamingPlayer sharedStreamingPlayer] isPlaying]) {
2764+ if ([controlItems containsObject:self.playButton]) {
2765+ NSInteger index = [controlItems indexOfObject:self.playButton];
2766+ [controlItems removeObjectAtIndex:index];
2767+ [controlItems insertObject:self.pauseButton atIndex:index];
2768+ [self.controlBar setItems:controlItems];
2769+ }
2770+ } else {
2771+ if ([controlItems containsObject:self.pauseButton]) {
2772+ NSInteger index = [controlItems indexOfObject:self.pauseButton];
2773+ [controlItems removeObjectAtIndex:index];
2774+ [controlItems insertObject:self.playButton atIndex:index];
2775+ [self.controlBar setItems:controlItems];
2776+ }
2777+ }
2778+}
2779+
2780+- (void)updateCurrentSong {
2781+ Song *song = [StreamingPlayer sharedStreamingPlayer].currentSong;
2782+ [self.artistLabel setText:song.artist.name];
2783+ [self.titleLabel setText:song.title];
2784+
2785+ [self.albumart setImage:song.art forState:UIControlStateNormal];
2786+}
2787+
2788+@end
2789
2790=== added file 'Music/View Controllers/PlaylistsViewController.h'
2791--- Music/View Controllers/PlaylistsViewController.h 1970-01-01 00:00:00 +0000
2792+++ Music/View Controllers/PlaylistsViewController.h 2013-01-24 17:06:42 +0000
2793@@ -0,0 +1,12 @@
2794+//
2795+// PlaylistsViewController.h
2796+// U1Music
2797+//
2798+// Created by Paul Hummer on 11/15/12.
2799+// Copyright (c) 2012 Canonical. All rights reserved.
2800+//
2801+
2802+#import "UOIndexedViewController.h"
2803+
2804+@interface PlaylistsViewController : UOIndexedViewController
2805+@end
2806
2807=== added file 'Music/View Controllers/PlaylistsViewController.m'
2808--- Music/View Controllers/PlaylistsViewController.m 1970-01-01 00:00:00 +0000
2809+++ Music/View Controllers/PlaylistsViewController.m 2013-01-24 17:06:42 +0000
2810@@ -0,0 +1,48 @@
2811+//
2812+// PlaylistsViewController.m
2813+// U1Music
2814+//
2815+// Created by Paul Hummer on 11/15/12.
2816+// Copyright (c) 2012 Canonical. All rights reserved.
2817+//
2818+
2819+#import "PlaylistsViewController.h"
2820+#import "UONetworkStatusCoordinator.h"
2821+#import "Playlist.h"
2822+#import "PlaylistCell.h"
2823+#import "NSString+Extras.h"
2824+#import "UOWebServiceController.h"
2825+
2826+@interface PlaylistsViewController ()
2827+
2828+@end
2829+
2830+@implementation PlaylistsViewController
2831+
2832+#pragma mark - UOIndexedViewController methods
2833+
2834+- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
2835+ PlaylistCell *playlistCell = (PlaylistCell *)cell;
2836+ Playlist *playlist = [self.fetchedResultsController objectAtIndexPath:indexPath];
2837+ [playlistCell setPlaylist:playlist];
2838+}
2839+
2840+- (NSString *)entityName {
2841+ return @"Playlist";
2842+}
2843+
2844+- (NSString *)lastUpdatedKey {
2845+ return PLAYLISTS_LAST_UPDATED;
2846+}
2847+
2848+- (NSArray *)sortDescriptors {
2849+ return [NSArray arrayWithObjects:
2850+ [[NSSortDescriptor alloc] initWithKey:@"dearticlizedTitle" ascending:YES],
2851+ nil];
2852+}
2853+
2854+- (void)update {
2855+ [[UOWebServiceController controller] updatePlaylists:self];
2856+}
2857+
2858+@end
2859
2860=== added file 'Music/View Controllers/SettingsAboutViewController.h'
2861--- Music/View Controllers/SettingsAboutViewController.h 1970-01-01 00:00:00 +0000
2862+++ Music/View Controllers/SettingsAboutViewController.h 2013-01-24 17:06:42 +0000
2863@@ -0,0 +1,13 @@
2864+//
2865+// SettingsAboutViewController.h
2866+// U1Music
2867+//
2868+// Created by Paul Hummer on 11/16/12.
2869+// Copyright (c) 2012 Canonical. All rights reserved.
2870+//
2871+
2872+#import <UIKit/UIKit.h>
2873+
2874+@interface SettingsAboutViewController : UIViewController
2875+
2876+@end
2877
2878=== added file 'Music/View Controllers/SettingsAboutViewController.m'
2879--- Music/View Controllers/SettingsAboutViewController.m 1970-01-01 00:00:00 +0000
2880+++ Music/View Controllers/SettingsAboutViewController.m 2013-01-24 17:06:42 +0000
2881@@ -0,0 +1,42 @@
2882+//
2883+// SettingsAboutViewController.m
2884+// U1Music
2885+//
2886+// Created by Paul Hummer on 11/16/12.
2887+// Copyright (c) 2012 Canonical. All rights reserved.
2888+//
2889+
2890+#import "SettingsAboutViewController.h"
2891+
2892+@interface SettingsAboutViewController ()
2893+- (IBAction)close:(id)sender;
2894+
2895+@end
2896+
2897+@implementation SettingsAboutViewController
2898+
2899+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
2900+{
2901+ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
2902+ if (self) {
2903+ // Custom initialization
2904+ }
2905+ return self;
2906+}
2907+
2908+- (void)viewDidLoad
2909+{
2910+ [super viewDidLoad];
2911+ // Do any additional setup after loading the view.
2912+}
2913+
2914+- (void)didReceiveMemoryWarning
2915+{
2916+ [super didReceiveMemoryWarning];
2917+ // Dispose of any resources that can be recreated.
2918+}
2919+
2920+- (IBAction)close:(id)sender {
2921+ [self dismissModalViewControllerAnimated:YES];
2922+}
2923+@end
2924
2925=== added file 'Music/View Controllers/SettingsAuthenticationViewController.h'
2926--- Music/View Controllers/SettingsAuthenticationViewController.h 1970-01-01 00:00:00 +0000
2927+++ Music/View Controllers/SettingsAuthenticationViewController.h 2013-01-24 17:06:42 +0000
2928@@ -0,0 +1,13 @@
2929+//
2930+// SettingsAuthenticationViewController.h
2931+// U1Music
2932+//
2933+// Created by Paul Hummer on 11/16/12.
2934+// Copyright (c) 2012 Canonical. All rights reserved.
2935+//
2936+
2937+#import <UIKit/UIKit.h>
2938+
2939+@interface SettingsAuthenticationViewController : UIViewController
2940+
2941+@end
2942
2943=== added file 'Music/View Controllers/SettingsAuthenticationViewController.m'
2944--- Music/View Controllers/SettingsAuthenticationViewController.m 1970-01-01 00:00:00 +0000
2945+++ Music/View Controllers/SettingsAuthenticationViewController.m 2013-01-24 17:06:42 +0000
2946@@ -0,0 +1,117 @@
2947+//
2948+// SettingsAuthenticationViewController.m
2949+// U1Music
2950+//
2951+// Created by Paul Hummer on 11/16/12.
2952+// Copyright (c) 2012 Canonical. All rights reserved.
2953+//
2954+
2955+#import "SettingsAuthenticationViewController.h"
2956+#import "UOAuthManager.h"
2957+#import "Subsonic.h"
2958+
2959+@interface SettingsAuthenticationViewController () <UOAuthManagerDelegate>
2960+@property (weak, nonatomic) IBOutlet UITextField *usernameField;
2961+@property (weak, nonatomic) IBOutlet UITextField *passwordField;
2962+
2963+/* XXX: rockstar - spinner should really be a childe of shade. */
2964+@property (weak, nonatomic) IBOutlet UIView *shade;
2965+@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *spinner;
2966+
2967+- (IBAction)authenticate:(id)sender;
2968+@end
2969+
2970+@implementation SettingsAuthenticationViewController
2971+@synthesize usernameField = _usernameField;
2972+@synthesize passwordField = _passwordField;
2973+
2974+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
2975+{
2976+ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
2977+ if (self) {
2978+ // Custom initialization
2979+ }
2980+ return self;
2981+}
2982+
2983+- (void)viewDidLoad
2984+{
2985+ [super viewDidLoad];
2986+ // Do any additional setup after loading the view.
2987+}
2988+
2989+- (void)didReceiveMemoryWarning
2990+{
2991+ [super didReceiveMemoryWarning];
2992+ // Dispose of any resources that can be recreated.
2993+}
2994+
2995+- (void)viewDidUnload {
2996+ [self setUsernameField:nil];
2997+ [self setPasswordField:nil];
2998+ [self setShade:nil];
2999+ [self setSpinner:nil];
3000+ [super viewDidUnload];
3001+}
3002+
3003+#pragma mark - Actions
3004+
3005+- (IBAction)authenticate:(id)sender {
3006+ NSString *username = _usernameField.text;
3007+ NSString *password = _passwordField.text;
3008+
3009+ [self.view endEditing:YES];
3010+
3011+ [self.shade setHidden:NO];
3012+ [self.spinner setHidden:NO];
3013+
3014+ NSString *tokenName = [NSString stringWithFormat:@"Ubuntu One @ %@", [[UIDevice currentDevice] name]];
3015+ [[UOAuthManager sharedAuthManager] loginWithUsername:username andPassword:password tokenName:tokenName delegate:self];
3016+}
3017+
3018+#pragma mark - UOAuthManagerDelegate methods
3019+
3020+- (void)authenticationSuccess {
3021+ /* XXX: rockstar - As soon as we no longer use Subsonic credentials for streaming, this can be dropped/simplified. */
3022+ id subsonicCompletionBlock = ^(NSString *username) {
3023+ [[Subsonic sharedSubsonic] setDefaultUserName:[[UOAuthManager sharedAuthManager] subsonicUsername]];
3024+ [[Subsonic sharedSubsonic] setDefaultPassword:[[UOAuthManager sharedAuthManager] subsonicPassword]];
3025+
3026+ [self.shade setHidden:YES];
3027+ [self.spinner setHidden:YES];
3028+
3029+ [self dismissModalViewControllerAnimated:YES];
3030+ };
3031+ id subsonicErrorBlock = ^(NSError *error) {
3032+ NSLog(@"Could not retrieve subsonic credentials");
3033+ };
3034+ [[UOAuthManager sharedAuthManager] fetchSubsonicCredentials:subsonicCompletionBlock errorBlock:subsonicErrorBlock];
3035+}
3036+
3037+-(void)authenticationError:(NSError *)error {
3038+ if (error.code == 401) {
3039+ [_passwordField setText:@""];
3040+ [self showAlert:@"Invalid username and password"];
3041+ } else if (error.code == 0) {
3042+ /* XXX: rockstar - This is too clever. It should really only retry once or twice. */
3043+ [self authenticate:nil];
3044+ } else {
3045+ [self showAlert:@"An error has ocurred. Please try again."];
3046+ }
3047+
3048+ [self.shade setHidden:YES];
3049+ [self.spinner setHidden:YES];
3050+}
3051+
3052+#pragma mark - Private methods
3053+
3054+- (void)showAlert:(NSString *)message {
3055+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error logging in"
3056+ message:message
3057+ delegate:nil
3058+ cancelButtonTitle:@"OK"
3059+ otherButtonTitles:nil];
3060+ [alert show];
3061+}
3062+
3063+@end
3064
3065=== added file 'Music/View Controllers/SettingsViewController.h'
3066--- Music/View Controllers/SettingsViewController.h 1970-01-01 00:00:00 +0000
3067+++ Music/View Controllers/SettingsViewController.h 2013-01-24 17:06:42 +0000
3068@@ -0,0 +1,13 @@
3069+//
3070+// SettingsViewController.h
3071+// U1Music
3072+//
3073+// Created by Paul Hummer on 11/15/12.
3074+// Copyright (c) 2012 Canonical. All rights reserved.
3075+//
3076+
3077+#import <UIKit/UIKit.h>
3078+
3079+@interface SettingsViewController : UIViewController
3080+
3081+@end
3082
3083=== added file 'Music/View Controllers/SettingsViewController.m'
3084--- Music/View Controllers/SettingsViewController.m 1970-01-01 00:00:00 +0000
3085+++ Music/View Controllers/SettingsViewController.m 2013-01-24 17:06:42 +0000
3086@@ -0,0 +1,60 @@
3087+//
3088+// SettingsViewController.m
3089+// U1Music
3090+//
3091+// Created by Paul Hummer on 11/15/12.
3092+// Copyright (c) 2012 Canonical. All rights reserved.
3093+//
3094+
3095+#import "SettingsViewController.h"
3096+#import "UOAuthManager.h"
3097+
3098+@interface SettingsViewController ()
3099+- (IBAction)deleteCredentials:(id)sender;
3100+
3101+@end
3102+
3103+@implementation SettingsViewController
3104+
3105+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
3106+{
3107+ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
3108+ if (self) {
3109+ // Custom initialization
3110+ }
3111+ return self;
3112+}
3113+
3114+- (void)viewDidLoad
3115+{
3116+ [super viewDidLoad];
3117+ // Do any additional setup after loading the view.
3118+}
3119+
3120+- (void)viewDidAppear:(BOOL)animated {
3121+ [super viewDidAppear:animated];
3122+ [self checkAuthentication];
3123+}
3124+
3125+- (void)didReceiveMemoryWarning
3126+{
3127+ [super didReceiveMemoryWarning];
3128+ // Dispose of any resources that can be recreated.
3129+}
3130+
3131+#pragma mark - Actions
3132+
3133+- (IBAction)deleteCredentials:(id)sender {
3134+ [[UOAuthManager sharedAuthManager] logout];
3135+ [self checkAuthentication];
3136+}
3137+
3138+#pragma mark - Private methods
3139+
3140+- (void)checkAuthentication {
3141+ if (![[UOAuthManager sharedAuthManager] hasCredentials]) {
3142+ [self performSegueWithIdentifier:@"AuthenticationSegue" sender:self];
3143+ }
3144+}
3145+
3146+@end
3147
3148=== added file 'Music/View Controllers/SongsViewController.h'
3149--- Music/View Controllers/SongsViewController.h 1970-01-01 00:00:00 +0000
3150+++ Music/View Controllers/SongsViewController.h 2013-01-24 17:06:42 +0000
3151@@ -0,0 +1,12 @@
3152+//
3153+// SongsViewController.h
3154+// U1Music
3155+//
3156+// Created by Paul Hummer on 11/15/12.
3157+// Copyright (c) 2012 Canonical. All rights reserved.
3158+//
3159+
3160+#import "UOIndexedViewController.h"
3161+
3162+@interface SongsViewController : UOIndexedViewController
3163+@end
3164
3165=== added file 'Music/View Controllers/SongsViewController.m'
3166--- Music/View Controllers/SongsViewController.m 1970-01-01 00:00:00 +0000
3167+++ Music/View Controllers/SongsViewController.m 2013-01-24 17:06:42 +0000
3168@@ -0,0 +1,70 @@
3169+//
3170+// SongsViewController.m
3171+// U1Music
3172+//
3173+// Created by Paul Hummer on 11/15/12.
3174+// Copyright (c) 2012 Canonical. All rights reserved.
3175+//
3176+
3177+#import "SongsViewController.h"
3178+#import "UONetworkStatusCoordinator.h"
3179+#import "Song.h"
3180+#import "SongCell.h"
3181+#import "NSString+Extras.h"
3182+#import "UOWebServiceController.h"
3183+#import "StreamingPlayer.h"
3184+
3185+@interface SongsViewController ()
3186+
3187+@end
3188+
3189+@implementation SongsViewController
3190+
3191+#pragma mark - UOIndexedViewControllers methods
3192+
3193+- (NSString *)entityName {
3194+ return @"Song";
3195+}
3196+
3197+- (NSString *)lastUpdatedKey {
3198+ return SONGS_LAST_UPDATED;
3199+}
3200+
3201+- (NSArray *)sortDescriptors {
3202+ return [NSArray arrayWithObjects:
3203+ [[NSSortDescriptor alloc] initWithKey:@"dearticlizedTitle" ascending:YES],
3204+ nil];
3205+}
3206+
3207+- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
3208+ SongCell *songCell = (SongCell *)cell;
3209+ Song *song = [self.fetchedResultsController objectAtIndexPath:indexPath];
3210+ [songCell setSong:song];
3211+}
3212+
3213+- (void)viewWillAppear:(BOOL)animated {
3214+ [super viewWillAppear:animated];
3215+ [[UOWebServiceController controller] updateSongs:self];
3216+}
3217+
3218+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
3219+ if (![sender respondsToSelector:@selector(song)]) {
3220+ return; // Hit 'Now Playing'
3221+ }
3222+
3223+ NSArray *songs = [[self.fetchedResultsController fetchedObjects] copy];
3224+ Song *song = ((SongCell *)sender).song;
3225+
3226+ StreamingPlayer *player = [StreamingPlayer sharedStreamingPlayer];
3227+ player.currentSong = song;
3228+ player.currentPlaylist = songs;
3229+ player.isNewSong = YES;
3230+ player.isShuffle = NO;
3231+
3232+ if (player.streamer) {
3233+ [player.streamer stop];
3234+ }
3235+ [player playPauseSong];
3236+}
3237+
3238+@end
3239
3240=== added file 'Music/View Controllers/UOIndexedViewController.h'
3241--- Music/View Controllers/UOIndexedViewController.h 1970-01-01 00:00:00 +0000
3242+++ Music/View Controllers/UOIndexedViewController.h 2013-01-24 17:06:42 +0000
3243@@ -0,0 +1,31 @@
3244+//
3245+// UOIndexedViewController.h
3246+// U1Music
3247+//
3248+// Created by Paul Hummer on 11/17/12.
3249+// Copyright (c) 2012 Canonical. All rights reserved.
3250+//
3251+
3252+#import <UIKit/UIKit.h>
3253+#import <RestKit/RestKit.h>
3254+#import "UOWebServiceController.h"
3255+
3256+@interface UOIndexedViewController : UITableViewController <NSFetchedResultsControllerDelegate,UOWebServiceDelegate> {
3257+ NSMutableDictionary *groupedTableData;
3258+ NSArray *indexes;
3259+ BOOL indexed;
3260+
3261+ NSArray *tableData;
3262+}
3263+@property (readonly, nonatomic) NSString *endpoint;
3264+@property (readonly, nonatomic) NSString *entityName;
3265+@property (readonly, nonatomic) NSString *sectionNameKeyPath;
3266+@property (readonly, nonatomic) NSString *lastUpdatedKey;
3267+@property (readonly, nonatomic) NSArray *sortDescriptors;
3268+- (void)update;
3269+- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath;
3270+
3271+- (NSFetchedResultsController *)fetchedResultsController;
3272+
3273+@property (strong, nonatomic) IBOutlet UIBarButtonItem *nowPlayingButton;
3274+@end
3275
3276=== added file 'Music/View Controllers/UOIndexedViewController.m'
3277--- Music/View Controllers/UOIndexedViewController.m 1970-01-01 00:00:00 +0000
3278+++ Music/View Controllers/UOIndexedViewController.m 2013-01-24 17:06:42 +0000
3279@@ -0,0 +1,169 @@
3280+//
3281+// UOIndexedViewController.m
3282+// U1Music
3283+//
3284+// Created by Paul Hummer on 11/17/12.
3285+// Copyright (c) 2012 Canonical. All rights reserved.
3286+//
3287+
3288+#import "UOIndexedViewController.h"
3289+#import <RestKit/RestKit.h>
3290+#import "UOAppDelegate.h"
3291+#import "StreamingPlayer.h"
3292+
3293+@interface UOIndexedViewController () {
3294+ NSFetchedResultsController *_fetchedResultsController;
3295+}
3296+
3297+@end
3298+
3299+@implementation UOIndexedViewController
3300+
3301+#pragma mark - Abstract methods
3302+
3303+- (NSString *)endpoint {
3304+ return @"/";
3305+}
3306+
3307+- (NSString *)entityName {
3308+ return nil;
3309+}
3310+
3311+- (NSArray *)sortDescriptors {
3312+ return [NSArray array];
3313+}
3314+
3315+- (NSString *)sectionNameKeyPath {
3316+ return @"index";
3317+}
3318+
3319+- (NSString *)lastUpdatedKey {
3320+ return nil;
3321+}
3322+
3323+- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
3324+ return;
3325+}
3326+
3327+- (void)update {
3328+}
3329+
3330+#pragma mark - UIViewController lifecycle
3331+
3332+- (void)viewDidLoad {
3333+ [super viewDidLoad];
3334+ groupedTableData = [NSMutableDictionary dictionary];
3335+}
3336+
3337+- (void)viewWillAppear:(BOOL)animated {
3338+ [super viewWillAppear:animated];
3339+ [self update];
3340+
3341+ if (![[StreamingPlayer sharedStreamingPlayer] currentSong]) {
3342+ self.navigationItem.rightBarButtonItem = nil;
3343+ } else {
3344+ self.navigationItem.rightBarButtonItem = self.nowPlayingButton;
3345+ }
3346+}
3347+
3348+- (void)didReceiveMemoryWarning
3349+{
3350+ [super didReceiveMemoryWarning];
3351+ // Dispose of any resources that can be recreated.
3352+}
3353+
3354+#pragma mark - Table view data source
3355+
3356+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
3357+ return [[self.fetchedResultsController sections] count];
3358+}
3359+
3360+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
3361+ id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
3362+ return [sectionInfo numberOfObjects];
3363+}
3364+
3365+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
3366+ id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
3367+ return [sectionInfo name];
3368+}
3369+
3370+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
3371+ static NSString *CellIdentifier = @"Cell";
3372+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
3373+
3374+ [self configureCell:cell forIndexPath:indexPath];
3375+ return cell;
3376+}
3377+
3378+- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
3379+ return [self.fetchedResultsController sectionIndexTitles];
3380+}
3381+
3382+#pragma mark - UOWebServiceDelegate methods
3383+
3384+- (void)webserviceUpdateComplete {
3385+ _fetchedResultsController = nil;
3386+ [self.tableView reloadData];
3387+}
3388+
3389+- (void)webserviceUpdateError:(NSError *)error {
3390+ if ([error code] == 2) { // Network is down.
3391+ return;
3392+ }
3393+ NSLog(@"Error: %@", [error localizedDescription]);
3394+}
3395+
3396+#pragma mark - RKObjectLoaderDelegate methods
3397+/*
3398+- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
3399+ [UONetworkStatusCoordinator removeNetworkActivity];
3400+ if ([error code] == 2) { // Network is down.
3401+ return;
3402+ }
3403+ NSLog(@"Error: %@", [error localizedDescription]);
3404+ [[NSUserDefaults standardUserDefaults] setObject:nil forKey:[self lastUpdatedKey]];
3405+}
3406+
3407+- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
3408+ [UONetworkStatusCoordinator removeNetworkActivity];
3409+ _fetchedResultsController = nil;
3410+ [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:[self lastUpdatedKey]];
3411+ [self.tableView reloadData];
3412+}
3413+ */
3414+
3415+#pragma mark - Fetched results controller
3416+
3417+- (NSFetchedResultsController *)fetchedResultsController {
3418+ if (_fetchedResultsController) {
3419+ return _fetchedResultsController;
3420+ }
3421+
3422+ NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[self entityName]];
3423+ [fetchRequest setFetchBatchSize:20];
3424+ [fetchRequest setSortDescriptors:[self sortDescriptors]];
3425+
3426+ _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
3427+ managedObjectContext:[[UOAppDelegate delegate] managedObjectContext]
3428+ sectionNameKeyPath:[self sectionNameKeyPath]
3429+ cacheName:nil];
3430+ _fetchedResultsController.delegate = self;
3431+
3432+ NSError *error = nil;
3433+ if (![_fetchedResultsController performFetch:&error]) {
3434+ if ([error code] == 134060) {
3435+ NSLog(@"The database model is stale. Please delete the app and re-install");
3436+ } else {
3437+ NSLog(@"OHNO: %@", [error localizedDescription]);
3438+ }
3439+ }
3440+
3441+ return _fetchedResultsController;
3442+}
3443+
3444+- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
3445+ [self.tableView reloadData];
3446+}
3447+
3448+@end
3449
3450=== added directory 'Music/Views'
3451=== added file 'Music/Views/PlayerHeaderView.h'
3452--- Music/Views/PlayerHeaderView.h 1970-01-01 00:00:00 +0000
3453+++ Music/Views/PlayerHeaderView.h 2013-01-24 17:06:42 +0000
3454@@ -0,0 +1,21 @@
3455+//
3456+// PlayerHeaderView.h
3457+// U1Music
3458+//
3459+// Created by Paul Hummer on 1/14/13.
3460+// Copyright (c) 2013 Canonical. All rights reserved.
3461+//
3462+
3463+#import <UIKit/UIKit.h>
3464+
3465+@interface PlayerHeaderView : UIView
3466+
3467+@property(nonatomic,retain) IBOutlet UILabel *artist;
3468+@property(nonatomic,retain) IBOutlet UILabel *title;
3469+@property(nonatomic,retain) IBOutlet UILabel *album;
3470+
3471+- (void)setArtistName:(NSString *)artistName;
3472+- (void)setTitleName:(NSString *)titleName;
3473+- (void)setAlbumName:(NSString *)albumName;
3474+
3475+@end
3476
3477=== added file 'Music/Views/PlayerHeaderView.m'
3478--- Music/Views/PlayerHeaderView.m 1970-01-01 00:00:00 +0000
3479+++ Music/Views/PlayerHeaderView.m 2013-01-24 17:06:42 +0000
3480@@ -0,0 +1,25 @@
3481+//
3482+// PlayerHeaderView.m
3483+// U1Music
3484+//
3485+// Created by Paul Hummer on 1/14/13.
3486+// Copyright (c) 2013 Canonical. All rights reserved.
3487+//
3488+
3489+#import "PlayerHeaderView.h"
3490+
3491+@implementation PlayerHeaderView
3492+
3493+- (void)setArtistName:(NSString *)artistName {
3494+ self.artist.text = artistName;
3495+}
3496+
3497+- (void)setTitleName:(NSString *)titleName {
3498+ self.title.text = titleName;
3499+}
3500+
3501+- (void)setAlbumName:(NSString *)albumName {
3502+ self.album.text = albumName;
3503+}
3504+
3505+@end
3506
3507=== added directory 'Music/Views/Table Cells'
3508=== added file 'Music/Views/Table Cells/AlbumCell.h'
3509--- Music/Views/Table Cells/AlbumCell.h 1970-01-01 00:00:00 +0000
3510+++ Music/Views/Table Cells/AlbumCell.h 2013-01-24 17:06:42 +0000
3511@@ -0,0 +1,14 @@
3512+//
3513+// AlbumCell.h
3514+// U1Music
3515+//
3516+// Created by Paul Hummer on 11/17/12.
3517+// Copyright (c) 2012 Canonical. All rights reserved.
3518+//
3519+
3520+#import <UIKit/UIKit.h>
3521+#import "Album.h"
3522+
3523+@interface AlbumCell : UITableViewCell
3524+@property (nonatomic, retain) Album *album;
3525+@end
3526
3527=== added file 'Music/Views/Table Cells/AlbumCell.m'
3528--- Music/Views/Table Cells/AlbumCell.m 1970-01-01 00:00:00 +0000
3529+++ Music/Views/Table Cells/AlbumCell.m 2013-01-24 17:06:42 +0000
3530@@ -0,0 +1,32 @@
3531+//
3532+// AlbumCell.m
3533+// U1Music
3534+//
3535+// Created by Paul Hummer on 11/17/12.
3536+// Copyright (c) 2012 Canonical. All rights reserved.
3537+//
3538+
3539+#import "AlbumCell.h"
3540+
3541+@implementation AlbumCell
3542+@synthesize album = _album;
3543+
3544+- (void)setAlbum:(Album *)album {
3545+ _album = album;
3546+
3547+ if (!album.art) {
3548+ [self.imageView setImage:[UIImage imageNamed:@"default-album-art-120.png"]];
3549+ [album fetchArt:^(UIImage *image) {
3550+ [self.imageView setImage:image];
3551+ [self setNeedsDisplay];
3552+ }];
3553+ } else {
3554+ [self.imageView setImage:album.art];
3555+ }
3556+
3557+ [self.textLabel setText:album.title];
3558+
3559+ [self.detailTextLabel setText:album.artist.name];
3560+}
3561+
3562+@end
3563
3564=== added file 'Music/Views/Table Cells/ArtistCell.h'
3565--- Music/Views/Table Cells/ArtistCell.h 1970-01-01 00:00:00 +0000
3566+++ Music/Views/Table Cells/ArtistCell.h 2013-01-24 17:06:42 +0000
3567@@ -0,0 +1,14 @@
3568+//
3569+// ArtistCell.h
3570+// U1Music
3571+//
3572+// Created by Paul Hummer on 11/16/12.
3573+// Copyright (c) 2012 Canonical. All rights reserved.
3574+//
3575+
3576+#import <UIKit/UIKit.h>
3577+#import "Artist.h"
3578+
3579+@interface ArtistCell : UITableViewCell
3580+@property (nonatomic, retain) Artist *artist;
3581+@end
3582
3583=== added file 'Music/Views/Table Cells/ArtistCell.m'
3584--- Music/Views/Table Cells/ArtistCell.m 1970-01-01 00:00:00 +0000
3585+++ Music/Views/Table Cells/ArtistCell.m 2013-01-24 17:06:42 +0000
3586@@ -0,0 +1,37 @@
3587+//
3588+// ArtistCell.m
3589+// U1Music
3590+//
3591+// Created by Paul Hummer on 11/16/12.
3592+// Copyright (c) 2012 Canonical. All rights reserved.
3593+//
3594+
3595+#import "ArtistCell.h"
3596+
3597+@implementation ArtistCell
3598+@synthesize artist = _artist;
3599+
3600+- (void)setArtist:(Artist *)artist {
3601+ _artist = artist;
3602+
3603+ if (!artist.art) {
3604+ [self.imageView setImage:[UIImage imageNamed:@"default-album-art-120.png"]];
3605+ [artist fetchArt:^(UIImage *image) {
3606+ [self.imageView setImage:image];
3607+ [self setNeedsDisplay];
3608+ }];
3609+ } else {
3610+ [self.imageView setImage:artist.art];
3611+ }
3612+
3613+ [self.textLabel setText:artist.name];
3614+ if ([artist.albums count] > 0) {
3615+ NSString *pluralizedNoun = @"albums";
3616+ if ([artist.albums count] == 1) {
3617+ pluralizedNoun = @"album";
3618+ }
3619+ [self.detailTextLabel setText:[NSString stringWithFormat:@"%d %@", [artist.albums count], pluralizedNoun]];
3620+ }
3621+}
3622+
3623+@end
3624
3625=== added file 'Music/Views/Table Cells/PlaylistCell.h'
3626--- Music/Views/Table Cells/PlaylistCell.h 1970-01-01 00:00:00 +0000
3627+++ Music/Views/Table Cells/PlaylistCell.h 2013-01-24 17:06:42 +0000
3628@@ -0,0 +1,14 @@
3629+//
3630+// PlaylistCell.h
3631+// U1Music
3632+//
3633+// Created by Paul Hummer on 11/17/12.
3634+// Copyright (c) 2012 Canonical. All rights reserved.
3635+//
3636+
3637+#import <UIKit/UIKit.h>
3638+#import "Playlist.h"
3639+
3640+@interface PlaylistCell : UITableViewCell
3641+@property (nonatomic, retain) Playlist *playlist;
3642+@end
3643
3644=== added file 'Music/Views/Table Cells/PlaylistCell.m'
3645--- Music/Views/Table Cells/PlaylistCell.m 1970-01-01 00:00:00 +0000
3646+++ Music/Views/Table Cells/PlaylistCell.m 2013-01-24 17:06:42 +0000
3647@@ -0,0 +1,26 @@
3648+//
3649+// PlaylistCell.m
3650+// U1Music
3651+//
3652+// Created by Paul Hummer on 11/17/12.
3653+// Copyright (c) 2012 Canonical. All rights reserved.
3654+//
3655+
3656+#import "PlaylistCell.h"
3657+
3658+@implementation PlaylistCell
3659+@synthesize playlist = _playlist;
3660+
3661+- (void)setPlaylist:(Playlist *)playlist {
3662+ _playlist = playlist;
3663+
3664+ [self.textLabel setText:playlist.title];
3665+
3666+ NSString *songCountNoun = @"songs";
3667+ if ([playlist.songCount integerValue] == 1) {
3668+ songCountNoun = @"song";
3669+ }
3670+ [self.detailTextLabel setText:[NSString stringWithFormat:@"%@ %@", playlist.songCount, songCountNoun]];
3671+}
3672+
3673+@end
3674
3675=== added file 'Music/Views/Table Cells/SongCell.h'
3676--- Music/Views/Table Cells/SongCell.h 1970-01-01 00:00:00 +0000
3677+++ Music/Views/Table Cells/SongCell.h 2013-01-24 17:06:42 +0000
3678@@ -0,0 +1,14 @@
3679+//
3680+// SongCell.h
3681+// U1Music
3682+//
3683+// Created by Paul Hummer on 11/17/12.
3684+// Copyright (c) 2012 Canonical. All rights reserved.
3685+//
3686+
3687+#import <UIKit/UIKit.h>
3688+#import "Song.h"
3689+
3690+@interface SongCell : UITableViewCell
3691+@property (nonatomic, retain) Song *song;
3692+@end
3693
3694=== added file 'Music/Views/Table Cells/SongCell.m'
3695--- Music/Views/Table Cells/SongCell.m 1970-01-01 00:00:00 +0000
3696+++ Music/Views/Table Cells/SongCell.m 2013-01-24 17:06:42 +0000
3697@@ -0,0 +1,32 @@
3698+//
3699+// SongCell.m
3700+// U1Music
3701+//
3702+// Created by Paul Hummer on 11/17/12.
3703+// Copyright (c) 2012 Canonical. All rights reserved.
3704+//
3705+
3706+#import "SongCell.h"
3707+#import "Artist.h"
3708+
3709+@implementation SongCell
3710+@synthesize song = _song;
3711+
3712+- (void)setSong:(Song *)song {
3713+ _song = song;
3714+
3715+ if (!song.art) {
3716+ [self.imageView setImage:[UIImage imageNamed:@"default-album-art-120.png"]];
3717+ [song fetchArt:^(UIImage *image) {
3718+ [self.imageView setImage:image];
3719+ [self setNeedsDisplay];
3720+ }];
3721+ } else {
3722+ [self.imageView setImage:song.art];
3723+ }
3724+
3725+ [self.textLabel setText:song.title];
3726+ [self.detailTextLabel setText:song.artist.name];
3727+}
3728+
3729+@end
3730
3731=== renamed file 'Other Sources/main.m' => 'Music/main.m'
3732--- Other Sources/main.m 2012-09-15 06:47:35 +0000
3733+++ Music/main.m 2013-01-24 17:06:42 +0000
3734@@ -30,10 +30,10 @@
3735
3736 #import <UIKit/UIKit.h>
3737
3738-#import "U1MusicAppDelegate.h"
3739+#import "UOAppDelegate.h"
3740
3741 int main(int argc, char *argv[]) {
3742 @autoreleasepool {
3743- return UIApplicationMain(argc, argv, nil, NSStringFromClass([U1MusicAppDelegate class]));
3744+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([UOAppDelegate class]));
3745 }
3746 }
3747
3748=== modified file 'U1Music-Info.plist'
3749--- U1Music-Info.plist 2012-08-09 20:06:43 +0000
3750+++ U1Music-Info.plist 2013-01-24 17:06:42 +0000
3751@@ -39,15 +39,15 @@
3752 </dict>
3753 </array>
3754 <key>CFBundleVersion</key>
3755- <string>58</string>
3756+ <string>100</string>
3757 <key>LSRequiresIPhoneOS</key>
3758 <false/>
3759- <key>NSMainNibFile</key>
3760- <string>MainWindow</string>
3761 <key>UIBackgroundModes</key>
3762 <array>
3763 <string>audio</string>
3764 </array>
3765+ <key>UIMainStoryboardFile</key>
3766+ <string>Storyboard_iPhone</string>
3767 <key>UIPrerenderedIcon</key>
3768 <true/>
3769 <key>UIStatusBarStyle</key>
3770
3771=== modified file 'U1Music.xcodeproj/project.pbxproj'
3772--- U1Music.xcodeproj/project.pbxproj 2012-09-25 21:28:26 +0000
3773+++ U1Music.xcodeproj/project.pbxproj 2013-01-24 17:06:42 +0000
3774@@ -26,28 +26,37 @@
3775 523B3CFA15B73BA0004394F4 /* download-grey@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CF615B73BA0004394F4 /* download-grey@2x.png */; };
3776 523B3CFB15B73BA0004394F4 /* download.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CF715B73BA0004394F4 /* download.png */; };
3777 523B3CFC15B73BA0004394F4 /* download@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CF815B73BA0004394F4 /* download@2x.png */; };
3778+ 5268509716AE5267001F65A6 /* libRestKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5268509016AE516C001F65A6 /* libRestKit.a */; };
3779+ 526850A816AEE4E1001F65A6 /* Storyboard_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 526850A516AEE4E1001F65A6 /* Storyboard_iPhone.storyboard */; };
3780+ 526850A916AEE4E1001F65A6 /* UOAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850A716AEE4E1001F65A6 /* UOAppDelegate.m */; };
3781+ 526850AC16AEF9DD001F65A6 /* UOMusic.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 526850AA16AEF9DD001F65A6 /* UOMusic.xcdatamodeld */; };
3782+ 526850C416AEFA59001F65A6 /* AlbumsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850AF16AEFA59001F65A6 /* AlbumsViewController.m */; };
3783+ 526850C516AEFA59001F65A6 /* AlbumViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850B116AEFA59001F65A6 /* AlbumViewController.m */; };
3784+ 526850C616AEFA59001F65A6 /* ArtistsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850B316AEFA59001F65A6 /* ArtistsViewController.m */; };
3785+ 526850C716AEFA59001F65A6 /* ArtistViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850B516AEFA59001F65A6 /* ArtistViewController.m */; };
3786+ 526850C816AEFA59001F65A6 /* PlayerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850B716AEFA59001F65A6 /* PlayerViewController.m */; };
3787+ 526850C916AEFA59001F65A6 /* PlaylistsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850B916AEFA59001F65A6 /* PlaylistsViewController.m */; };
3788+ 526850CA16AEFA59001F65A6 /* SettingsAboutViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850BB16AEFA59001F65A6 /* SettingsAboutViewController.m */; };
3789+ 526850CB16AEFA59001F65A6 /* SettingsAuthenticationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850BD16AEFA59001F65A6 /* SettingsAuthenticationViewController.m */; };
3790+ 526850CC16AEFA59001F65A6 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850BF16AEFA59001F65A6 /* SettingsViewController.m */; };
3791+ 526850CD16AEFA59001F65A6 /* SongsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850C116AEFA59001F65A6 /* SongsViewController.m */; };
3792+ 526850CE16AEFA59001F65A6 /* UOIndexedViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850C316AEFA59001F65A6 /* UOIndexedViewController.m */; };
3793+ 526850DE16AEFA7D001F65A6 /* UOWebServiceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850D116AEFA7C001F65A6 /* UOWebServiceController.m */; };
3794+ 526850DF16AEFA7D001F65A6 /* PlayerHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850D416AEFA7D001F65A6 /* PlayerHeaderView.m */; };
3795+ 526850E016AEFA7D001F65A6 /* AlbumCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850D716AEFA7D001F65A6 /* AlbumCell.m */; };
3796+ 526850E116AEFA7D001F65A6 /* ArtistCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850D916AEFA7D001F65A6 /* ArtistCell.m */; };
3797+ 526850E216AEFA7D001F65A6 /* PlaylistCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850DB16AEFA7D001F65A6 /* PlaylistCell.m */; };
3798+ 526850E316AEFA7D001F65A6 /* SongCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850DD16AEFA7D001F65A6 /* SongCell.m */; };
3799+ 526850FF16AEFC6A001F65A6 /* Album.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850F616AEFC6A001F65A6 /* Album.m */; };
3800+ 5268510016AEFC6A001F65A6 /* Artist.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850F816AEFC6A001F65A6 /* Artist.m */; };
3801+ 5268510116AEFC6A001F65A6 /* Playlist.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850FA16AEFC6A001F65A6 /* Playlist.m */; };
3802+ 5268510216AEFC6A001F65A6 /* Song.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850FC16AEFC6A001F65A6 /* Song.m */; };
3803+ 5268510316AEFC6A001F65A6 /* UOModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 526850FE16AEFC6A001F65A6 /* UOModel.m */; };
3804+ 5268510416AEFCB2001F65A6 /* CachedSongsPlaylist.m in Sources */ = {isa = PBXBuildFile; fileRef = 914AC3F114B61D8A00C7D5A3 /* CachedSongsPlaylist.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3805+ 5268510516AEFCB2001F65A6 /* _U1CachedFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 960E4B3714E5884B002AAB79 /* _U1CachedFile.m */; };
3806+ 5268510616AEFCB2001F65A6 /* U1CachedFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 960E4B3414E58844002AAB79 /* U1CachedFile.m */; };
3807+ 5268510816AEFD20001F65A6 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5268510716AEFD20001F65A6 /* MobileCoreServices.framework */; };
3808 5279764915F00B2600F8435F /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5279764815F00B2600F8435F /* libz.dylib */; };
3809- 528515991604F410004A1F7C /* UbuntuOneAuthKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 528515941604F16D004A1F7C /* UbuntuOneAuthKit.a */; };
3810- 52A042FF1606D6C40000B4BC /* NSMutableURLRequest+Parameters.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042D71606D6C40000B4BC /* NSMutableURLRequest+Parameters.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3811- 52A043001606D6C40000B4BC /* NSString+URLEncoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042D91606D6C40000B4BC /* NSString+URLEncoding.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3812- 52A043011606D6C40000B4BC /* NSURL+Base.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042DB1606D6C40000B4BC /* NSURL+Base.m */; };
3813- 52A043021606D6C40000B4BC /* Base64Transcoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 52A042DD1606D6C40000B4BC /* Base64Transcoder.c */; };
3814- 52A043031606D6C40000B4BC /* hmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 52A042DF1606D6C40000B4BC /* hmac.c */; };
3815- 52A043041606D6C40000B4BC /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 52A042E11606D6C40000B4BC /* sha1.c */; };
3816- 52A043051606D6C40000B4BC /* OAAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042E41606D6C40000B4BC /* OAAttachment.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3817- 52A043061606D6C40000B4BC /* OACall.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042E61606D6C40000B4BC /* OACall.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3818- 52A043071606D6C40000B4BC /* OAConsumer.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042E81606D6C40000B4BC /* OAConsumer.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3819- 52A043081606D6C40000B4BC /* OADataFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042EA1606D6C40000B4BC /* OADataFetcher.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3820- 52A043091606D6C40000B4BC /* OAHMAC_SHA1SignatureProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042EC1606D6C40000B4BC /* OAHMAC_SHA1SignatureProvider.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3821- 52A0430A1606D6C40000B4BC /* OAMutableURLRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042EE1606D6C40000B4BC /* OAMutableURLRequest.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3822- 52A0430B1606D6C40000B4BC /* OAPlaintextSignatureProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042F01606D6C40000B4BC /* OAPlaintextSignatureProvider.m */; };
3823- 52A0430C1606D6C40000B4BC /* OAProblem.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042F21606D6C40000B4BC /* OAProblem.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3824- 52A0430D1606D6C40000B4BC /* OARequestParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042F41606D6C40000B4BC /* OARequestParameter.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3825- 52A0430E1606D6C40000B4BC /* OAServiceTicket.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042F61606D6C40000B4BC /* OAServiceTicket.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3826- 52A0430F1606D6C40000B4BC /* OATestServer.rb in Resources */ = {isa = PBXBuildFile; fileRef = 52A042F81606D6C40000B4BC /* OATestServer.rb */; };
3827- 52A043101606D6C40000B4BC /* OAToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042FA1606D6C40000B4BC /* OAToken.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3828- 52A043111606D6C40000B4BC /* OATokenManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 52A042FC1606D6C40000B4BC /* OATokenManager.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3829- 52A043121606D6C40000B4BC /* README in Resources */ = {isa = PBXBuildFile; fileRef = 52A042FE1606D6C40000B4BC /* README */; };
3830 52AC3D671604513E00B4785D /* about_logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 52AC3D4B1604513E00B4785D /* about_logo.png */; };
3831 52AC3D681604513E00B4785D /* albums.png in Resources */ = {isa = PBXBuildFile; fileRef = 52AC3D4C1604513E00B4785D /* albums.png */; };
3832 52AC3D691604513E00B4785D /* albums@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 52AC3D4D1604513E00B4785D /* albums@2x.png */; };
3833@@ -77,6 +86,7 @@
3834 52AC3D811604513E00B4785D /* uncached.png in Resources */ = {isa = PBXBuildFile; fileRef = 52AC3D651604513E00B4785D /* uncached.png */; };
3835 52AC3D821604513E00B4785D /* uncached@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 52AC3D661604513E00B4785D /* uncached@2x.png */; };
3836 52AC3D841604539000B4785D /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 52AC3D831604539000B4785D /* Default-568h@2x.png */; };
3837+ 52E7F4A316AF1522003A46DA /* UbuntuOneAuthKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 528515941604F16D004A1F7C /* UbuntuOneAuthKit.a */; };
3838 536D620B1144495400DFCE56 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 536D620A1144495400DFCE56 /* SystemConfiguration.framework */; };
3839 537DE2D9113F008C00875852 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 537DE2D8113F008C00875852 /* CoreFoundation.framework */; };
3840 53F675D8113B092C00822059 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53F675D7113B092C00822059 /* MediaPlayer.framework */; };
3841@@ -86,22 +96,8 @@
3842 91018B0B13573BBB0051EFDC /* UIImage+Resize.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B0A13573BBB0051EFDC /* UIImage+Resize.m */; };
3843 91018B0E13573D150051EFDC /* UIImage+Alpha.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B0D13573D150051EFDC /* UIImage+Alpha.m */; };
3844 91018B1113573D350051EFDC /* UIImage+RoundedCorner.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B1013573D350051EFDC /* UIImage+RoundedCorner.m */; };
3845- 91018B4B135A724B0051EFDC /* PlaylistEditAlbumListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B42135A724B0051EFDC /* PlaylistEditAlbumListViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3846- 91018B4C135A724B0051EFDC /* PlaylistEditAlbumViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B44135A724B0051EFDC /* PlaylistEditAlbumViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3847- 91018B4D135A724B0051EFDC /* PlaylistEditArtistListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B46135A724B0051EFDC /* PlaylistEditArtistListViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3848- 91018B4E135A724B0051EFDC /* PlaylistEditArtistViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B48135A724B0051EFDC /* PlaylistEditArtistViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3849- 91018B4F135A724B0051EFDC /* PlaylistEditSongListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B4A135A724B0051EFDC /* PlaylistEditSongListViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3850- 9110DC38134C045A0046B8E4 /* AlbumParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 9110DC37134C04590046B8E4 /* AlbumParser.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3851- 9110DC44134EAC740046B8E4 /* AlbumListParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 9110DC43134EAC730046B8E4 /* AlbumListParser.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3852 9110DC571354A7490046B8E4 /* AlbumArtistUITableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9110DC561354A7470046B8E4 /* AlbumArtistUITableViewCell.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3853- 9123D1A113257ADF00B40210 /* PlaylistListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9123D1A013257ADF00B40210 /* PlaylistListViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3854- 9123D1BB13280B3400B40210 /* PlaylistViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9123D1BA13280B3400B40210 /* PlaylistViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3855- 9123D1C3132816D200B40210 /* PlaylistListParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 9123D1C2132816D200B40210 /* PlaylistListParser.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3856- 912D1259134617F600721EE4 /* SongListParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 912D1258134617F600721EE4 /* SongListParser.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3857 912D1264134A162000721EE4 /* AlertPrompt.m in Sources */ = {isa = PBXBuildFile; fileRef = 912D1263134A162000721EE4 /* AlertPrompt.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3858- 912D1267134B609700721EE4 /* PlaylistEditViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 912D1266134B609600721EE4 /* PlaylistEditViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3859- 912D392213311F2700A443B2 /* AlbumListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 912D392113311F2500A443B2 /* AlbumListViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3860- 912D392613311FC600A443B2 /* SongListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 912D392513311FC400A443B2 /* SongListViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3861 9132827D144E07EA00395F40 /* libTestFlight.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 91328279144E07EA00395F40 /* libTestFlight.a */; };
3862 91406EEA138AEEE000A7DA67 /* NSString+Extras.m in Sources */ = {isa = PBXBuildFile; fileRef = 91406EE9138AEEE000A7DA67 /* NSString+Extras.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3863 9149D9CF159BEC3D009AE771 /* default-album-art-120.png in Resources */ = {isa = PBXBuildFile; fileRef = 9149D9C9159BEC3D009AE771 /* default-album-art-120.png */; };
3864@@ -110,17 +106,9 @@
3865 9149D9D2159BEC3D009AE771 /* default-album-art-200@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9149D9CC159BEC3D009AE771 /* default-album-art-200@2x.png */; };
3866 9149D9D3159BEC3D009AE771 /* default-album-art-640.png in Resources */ = {isa = PBXBuildFile; fileRef = 9149D9CD159BEC3D009AE771 /* default-album-art-640.png */; };
3867 9149D9D4159BEC3D009AE771 /* default-album-art-640@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9149D9CE159BEC3D009AE771 /* default-album-art-640@2x.png */; };
3868- 914AC3FF14B61D8A00C7D5A3 /* CachedSongsPlaylist.m in Sources */ = {isa = PBXBuildFile; fileRef = 914AC3F114B61D8A00C7D5A3 /* CachedSongsPlaylist.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3869- 914AC40014B61D8A00C7D5A3 /* _Album.m in Sources */ = {isa = PBXBuildFile; fileRef = 914AC3F414B61D8A00C7D5A3 /* _Album.m */; };
3870- 914AC40114B61D8A00C7D5A3 /* _Artist.m in Sources */ = {isa = PBXBuildFile; fileRef = 914AC3F614B61D8A00C7D5A3 /* _Artist.m */; };
3871- 914AC40214B61D8A00C7D5A3 /* _Playlist.m in Sources */ = {isa = PBXBuildFile; fileRef = 914AC3F814B61D8A00C7D5A3 /* _Playlist.m */; };
3872- 914AC40314B61D8A00C7D5A3 /* _PlaylistSongIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = 914AC3FA14B61D8A00C7D5A3 /* _PlaylistSongIndex.m */; };
3873- 914AC40414B61D8A00C7D5A3 /* _Song.m in Sources */ = {isa = PBXBuildFile; fileRef = 914AC3FC14B61D8A00C7D5A3 /* _Song.m */; };
3874- 914AC40514B61D8A00C7D5A3 /* PlaylistSongIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = 914AC3FE14B61D8A00C7D5A3 /* PlaylistSongIndex.m */; };
3875 917B47EF14E306C800062874 /* U1AutoDownloadsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 917B47EE14E306C800062874 /* U1AutoDownloadsManager.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3876 917B47FB14E42C7900062874 /* U1CacheFileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 917B47FA14E42C7900062874 /* U1CacheFileManager.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3877 919376F3135CC1CF0030B7BD /* PlaylistEditSongUITableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 919376F2135CC1CF0030B7BD /* PlaylistEditSongUITableViewCell.m */; };
3878- 91B3A4441344CF92006C8193 /* SubsonicIndexedTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91B3A4431344CF91006C8193 /* SubsonicIndexedTableViewController.m */; };
3879 91BE4018138E8D2300D44D68 /* UIActionSheet+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = 91BE4015138E8D2300D44D68 /* UIActionSheet+Blocks.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3880 91BE4019138E8D2300D44D68 /* UIAlertView+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = 91BE4017138E8D2300D44D68 /* UIAlertView+Blocks.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3881 91BE401C138E8D3A00D44D68 /* RIButtonItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 91BE401B138E8D3A00D44D68 /* RIButtonItem.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3882@@ -130,8 +118,6 @@
3883 91D3A17214BE12FE003D4FC0 /* PlaylistUITableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 91D3A17114BE12FE003D4FC0 /* PlaylistUITableViewCell.m */; };
3884 91E3E46414D33A2D006ED32F /* U1SerializedDownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 91E3E46314D33A2D006ED32F /* U1SerializedDownloadOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3885 91E3E46814D33A6F006ED32F /* U1ChunkDownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 91E3E46714D33A6F006ED32F /* U1ChunkDownloadOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3886- 91E88609132DA82000618994 /* PlaylistParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 91E88608132DA82000618994 /* PlaylistParser.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3887- 91F2653014EACFCC0027232B /* U1MigrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91F2652E14EACFCC0027232B /* U1MigrationViewController.m */; };
3888 91F2653114EACFCC0027232B /* U1MigrationViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 91F2652F14EACFCC0027232B /* U1MigrationViewController.xib */; };
3889 9316628812264A74003B0EB7 /* NSDate+Extras.m in Sources */ = {isa = PBXBuildFile; fileRef = 9316628712264A74003B0EB7 /* NSDate+Extras.m */; };
3890 932E7AA01255265A00E7C8FF /* about.css in Resources */ = {isa = PBXBuildFile; fileRef = 932E7A9E1255265A00E7C8FF /* about.css */; };
3891@@ -139,8 +125,6 @@
3892 932E7B0912552CB400E7C8FF /* PullRefreshTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 932E7B0812552CB400E7C8FF /* PullRefreshTableViewController.m */; };
3893 932E7B0B12552CD500E7C8FF /* arrow.png in Resources */ = {isa = PBXBuildFile; fileRef = 932E7B0A12552CD500E7C8FF /* arrow.png */; };
3894 9354D0AB1248267B00733067 /* NSDictionary+Extras.m in Sources */ = {isa = PBXBuildFile; fileRef = 9354D0AA1248267B00733067 /* NSDictionary+Extras.m */; };
3895- 936F20681227364200070F43 /* Playlist.m in Sources */ = {isa = PBXBuildFile; fileRef = 936F20671227364200070F43 /* Playlist.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3896- 936F209012273D9000070F43 /* Song.m in Sources */ = {isa = PBXBuildFile; fileRef = 936F208F12273D9000070F43 /* Song.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3897 936F230A12284D1900070F43 /* NamedTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 936F230912284D1900070F43 /* NamedTextFieldCell.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3898 937FAA11137CFC1B00507E51 /* AlbumArtLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 937FAA0E137CFC1B00507E51 /* AlbumArtLoader.m */; };
3899 937FAA12137CFC1B00507E51 /* AlbumArtDownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 937FAA10137CFC1B00507E51 /* AlbumArtDownloadOperation.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3900@@ -169,25 +153,14 @@
3901 93DFFE3F135D70B60061F29F /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93DFFE3E135D70B60061F29F /* CoreData.framework */; };
3902 93DFFE4D135D71760061F29F /* music.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 93DFFE4C135D71760061F29F /* music.xcdatamodeld */; };
3903 93DFFE54135D72420061F29F /* NSManagedObjectContext+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 93DFFE53135D72420061F29F /* NSManagedObjectContext+Additions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3904- 93EE2AF0124993F100E7E060 /* ArtistListParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 93EE2AEF124993F100E7E060 /* ArtistListParser.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3905- 93EE2BA31249F33D00E7E060 /* ArtistParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 93EE2BA21249F33D00E7E060 /* ArtistParser.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3906 93F3344D1247FA0B006C6707 /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F3344C1247FA0B006C6707 /* Reachability.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3907- 93F334521247FA2C006C6707 /* Album.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F3344F1247FA2C006C6707 /* Album.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3908- 93F334531247FA2C006C6707 /* Artist.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F334511247FA2C006C6707 /* Artist.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3909 93F3345C1247FA85006C6707 /* AlbumUITableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F3345B1247FA85006C6707 /* AlbumUITableViewCell.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3910 93F3345F1247FA97006C6707 /* SongUITableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F3345E1247FA97006C6707 /* SongUITableViewCell.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3911 93F334681247FB02006C6707 /* SongViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93F334641247FB02006C6707 /* SongViewController.xib */; };
3912 93F334691247FB02006C6707 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93F334651247FB02006C6707 /* MainWindow.xib */; };
3913 93F3346A1247FB02006C6707 /* SearchableTableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93F334661247FB02006C6707 /* SearchableTableViewController.xib */; };
3914- 93F334711247FB78006C6707 /* U1MusicAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F3346F1247FB78006C6707 /* U1MusicAppDelegate.m */; };
3915 93F334721247FB78006C6707 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F334701247FB78006C6707 /* main.m */; };
3916 93F334751247FB9F006C6707 /* AudioStreamer.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F334741247FB9F006C6707 /* AudioStreamer.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3917- 93F3349F1247FCDC006C6707 /* ArtistViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F3348E1247FCDC006C6707 /* ArtistViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3918- 93F334A01247FCDC006C6707 /* SongViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F334901247FCDC006C6707 /* SongViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3919- 93F334A31247FCDC006C6707 /* ArtistListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F334961247FCDC006C6707 /* ArtistListViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3920- 93F334A41247FCDC006C6707 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F334981247FCDC006C6707 /* SettingsViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3921- 93F334A61247FCDC006C6707 /* AlbumViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F3349C1247FCDC006C6707 /* AlbumViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3922- 93F334A71247FCDC006C6707 /* SubsonicTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F3349E1247FCDC006C6707 /* SubsonicTableViewController.m */; };
3923 93FA42AE124DC1350080DF62 /* 03-loopback.png in Resources */ = {isa = PBXBuildFile; fileRef = 93FA42A7124DC1350080DF62 /* 03-loopback.png */; };
3924 93FA42AF124DC1350080DF62 /* 03-loopback@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93FA42A8124DC1350080DF62 /* 03-loopback@2x.png */; };
3925 93FA42B0124DC1350080DF62 /* 05-shuffle.png in Resources */ = {isa = PBXBuildFile; fileRef = 93FA42A9124DC1350080DF62 /* 05-shuffle.png */; };
3926@@ -201,8 +174,6 @@
3927 93FA43B5124DF07C0080DF62 /* player_overlay_bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 93FA43B3124DF07C0080DF62 /* player_overlay_bg.png */; };
3928 93FA43B6124DF07C0080DF62 /* player_overlay_bg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93FA43B4124DF07C0080DF62 /* player_overlay_bg@2x.png */; };
3929 960E4B2E14E586AE002AAB79 /* CacheFileAccess.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 960E4B2C14E586AE002AAB79 /* CacheFileAccess.xcdatamodeld */; };
3930- 960E4B3514E58844002AAB79 /* U1CachedFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 960E4B3414E58844002AAB79 /* U1CachedFile.m */; };
3931- 960E4B3814E5884B002AAB79 /* _U1CachedFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 960E4B3714E5884B002AAB79 /* _U1CachedFile.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3932 9619626614E088F50038DACA /* U1SocketListener.m in Sources */ = {isa = PBXBuildFile; fileRef = 9619626514E088F50038DACA /* U1SocketListener.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3933 9619626A14E08F4B0038DACA /* U1HTTPMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9619626914E08F4B0038DACA /* U1HTTPMessage.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3934 9619626F14E08F630038DACA /* U1HTTPRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 9619626C14E08F630038DACA /* U1HTTPRequest.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
3935@@ -221,6 +192,34 @@
3936 /* End PBXBuildFile section */
3937
3938 /* Begin PBXContainerItemProxy section */
3939+ 5268508F16AE516C001F65A6 /* PBXContainerItemProxy */ = {
3940+ isa = PBXContainerItemProxy;
3941+ containerPortal = 5268508516AE516B001F65A6 /* RestKit.xcodeproj */;
3942+ proxyType = 2;
3943+ remoteGlobalIDString = 25160D1614564E810060A5C5;
3944+ remoteInfo = RestKit;
3945+ };
3946+ 5268509116AE516C001F65A6 /* PBXContainerItemProxy */ = {
3947+ isa = PBXContainerItemProxy;
3948+ containerPortal = 5268508516AE516B001F65A6 /* RestKit.xcodeproj */;
3949+ proxyType = 2;
3950+ remoteGlobalIDString = 25160D2614564E820060A5C5;
3951+ remoteInfo = RestKitTests;
3952+ };
3953+ 5268509316AE516C001F65A6 /* PBXContainerItemProxy */ = {
3954+ isa = PBXContainerItemProxy;
3955+ containerPortal = 5268508516AE516B001F65A6 /* RestKit.xcodeproj */;
3956+ proxyType = 2;
3957+ remoteGlobalIDString = 25160E62145651060060A5C5;
3958+ remoteInfo = RestKitFramework;
3959+ };
3960+ 5268509516AE516C001F65A6 /* PBXContainerItemProxy */ = {
3961+ isa = PBXContainerItemProxy;
3962+ containerPortal = 5268508516AE516B001F65A6 /* RestKit.xcodeproj */;
3963+ proxyType = 2;
3964+ remoteGlobalIDString = 25160E78145651060060A5C5;
3965+ remoteInfo = RestKitFrameworkTests;
3966+ };
3967 528515931604F16D004A1F7C /* PBXContainerItemProxy */ = {
3968 isa = PBXContainerItemProxy;
3969 containerPortal = 5285158E1604F16B004A1F7C /* UbuntuOneAuthKit.xcodeproj */;
3970@@ -267,48 +266,58 @@
3971 523B3CF615B73BA0004394F4 /* download-grey@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "download-grey@2x.png"; sourceTree = "<group>"; };
3972 523B3CF715B73BA0004394F4 /* download.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = download.png; sourceTree = "<group>"; };
3973 523B3CF815B73BA0004394F4 /* download@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "download@2x.png"; sourceTree = "<group>"; };
3974+ 5268508516AE516B001F65A6 /* RestKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RestKit.xcodeproj; path = ../RestKit/RestKit.xcodeproj; sourceTree = "<group>"; };
3975+ 526850A516AEE4E1001F65A6 /* Storyboard_iPhone.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Storyboard_iPhone.storyboard; sourceTree = "<group>"; };
3976+ 526850A616AEE4E1001F65A6 /* UOAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UOAppDelegate.h; sourceTree = "<group>"; };
3977+ 526850A716AEE4E1001F65A6 /* UOAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UOAppDelegate.m; sourceTree = "<group>"; };
3978+ 526850AB16AEF9DD001F65A6 /* UOMusic.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = UOMusic.xcdatamodel; sourceTree = "<group>"; };
3979+ 526850AE16AEFA59001F65A6 /* AlbumsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlbumsViewController.h; sourceTree = "<group>"; };
3980+ 526850AF16AEFA59001F65A6 /* AlbumsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlbumsViewController.m; sourceTree = "<group>"; };
3981+ 526850B016AEFA59001F65A6 /* AlbumViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlbumViewController.h; sourceTree = "<group>"; };
3982+ 526850B116AEFA59001F65A6 /* AlbumViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlbumViewController.m; sourceTree = "<group>"; };
3983+ 526850B216AEFA59001F65A6 /* ArtistsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArtistsViewController.h; sourceTree = "<group>"; };
3984+ 526850B316AEFA59001F65A6 /* ArtistsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArtistsViewController.m; sourceTree = "<group>"; };
3985+ 526850B416AEFA59001F65A6 /* ArtistViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArtistViewController.h; sourceTree = "<group>"; };
3986+ 526850B516AEFA59001F65A6 /* ArtistViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArtistViewController.m; sourceTree = "<group>"; };
3987+ 526850B616AEFA59001F65A6 /* PlayerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerViewController.h; sourceTree = "<group>"; };
3988+ 526850B716AEFA59001F65A6 /* PlayerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlayerViewController.m; sourceTree = "<group>"; };
3989+ 526850B816AEFA59001F65A6 /* PlaylistsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaylistsViewController.h; sourceTree = "<group>"; };
3990+ 526850B916AEFA59001F65A6 /* PlaylistsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlaylistsViewController.m; sourceTree = "<group>"; };
3991+ 526850BA16AEFA59001F65A6 /* SettingsAboutViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsAboutViewController.h; sourceTree = "<group>"; };
3992+ 526850BB16AEFA59001F65A6 /* SettingsAboutViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsAboutViewController.m; sourceTree = "<group>"; };
3993+ 526850BC16AEFA59001F65A6 /* SettingsAuthenticationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsAuthenticationViewController.h; sourceTree = "<group>"; };
3994+ 526850BD16AEFA59001F65A6 /* SettingsAuthenticationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsAuthenticationViewController.m; sourceTree = "<group>"; };
3995+ 526850BE16AEFA59001F65A6 /* SettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsViewController.h; sourceTree = "<group>"; };
3996+ 526850BF16AEFA59001F65A6 /* SettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsViewController.m; sourceTree = "<group>"; };
3997+ 526850C016AEFA59001F65A6 /* SongsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SongsViewController.h; sourceTree = "<group>"; };
3998+ 526850C116AEFA59001F65A6 /* SongsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SongsViewController.m; sourceTree = "<group>"; };
3999+ 526850C216AEFA59001F65A6 /* UOIndexedViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UOIndexedViewController.h; sourceTree = "<group>"; };
4000+ 526850C316AEFA59001F65A6 /* UOIndexedViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UOIndexedViewController.m; sourceTree = "<group>"; };
4001+ 526850D016AEFA7C001F65A6 /* UOWebServiceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UOWebServiceController.h; sourceTree = "<group>"; };
4002+ 526850D116AEFA7C001F65A6 /* UOWebServiceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UOWebServiceController.m; sourceTree = "<group>"; };
4003+ 526850D316AEFA7D001F65A6 /* PlayerHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerHeaderView.h; sourceTree = "<group>"; };
4004+ 526850D416AEFA7D001F65A6 /* PlayerHeaderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlayerHeaderView.m; sourceTree = "<group>"; };
4005+ 526850D616AEFA7D001F65A6 /* AlbumCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlbumCell.h; sourceTree = "<group>"; };
4006+ 526850D716AEFA7D001F65A6 /* AlbumCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlbumCell.m; sourceTree = "<group>"; };
4007+ 526850D816AEFA7D001F65A6 /* ArtistCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArtistCell.h; sourceTree = "<group>"; };
4008+ 526850D916AEFA7D001F65A6 /* ArtistCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArtistCell.m; sourceTree = "<group>"; };
4009+ 526850DA16AEFA7D001F65A6 /* PlaylistCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaylistCell.h; sourceTree = "<group>"; };
4010+ 526850DB16AEFA7D001F65A6 /* PlaylistCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlaylistCell.m; sourceTree = "<group>"; };
4011+ 526850DC16AEFA7D001F65A6 /* SongCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SongCell.h; sourceTree = "<group>"; };
4012+ 526850DD16AEFA7D001F65A6 /* SongCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SongCell.m; sourceTree = "<group>"; };
4013+ 526850F516AEFC6A001F65A6 /* Album.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Album.h; sourceTree = "<group>"; };
4014+ 526850F616AEFC6A001F65A6 /* Album.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Album.m; sourceTree = "<group>"; };
4015+ 526850F716AEFC6A001F65A6 /* Artist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Artist.h; sourceTree = "<group>"; };
4016+ 526850F816AEFC6A001F65A6 /* Artist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Artist.m; sourceTree = "<group>"; };
4017+ 526850F916AEFC6A001F65A6 /* Playlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Playlist.h; sourceTree = "<group>"; };
4018+ 526850FA16AEFC6A001F65A6 /* Playlist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Playlist.m; sourceTree = "<group>"; };
4019+ 526850FB16AEFC6A001F65A6 /* Song.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Song.h; sourceTree = "<group>"; };
4020+ 526850FC16AEFC6A001F65A6 /* Song.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Song.m; sourceTree = "<group>"; };
4021+ 526850FD16AEFC6A001F65A6 /* UOModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UOModel.h; sourceTree = "<group>"; };
4022+ 526850FE16AEFC6A001F65A6 /* UOModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UOModel.m; sourceTree = "<group>"; };
4023+ 5268510716AEFD20001F65A6 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
4024 5279764815F00B2600F8435F /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
4025 5285158E1604F16B004A1F7C /* UbuntuOneAuthKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = UbuntuOneAuthKit.xcodeproj; path = ../UbuntuOneAuthKit/UbuntuOneAuthKit.xcodeproj; sourceTree = "<group>"; };
4026- 52A042D61606D6C40000B4BC /* NSMutableURLRequest+Parameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableURLRequest+Parameters.h"; sourceTree = "<group>"; };
4027- 52A042D71606D6C40000B4BC /* NSMutableURLRequest+Parameters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableURLRequest+Parameters.m"; sourceTree = "<group>"; };
4028- 52A042D81606D6C40000B4BC /* NSString+URLEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+URLEncoding.h"; sourceTree = "<group>"; };
4029- 52A042D91606D6C40000B4BC /* NSString+URLEncoding.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+URLEncoding.m"; sourceTree = "<group>"; };
4030- 52A042DA1606D6C40000B4BC /* NSURL+Base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+Base.h"; sourceTree = "<group>"; };
4031- 52A042DB1606D6C40000B4BC /* NSURL+Base.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+Base.m"; sourceTree = "<group>"; };
4032- 52A042DD1606D6C40000B4BC /* Base64Transcoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Base64Transcoder.c; sourceTree = "<group>"; };
4033- 52A042DE1606D6C40000B4BC /* Base64Transcoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64Transcoder.h; sourceTree = "<group>"; };
4034- 52A042DF1606D6C40000B4BC /* hmac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hmac.c; sourceTree = "<group>"; };
4035- 52A042E01606D6C40000B4BC /* hmac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hmac.h; sourceTree = "<group>"; };
4036- 52A042E11606D6C40000B4BC /* sha1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sha1.c; sourceTree = "<group>"; };
4037- 52A042E21606D6C40000B4BC /* sha1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sha1.h; sourceTree = "<group>"; };
4038- 52A042E31606D6C40000B4BC /* OAAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAAttachment.h; sourceTree = "<group>"; };
4039- 52A042E41606D6C40000B4BC /* OAAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAAttachment.m; sourceTree = "<group>"; };
4040- 52A042E51606D6C40000B4BC /* OACall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OACall.h; sourceTree = "<group>"; };
4041- 52A042E61606D6C40000B4BC /* OACall.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OACall.m; sourceTree = "<group>"; };
4042- 52A042E71606D6C40000B4BC /* OAConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAConsumer.h; sourceTree = "<group>"; };
4043- 52A042E81606D6C40000B4BC /* OAConsumer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAConsumer.m; sourceTree = "<group>"; };
4044- 52A042E91606D6C40000B4BC /* OADataFetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OADataFetcher.h; sourceTree = "<group>"; };
4045- 52A042EA1606D6C40000B4BC /* OADataFetcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OADataFetcher.m; sourceTree = "<group>"; };
4046- 52A042EB1606D6C40000B4BC /* OAHMAC_SHA1SignatureProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAHMAC_SHA1SignatureProvider.h; sourceTree = "<group>"; };
4047- 52A042EC1606D6C40000B4BC /* OAHMAC_SHA1SignatureProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAHMAC_SHA1SignatureProvider.m; sourceTree = "<group>"; };
4048- 52A042ED1606D6C40000B4BC /* OAMutableURLRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAMutableURLRequest.h; sourceTree = "<group>"; };
4049- 52A042EE1606D6C40000B4BC /* OAMutableURLRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAMutableURLRequest.m; sourceTree = "<group>"; };
4050- 52A042EF1606D6C40000B4BC /* OAPlaintextSignatureProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAPlaintextSignatureProvider.h; sourceTree = "<group>"; };
4051- 52A042F01606D6C40000B4BC /* OAPlaintextSignatureProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAPlaintextSignatureProvider.m; sourceTree = "<group>"; };
4052- 52A042F11606D6C40000B4BC /* OAProblem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAProblem.h; sourceTree = "<group>"; };
4053- 52A042F21606D6C40000B4BC /* OAProblem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAProblem.m; sourceTree = "<group>"; };
4054- 52A042F31606D6C40000B4BC /* OARequestParameter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OARequestParameter.h; sourceTree = "<group>"; };
4055- 52A042F41606D6C40000B4BC /* OARequestParameter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OARequestParameter.m; sourceTree = "<group>"; };
4056- 52A042F51606D6C40000B4BC /* OAServiceTicket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAServiceTicket.h; sourceTree = "<group>"; };
4057- 52A042F61606D6C40000B4BC /* OAServiceTicket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAServiceTicket.m; sourceTree = "<group>"; };
4058- 52A042F71606D6C40000B4BC /* OASignatureProviding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OASignatureProviding.h; sourceTree = "<group>"; };
4059- 52A042F81606D6C40000B4BC /* OATestServer.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = OATestServer.rb; sourceTree = "<group>"; };
4060- 52A042F91606D6C40000B4BC /* OAToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAToken.h; sourceTree = "<group>"; };
4061- 52A042FA1606D6C40000B4BC /* OAToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAToken.m; sourceTree = "<group>"; };
4062- 52A042FB1606D6C40000B4BC /* OATokenManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OATokenManager.h; sourceTree = "<group>"; };
4063- 52A042FC1606D6C40000B4BC /* OATokenManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OATokenManager.m; sourceTree = "<group>"; };
4064- 52A042FD1606D6C40000B4BC /* OAuthConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthConsumer.h; sourceTree = "<group>"; };
4065- 52A042FE1606D6C40000B4BC /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
4066 52AC3D4B1604513E00B4785D /* about_logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = about_logo.png; sourceTree = "<group>"; };
4067 52AC3D4C1604513E00B4785D /* albums.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = albums.png; sourceTree = "<group>"; };
4068 52AC3D4D1604513E00B4785D /* albums@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "albums@2x.png"; sourceTree = "<group>"; };
4069@@ -515,8 +524,8 @@
4070 93F334641247FB02006C6707 /* SongViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SongViewController.xib; sourceTree = "<group>"; };
4071 93F334651247FB02006C6707 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = "<group>"; };
4072 93F334661247FB02006C6707 /* SearchableTableViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SearchableTableViewController.xib; sourceTree = "<group>"; };
4073- 93F3346E1247FB78006C6707 /* U1MusicAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = U1MusicAppDelegate.h; sourceTree = "<group>"; };
4074- 93F3346F1247FB78006C6707 /* U1MusicAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = U1MusicAppDelegate.m; sourceTree = "<group>"; };
4075+ 93F3346E1247FB78006C6707 /* U1MusicAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = U1MusicAppDelegate.h; path = "Other Sources/U1MusicAppDelegate.h"; sourceTree = "<group>"; };
4076+ 93F3346F1247FB78006C6707 /* U1MusicAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = U1MusicAppDelegate.m; path = "Other Sources/U1MusicAppDelegate.m"; sourceTree = "<group>"; };
4077 93F334701247FB78006C6707 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
4078 93F334731247FB9F006C6707 /* AudioStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioStreamer.h; sourceTree = "<group>"; };
4079 93F334741247FB9F006C6707 /* AudioStreamer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioStreamer.m; sourceTree = "<group>"; };
4080@@ -586,20 +595,22 @@
4081 isa = PBXFrameworksBuildPhase;
4082 buildActionMask = 2147483647;
4083 files = (
4084- 528515991604F410004A1F7C /* UbuntuOneAuthKit.a in Frameworks */,
4085- 5279764915F00B2600F8435F /* libz.dylib in Frameworks */,
4086+ 53F675E8113B096400822059 /* AudioToolbox.framework in Frameworks */,
4087+ 53F675DC113B093900822059 /* CFNetwork.framework in Frameworks */,
4088+ 93DFFE3F135D70B60061F29F /* CoreData.framework in Frameworks */,
4089+ 537DE2D9113F008C00875852 /* CoreFoundation.framework in Frameworks */,
4090+ 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */,
4091 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
4092- 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
4093- 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */,
4094 53F675D8113B092C00822059 /* MediaPlayer.framework in Frameworks */,
4095- 53F675DC113B093900822059 /* CFNetwork.framework in Frameworks */,
4096+ 5268510816AEFD20001F65A6 /* MobileCoreServices.framework in Frameworks */,
4097 53F675E2113B095900822059 /* QuartzCore.framework in Frameworks */,
4098- 53F675E8113B096400822059 /* AudioToolbox.framework in Frameworks */,
4099- 537DE2D9113F008C00875852 /* CoreFoundation.framework in Frameworks */,
4100+ 93A54024123188880048BC3D /* Security.framework in Frameworks */,
4101 536D620B1144495400DFCE56 /* SystemConfiguration.framework in Frameworks */,
4102- 93A54024123188880048BC3D /* Security.framework in Frameworks */,
4103- 93DFFE3F135D70B60061F29F /* CoreData.framework in Frameworks */,
4104+ 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
4105+ 5279764915F00B2600F8435F /* libz.dylib in Frameworks */,
4106 9132827D144E07EA00395F40 /* libTestFlight.a in Frameworks */,
4107+ 5268509716AE5267001F65A6 /* libRestKit.a in Frameworks */,
4108+ 52E7F4A316AF1522003A46DA /* UbuntuOneAuthKit.a in Frameworks */,
4109 );
4110 runOnlyForDeploymentPostprocessing = 0;
4111 };
4112@@ -617,15 +628,16 @@
4113 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
4114 isa = PBXGroup;
4115 children = (
4116+ 5268508516AE516B001F65A6 /* RestKit.xcodeproj */,
4117 5285158E1604F16B004A1F7C /* UbuntuOneAuthKit.xcodeproj */,
4118 93F3346C1247FB78006C6707 /* Music */,
4119+ 526850A416AEE4B7001F65A6 /* Deprecated */,
4120 91018B261359233E0051EFDC /* Base View Controllers */,
4121 93F3348C1247FCDC006C6707 /* Root View Controllers */,
4122 91018B27135923960051EFDC /* Sub View Controllers */,
4123 91018B28135923D20051EFDC /* Playlist Edit View Controllers */,
4124 93F334631247FB02006C6707 /* Xibs */,
4125 93F334441247F9B9006C6707 /* Utilities */,
4126- 936F20651227363800070F43 /* Models */,
4127 936F1F2E12271B6500070F43 /* Controls */,
4128 9316628512264A74003B0EB7 /* Categories */,
4129 29B97317FDCFA39411CA2CEA /* Resources */,
4130@@ -648,6 +660,7 @@
4131 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
4132 isa = PBXGroup;
4133 children = (
4134+ 5268510716AEFD20001F65A6 /* MobileCoreServices.framework */,
4135 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
4136 1D30AB110D05D00D00671497 /* Foundation.framework */,
4137 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */,
4138@@ -663,6 +676,111 @@
4139 name = Frameworks;
4140 sourceTree = "<group>";
4141 };
4142+ 5268508616AE516B001F65A6 /* Products */ = {
4143+ isa = PBXGroup;
4144+ children = (
4145+ 5268509016AE516C001F65A6 /* libRestKit.a */,
4146+ 5268509216AE516C001F65A6 /* RestKitTests.octest */,
4147+ 5268509416AE516C001F65A6 /* RestKit.framework */,
4148+ 5268509616AE516C001F65A6 /* RestKitFrameworkTests.octest */,
4149+ );
4150+ name = Products;
4151+ sourceTree = "<group>";
4152+ };
4153+ 526850A416AEE4B7001F65A6 /* Deprecated */ = {
4154+ isa = PBXGroup;
4155+ children = (
4156+ 91D3A16D14B93B2A003D4FC0 /* MOC.h */,
4157+ 91D3A16E14B93B2A003D4FC0 /* MOC.m */,
4158+ 914AC3F014B61D8A00C7D5A3 /* CachedSongsPlaylist.h */,
4159+ 914AC3F114B61D8A00C7D5A3 /* CachedSongsPlaylist.m */,
4160+ 936F20651227363800070F43 /* Models */,
4161+ 93F3346E1247FB78006C6707 /* U1MusicAppDelegate.h */,
4162+ 93F3346F1247FB78006C6707 /* U1MusicAppDelegate.m */,
4163+ );
4164+ name = Deprecated;
4165+ sourceTree = "<group>";
4166+ };
4167+ 526850AD16AEFA59001F65A6 /* View Controllers */ = {
4168+ isa = PBXGroup;
4169+ children = (
4170+ 526850AE16AEFA59001F65A6 /* AlbumsViewController.h */,
4171+ 526850AF16AEFA59001F65A6 /* AlbumsViewController.m */,
4172+ 526850B016AEFA59001F65A6 /* AlbumViewController.h */,
4173+ 526850B116AEFA59001F65A6 /* AlbumViewController.m */,
4174+ 526850B216AEFA59001F65A6 /* ArtistsViewController.h */,
4175+ 526850B316AEFA59001F65A6 /* ArtistsViewController.m */,
4176+ 526850B416AEFA59001F65A6 /* ArtistViewController.h */,
4177+ 526850B516AEFA59001F65A6 /* ArtistViewController.m */,
4178+ 526850B616AEFA59001F65A6 /* PlayerViewController.h */,
4179+ 526850B716AEFA59001F65A6 /* PlayerViewController.m */,
4180+ 526850B816AEFA59001F65A6 /* PlaylistsViewController.h */,
4181+ 526850B916AEFA59001F65A6 /* PlaylistsViewController.m */,
4182+ 526850BA16AEFA59001F65A6 /* SettingsAboutViewController.h */,
4183+ 526850BB16AEFA59001F65A6 /* SettingsAboutViewController.m */,
4184+ 526850BC16AEFA59001F65A6 /* SettingsAuthenticationViewController.h */,
4185+ 526850BD16AEFA59001F65A6 /* SettingsAuthenticationViewController.m */,
4186+ 526850BE16AEFA59001F65A6 /* SettingsViewController.h */,
4187+ 526850BF16AEFA59001F65A6 /* SettingsViewController.m */,
4188+ 526850C016AEFA59001F65A6 /* SongsViewController.h */,
4189+ 526850C116AEFA59001F65A6 /* SongsViewController.m */,
4190+ 526850C216AEFA59001F65A6 /* UOIndexedViewController.h */,
4191+ 526850C316AEFA59001F65A6 /* UOIndexedViewController.m */,
4192+ );
4193+ path = "View Controllers";
4194+ sourceTree = "<group>";
4195+ };
4196+ 526850CF16AEFA7C001F65A6 /* Utilities */ = {
4197+ isa = PBXGroup;
4198+ children = (
4199+ 526850D016AEFA7C001F65A6 /* UOWebServiceController.h */,
4200+ 526850D116AEFA7C001F65A6 /* UOWebServiceController.m */,
4201+ );
4202+ path = Utilities;
4203+ sourceTree = "<group>";
4204+ };
4205+ 526850D216AEFA7C001F65A6 /* Views */ = {
4206+ isa = PBXGroup;
4207+ children = (
4208+ 526850D316AEFA7D001F65A6 /* PlayerHeaderView.h */,
4209+ 526850D416AEFA7D001F65A6 /* PlayerHeaderView.m */,
4210+ 526850D516AEFA7D001F65A6 /* Table Cells */,
4211+ );
4212+ path = Views;
4213+ sourceTree = "<group>";
4214+ };
4215+ 526850D516AEFA7D001F65A6 /* Table Cells */ = {
4216+ isa = PBXGroup;
4217+ children = (
4218+ 526850D616AEFA7D001F65A6 /* AlbumCell.h */,
4219+ 526850D716AEFA7D001F65A6 /* AlbumCell.m */,
4220+ 526850D816AEFA7D001F65A6 /* ArtistCell.h */,
4221+ 526850D916AEFA7D001F65A6 /* ArtistCell.m */,
4222+ 526850DA16AEFA7D001F65A6 /* PlaylistCell.h */,
4223+ 526850DB16AEFA7D001F65A6 /* PlaylistCell.m */,
4224+ 526850DC16AEFA7D001F65A6 /* SongCell.h */,
4225+ 526850DD16AEFA7D001F65A6 /* SongCell.m */,
4226+ );
4227+ path = "Table Cells";
4228+ sourceTree = "<group>";
4229+ };
4230+ 526850F416AEFC6A001F65A6 /* Models */ = {
4231+ isa = PBXGroup;
4232+ children = (
4233+ 526850F516AEFC6A001F65A6 /* Album.h */,
4234+ 526850F616AEFC6A001F65A6 /* Album.m */,
4235+ 526850F716AEFC6A001F65A6 /* Artist.h */,
4236+ 526850F816AEFC6A001F65A6 /* Artist.m */,
4237+ 526850F916AEFC6A001F65A6 /* Playlist.h */,
4238+ 526850FA16AEFC6A001F65A6 /* Playlist.m */,
4239+ 526850FB16AEFC6A001F65A6 /* Song.h */,
4240+ 526850FC16AEFC6A001F65A6 /* Song.m */,
4241+ 526850FD16AEFC6A001F65A6 /* UOModel.h */,
4242+ 526850FE16AEFC6A001F65A6 /* UOModel.m */,
4243+ );
4244+ path = Models;
4245+ sourceTree = "<group>";
4246+ };
4247 528515571604EED8004A1F7C /* Supporting Files */ = {
4248 isa = PBXGroup;
4249 children = (
4250@@ -682,70 +800,6 @@
4251 name = Products;
4252 sourceTree = "<group>";
4253 };
4254- 52A042D41606D6C40000B4BC /* oauthconsumer */ = {
4255- isa = PBXGroup;
4256- children = (
4257- 52A042D51606D6C40000B4BC /* Categories */,
4258- 52A042DC1606D6C40000B4BC /* Crypto */,
4259- 52A042E31606D6C40000B4BC /* OAAttachment.h */,
4260- 52A042E41606D6C40000B4BC /* OAAttachment.m */,
4261- 52A042E51606D6C40000B4BC /* OACall.h */,
4262- 52A042E61606D6C40000B4BC /* OACall.m */,
4263- 52A042E71606D6C40000B4BC /* OAConsumer.h */,
4264- 52A042E81606D6C40000B4BC /* OAConsumer.m */,
4265- 52A042E91606D6C40000B4BC /* OADataFetcher.h */,
4266- 52A042EA1606D6C40000B4BC /* OADataFetcher.m */,
4267- 52A042EB1606D6C40000B4BC /* OAHMAC_SHA1SignatureProvider.h */,
4268- 52A042EC1606D6C40000B4BC /* OAHMAC_SHA1SignatureProvider.m */,
4269- 52A042ED1606D6C40000B4BC /* OAMutableURLRequest.h */,
4270- 52A042EE1606D6C40000B4BC /* OAMutableURLRequest.m */,
4271- 52A042EF1606D6C40000B4BC /* OAPlaintextSignatureProvider.h */,
4272- 52A042F01606D6C40000B4BC /* OAPlaintextSignatureProvider.m */,
4273- 52A042F11606D6C40000B4BC /* OAProblem.h */,
4274- 52A042F21606D6C40000B4BC /* OAProblem.m */,
4275- 52A042F31606D6C40000B4BC /* OARequestParameter.h */,
4276- 52A042F41606D6C40000B4BC /* OARequestParameter.m */,
4277- 52A042F51606D6C40000B4BC /* OAServiceTicket.h */,
4278- 52A042F61606D6C40000B4BC /* OAServiceTicket.m */,
4279- 52A042F71606D6C40000B4BC /* OASignatureProviding.h */,
4280- 52A042F81606D6C40000B4BC /* OATestServer.rb */,
4281- 52A042F91606D6C40000B4BC /* OAToken.h */,
4282- 52A042FA1606D6C40000B4BC /* OAToken.m */,
4283- 52A042FB1606D6C40000B4BC /* OATokenManager.h */,
4284- 52A042FC1606D6C40000B4BC /* OATokenManager.m */,
4285- 52A042FD1606D6C40000B4BC /* OAuthConsumer.h */,
4286- 52A042FE1606D6C40000B4BC /* README */,
4287- );
4288- name = oauthconsumer;
4289- path = Dependencies/oauthconsumer;
4290- sourceTree = "<group>";
4291- };
4292- 52A042D51606D6C40000B4BC /* Categories */ = {
4293- isa = PBXGroup;
4294- children = (
4295- 52A042D61606D6C40000B4BC /* NSMutableURLRequest+Parameters.h */,
4296- 52A042D71606D6C40000B4BC /* NSMutableURLRequest+Parameters.m */,
4297- 52A042D81606D6C40000B4BC /* NSString+URLEncoding.h */,
4298- 52A042D91606D6C40000B4BC /* NSString+URLEncoding.m */,
4299- 52A042DA1606D6C40000B4BC /* NSURL+Base.h */,
4300- 52A042DB1606D6C40000B4BC /* NSURL+Base.m */,
4301- );
4302- path = Categories;
4303- sourceTree = "<group>";
4304- };
4305- 52A042DC1606D6C40000B4BC /* Crypto */ = {
4306- isa = PBXGroup;
4307- children = (
4308- 52A042DD1606D6C40000B4BC /* Base64Transcoder.c */,
4309- 52A042DE1606D6C40000B4BC /* Base64Transcoder.h */,
4310- 52A042DF1606D6C40000B4BC /* hmac.c */,
4311- 52A042E01606D6C40000B4BC /* hmac.h */,
4312- 52A042E11606D6C40000B4BC /* sha1.c */,
4313- 52A042E21606D6C40000B4BC /* sha1.h */,
4314- );
4315- path = Crypto;
4316- sourceTree = "<group>";
4317- };
4318 91018B261359233E0051EFDC /* Base View Controllers */ = {
4319 isa = PBXGroup;
4320 children = (
4321@@ -925,8 +979,6 @@
4322 isa = PBXGroup;
4323 children = (
4324 914AC3F214B61D8A00C7D5A3 /* Generated */,
4325- 91D3A16D14B93B2A003D4FC0 /* MOC.h */,
4326- 91D3A16E14B93B2A003D4FC0 /* MOC.m */,
4327 93F3344E1247FA2C006C6707 /* Album.h */,
4328 93F3344F1247FA2C006C6707 /* Album.m */,
4329 93F334501247FA2C006C6707 /* Artist.h */,
4330@@ -937,8 +989,6 @@
4331 936F20671227364200070F43 /* Playlist.m */,
4332 914AC3FD14B61D8A00C7D5A3 /* PlaylistSongIndex.h */,
4333 914AC3FE14B61D8A00C7D5A3 /* PlaylistSongIndex.m */,
4334- 914AC3F014B61D8A00C7D5A3 /* CachedSongsPlaylist.h */,
4335- 914AC3F114B61D8A00C7D5A3 /* CachedSongsPlaylist.m */,
4336 );
4337 name = Models;
4338 path = models;
4339@@ -1015,14 +1065,19 @@
4340 93F3346C1247FB78006C6707 /* Music */ = {
4341 isa = PBXGroup;
4342 children = (
4343+ 526850F416AEFC6A001F65A6 /* Models */,
4344+ 528515571604EED8004A1F7C /* Supporting Files */,
4345+ 526850CF16AEFA7C001F65A6 /* Utilities */,
4346+ 526850AD16AEFA59001F65A6 /* View Controllers */,
4347+ 526850D216AEFA7C001F65A6 /* Views */,
4348+ 526850A516AEE4E1001F65A6 /* Storyboard_iPhone.storyboard */,
4349+ 526850A616AEE4E1001F65A6 /* UOAppDelegate.h */,
4350+ 526850A716AEE4E1001F65A6 /* UOAppDelegate.m */,
4351 93F334841247FC15006C6707 /* U1Music_Prefix.pch */,
4352- 93F3346E1247FB78006C6707 /* U1MusicAppDelegate.h */,
4353- 93F3346F1247FB78006C6707 /* U1MusicAppDelegate.m */,
4354+ 526850AA16AEF9DD001F65A6 /* UOMusic.xcdatamodeld */,
4355 93DFFE4C135D71760061F29F /* music.xcdatamodeld */,
4356- 528515571604EED8004A1F7C /* Supporting Files */,
4357 );
4358- name = Music;
4359- path = "Other Sources";
4360+ path = Music;
4361 sourceTree = "<group>";
4362 };
4363 93F3348C1247FCDC006C6707 /* Root View Controllers */ = {
4364@@ -1170,7 +1225,6 @@
4365 964FA39013CA5BE60018A65B /* Dependencies */ = {
4366 isa = PBXGroup;
4367 children = (
4368- 52A042D41606D6C40000B4BC /* oauthconsumer */,
4369 93BC520A124C187700B7587C /* SynthesizeSingleton.h */,
4370 5279764815F00B2600F8435F /* libz.dylib */,
4371 91328278144E07EA00395F40 /* TestFlight SDK */,
4372@@ -1245,6 +1299,10 @@
4373 projectDirPath = "";
4374 projectReferences = (
4375 {
4376+ ProductGroup = 5268508616AE516B001F65A6 /* Products */;
4377+ ProjectRef = 5268508516AE516B001F65A6 /* RestKit.xcodeproj */;
4378+ },
4379+ {
4380 ProductGroup = 5285158F1604F16B004A1F7C /* Products */;
4381 ProjectRef = 5285158E1604F16B004A1F7C /* UbuntuOneAuthKit.xcodeproj */;
4382 },
4383@@ -1257,6 +1315,34 @@
4384 /* End PBXProject section */
4385
4386 /* Begin PBXReferenceProxy section */
4387+ 5268509016AE516C001F65A6 /* libRestKit.a */ = {
4388+ isa = PBXReferenceProxy;
4389+ fileType = archive.ar;
4390+ path = libRestKit.a;
4391+ remoteRef = 5268508F16AE516C001F65A6 /* PBXContainerItemProxy */;
4392+ sourceTree = BUILT_PRODUCTS_DIR;
4393+ };
4394+ 5268509216AE516C001F65A6 /* RestKitTests.octest */ = {
4395+ isa = PBXReferenceProxy;
4396+ fileType = wrapper.cfbundle;
4397+ path = RestKitTests.octest;
4398+ remoteRef = 5268509116AE516C001F65A6 /* PBXContainerItemProxy */;
4399+ sourceTree = BUILT_PRODUCTS_DIR;
4400+ };
4401+ 5268509416AE516C001F65A6 /* RestKit.framework */ = {
4402+ isa = PBXReferenceProxy;
4403+ fileType = wrapper.framework;
4404+ path = RestKit.framework;
4405+ remoteRef = 5268509316AE516C001F65A6 /* PBXContainerItemProxy */;
4406+ sourceTree = BUILT_PRODUCTS_DIR;
4407+ };
4408+ 5268509616AE516C001F65A6 /* RestKitFrameworkTests.octest */ = {
4409+ isa = PBXReferenceProxy;
4410+ fileType = wrapper.cfbundle;
4411+ path = RestKitFrameworkTests.octest;
4412+ remoteRef = 5268509516AE516C001F65A6 /* PBXContainerItemProxy */;
4413+ sourceTree = BUILT_PRODUCTS_DIR;
4414+ };
4415 528515941604F16D004A1F7C /* UbuntuOneAuthKit.a */ = {
4416 isa = PBXReferenceProxy;
4417 fileType = archive.ar;
4418@@ -1356,8 +1442,7 @@
4419 52AC3D811604513E00B4785D /* uncached.png in Resources */,
4420 52AC3D821604513E00B4785D /* uncached@2x.png in Resources */,
4421 52AC3D841604539000B4785D /* Default-568h@2x.png in Resources */,
4422- 52A0430F1606D6C40000B4BC /* OATestServer.rb in Resources */,
4423- 52A043121606D6C40000B4BC /* README in Resources */,
4424+ 526850A816AEE4E1001F65A6 /* Storyboard_iPhone.storyboard in Resources */,
4425 );
4426 runOnlyForDeploymentPostprocessing = 0;
4427 };
4428@@ -1386,27 +1471,17 @@
4429 isa = PBXSourcesBuildPhase;
4430 buildActionMask = 2147483647;
4431 files = (
4432+ 5268510416AEFCB2001F65A6 /* CachedSongsPlaylist.m in Sources */,
4433+ 5268510516AEFCB2001F65A6 /* _U1CachedFile.m in Sources */,
4434+ 5268510616AEFCB2001F65A6 /* U1CachedFile.m in Sources */,
4435 9316628812264A74003B0EB7 /* NSDate+Extras.m in Sources */,
4436- 936F20681227364200070F43 /* Playlist.m in Sources */,
4437- 936F209012273D9000070F43 /* Song.m in Sources */,
4438 936F230A12284D1900070F43 /* NamedTextFieldCell.m in Sources */,
4439 93F3344D1247FA0B006C6707 /* Reachability.m in Sources */,
4440- 93F334521247FA2C006C6707 /* Album.m in Sources */,
4441- 93F334531247FA2C006C6707 /* Artist.m in Sources */,
4442 93F3345C1247FA85006C6707 /* AlbumUITableViewCell.m in Sources */,
4443 93F3345F1247FA97006C6707 /* SongUITableViewCell.m in Sources */,
4444- 93F334711247FB78006C6707 /* U1MusicAppDelegate.m in Sources */,
4445 93F334721247FB78006C6707 /* main.m in Sources */,
4446 93F334751247FB9F006C6707 /* AudioStreamer.m in Sources */,
4447- 93F3349F1247FCDC006C6707 /* ArtistViewController.m in Sources */,
4448- 93F334A01247FCDC006C6707 /* SongViewController.m in Sources */,
4449- 93F334A31247FCDC006C6707 /* ArtistListViewController.m in Sources */,
4450- 93F334A41247FCDC006C6707 /* SettingsViewController.m in Sources */,
4451- 93F334A61247FCDC006C6707 /* AlbumViewController.m in Sources */,
4452- 93F334A71247FCDC006C6707 /* SubsonicTableViewController.m in Sources */,
4453 9354D0AB1248267B00733067 /* NSDictionary+Extras.m in Sources */,
4454- 93EE2AF0124993F100E7E060 /* ArtistListParser.m in Sources */,
4455- 93EE2BA31249F33D00E7E060 /* ArtistParser.m in Sources */,
4456 93BC5209124C181600B7587C /* Subsonic.m in Sources */,
4457 93BC52A7124C1E6900B7587C /* StreamingPlayer.m in Sources */,
4458 93D6B0FF124ED061007880B0 /* SubsonicViewController.m in Sources */,
4459@@ -1416,27 +1491,11 @@
4460 93D6B54B1252CE57007880B0 /* URLQueryStringParser.m in Sources */,
4461 93CCBD7D12540CB700AFFC22 /* AboutViewController.m in Sources */,
4462 932E7B0912552CB400E7C8FF /* PullRefreshTableViewController.m in Sources */,
4463- 9123D1A113257ADF00B40210 /* PlaylistListViewController.m in Sources */,
4464- 9123D1BB13280B3400B40210 /* PlaylistViewController.m in Sources */,
4465- 9123D1C3132816D200B40210 /* PlaylistListParser.m in Sources */,
4466- 91E88609132DA82000618994 /* PlaylistParser.m in Sources */,
4467- 912D392213311F2700A443B2 /* AlbumListViewController.m in Sources */,
4468- 912D392613311FC600A443B2 /* SongListViewController.m in Sources */,
4469- 91B3A4441344CF92006C8193 /* SubsonicIndexedTableViewController.m in Sources */,
4470- 912D1259134617F600721EE4 /* SongListParser.m in Sources */,
4471 912D1264134A162000721EE4 /* AlertPrompt.m in Sources */,
4472- 912D1267134B609700721EE4 /* PlaylistEditViewController.m in Sources */,
4473- 9110DC38134C045A0046B8E4 /* AlbumParser.m in Sources */,
4474- 9110DC44134EAC740046B8E4 /* AlbumListParser.m in Sources */,
4475 9110DC571354A7490046B8E4 /* AlbumArtistUITableViewCell.m in Sources */,
4476 91018B0B13573BBB0051EFDC /* UIImage+Resize.m in Sources */,
4477 91018B0E13573D150051EFDC /* UIImage+Alpha.m in Sources */,
4478 91018B1113573D350051EFDC /* UIImage+RoundedCorner.m in Sources */,
4479- 91018B4B135A724B0051EFDC /* PlaylistEditAlbumListViewController.m in Sources */,
4480- 91018B4C135A724B0051EFDC /* PlaylistEditAlbumViewController.m in Sources */,
4481- 91018B4D135A724B0051EFDC /* PlaylistEditArtistListViewController.m in Sources */,
4482- 91018B4E135A724B0051EFDC /* PlaylistEditArtistViewController.m in Sources */,
4483- 91018B4F135A724B0051EFDC /* PlaylistEditSongListViewController.m in Sources */,
4484 919376F3135CC1CF0030B7BD /* PlaylistEditSongUITableViewCell.m in Sources */,
4485 93DFFE4D135D71760061F29F /* music.xcdatamodeld in Sources */,
4486 93DFFE54135D72420061F29F /* NSManagedObjectContext+Additions.m in Sources */,
4487@@ -1462,13 +1521,6 @@
4488 9619626F14E08F630038DACA /* U1HTTPRequest.m in Sources */,
4489 9619627014E08F630038DACA /* U1HTTPResponse.m in Sources */,
4490 9619627314E0A4930038DACA /* U1HTTPServer.m in Sources */,
4491- 914AC3FF14B61D8A00C7D5A3 /* CachedSongsPlaylist.m in Sources */,
4492- 914AC40014B61D8A00C7D5A3 /* _Album.m in Sources */,
4493- 914AC40114B61D8A00C7D5A3 /* _Artist.m in Sources */,
4494- 914AC40214B61D8A00C7D5A3 /* _Playlist.m in Sources */,
4495- 914AC40314B61D8A00C7D5A3 /* _PlaylistSongIndex.m in Sources */,
4496- 914AC40414B61D8A00C7D5A3 /* _Song.m in Sources */,
4497- 914AC40514B61D8A00C7D5A3 /* PlaylistSongIndex.m in Sources */,
4498 91C8CCAF14B7883600A0E311 /* ArtistUITableViewCell.m in Sources */,
4499 91D3A16F14B93B2A003D4FC0 /* MOC.m in Sources */,
4500 91D3A17214BE12FE003D4FC0 /* PlaylistUITableViewCell.m in Sources */,
4501@@ -1480,29 +1532,32 @@
4502 917B47FB14E42C7900062874 /* U1CacheFileManager.m in Sources */,
4503 91C493D014E4593C00BC1815 /* U1ByteSizeValueTransformer.m in Sources */,
4504 960E4B2E14E586AE002AAB79 /* CacheFileAccess.xcdatamodeld in Sources */,
4505- 960E4B3514E58844002AAB79 /* U1CachedFile.m in Sources */,
4506- 960E4B3814E5884B002AAB79 /* _U1CachedFile.m in Sources */,
4507- 91F2653014EACFCC0027232B /* U1MigrationViewController.m in Sources */,
4508 523B3CDE15B4C42F004394F4 /* SongUITableView.m in Sources */,
4509 523B3CE615B5D814004394F4 /* UOPullGestureRecognizer.m in Sources */,
4510- 52A042FF1606D6C40000B4BC /* NSMutableURLRequest+Parameters.m in Sources */,
4511- 52A043001606D6C40000B4BC /* NSString+URLEncoding.m in Sources */,
4512- 52A043011606D6C40000B4BC /* NSURL+Base.m in Sources */,
4513- 52A043021606D6C40000B4BC /* Base64Transcoder.c in Sources */,
4514- 52A043031606D6C40000B4BC /* hmac.c in Sources */,
4515- 52A043041606D6C40000B4BC /* sha1.c in Sources */,
4516- 52A043051606D6C40000B4BC /* OAAttachment.m in Sources */,
4517- 52A043061606D6C40000B4BC /* OACall.m in Sources */,
4518- 52A043071606D6C40000B4BC /* OAConsumer.m in Sources */,
4519- 52A043081606D6C40000B4BC /* OADataFetcher.m in Sources */,
4520- 52A043091606D6C40000B4BC /* OAHMAC_SHA1SignatureProvider.m in Sources */,
4521- 52A0430A1606D6C40000B4BC /* OAMutableURLRequest.m in Sources */,
4522- 52A0430B1606D6C40000B4BC /* OAPlaintextSignatureProvider.m in Sources */,
4523- 52A0430C1606D6C40000B4BC /* OAProblem.m in Sources */,
4524- 52A0430D1606D6C40000B4BC /* OARequestParameter.m in Sources */,
4525- 52A0430E1606D6C40000B4BC /* OAServiceTicket.m in Sources */,
4526- 52A043101606D6C40000B4BC /* OAToken.m in Sources */,
4527- 52A043111606D6C40000B4BC /* OATokenManager.m in Sources */,
4528+ 526850A916AEE4E1001F65A6 /* UOAppDelegate.m in Sources */,
4529+ 526850AC16AEF9DD001F65A6 /* UOMusic.xcdatamodeld in Sources */,
4530+ 526850C416AEFA59001F65A6 /* AlbumsViewController.m in Sources */,
4531+ 526850C516AEFA59001F65A6 /* AlbumViewController.m in Sources */,
4532+ 526850C616AEFA59001F65A6 /* ArtistsViewController.m in Sources */,
4533+ 526850C716AEFA59001F65A6 /* ArtistViewController.m in Sources */,
4534+ 526850C816AEFA59001F65A6 /* PlayerViewController.m in Sources */,
4535+ 526850C916AEFA59001F65A6 /* PlaylistsViewController.m in Sources */,
4536+ 526850CA16AEFA59001F65A6 /* SettingsAboutViewController.m in Sources */,
4537+ 526850CB16AEFA59001F65A6 /* SettingsAuthenticationViewController.m in Sources */,
4538+ 526850CC16AEFA59001F65A6 /* SettingsViewController.m in Sources */,
4539+ 526850CD16AEFA59001F65A6 /* SongsViewController.m in Sources */,
4540+ 526850CE16AEFA59001F65A6 /* UOIndexedViewController.m in Sources */,
4541+ 526850DE16AEFA7D001F65A6 /* UOWebServiceController.m in Sources */,
4542+ 526850DF16AEFA7D001F65A6 /* PlayerHeaderView.m in Sources */,
4543+ 526850E016AEFA7D001F65A6 /* AlbumCell.m in Sources */,
4544+ 526850E116AEFA7D001F65A6 /* ArtistCell.m in Sources */,
4545+ 526850E216AEFA7D001F65A6 /* PlaylistCell.m in Sources */,
4546+ 526850E316AEFA7D001F65A6 /* SongCell.m in Sources */,
4547+ 526850FF16AEFC6A001F65A6 /* Album.m in Sources */,
4548+ 5268510016AEFC6A001F65A6 /* Artist.m in Sources */,
4549+ 5268510116AEFC6A001F65A6 /* Playlist.m in Sources */,
4550+ 5268510216AEFC6A001F65A6 /* Song.m in Sources */,
4551+ 5268510316AEFC6A001F65A6 /* UOModel.m in Sources */,
4552 );
4553 runOnlyForDeploymentPostprocessing = 0;
4554 };
4555@@ -1536,7 +1591,10 @@
4556 GCC_PREFIX_HEADER = U1Music_Prefix.pch;
4557 GCC_THUMB_SUPPORT = NO;
4558 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
4559- HEADER_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)/usr/local/include";
4560+ HEADER_SEARCH_PATHS = (
4561+ "$(BUILT_PRODUCTS_DIR)/usr/local/include",
4562+ "\"$(BUILT_PRODUCTS_DIR)/../../Headers\"",
4563+ );
4564 INFOPLIST_FILE = "U1Music-Info.plist";
4565 IPHONEOS_DEPLOYMENT_TARGET = 5.0;
4566 LIBRARY_SEARCH_PATHS = (
4567@@ -1544,6 +1602,7 @@
4568 "\"$(SRCROOT)/TestFlight SDK\"",
4569 "$(BUILT_PRODUCTS_DIR)/**",
4570 );
4571+ OTHER_LDFLAGS = "-ObjC";
4572 PRODUCT_NAME = "U1 Music";
4573 PROVISIONING_PROFILE = "";
4574 "PROVISIONING_PROFILE[sdk=*]" = "";
4575@@ -1569,7 +1628,10 @@
4576 GCC_PREFIX_HEADER = U1Music_Prefix.pch;
4577 GCC_THUMB_SUPPORT = NO;
4578 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
4579- HEADER_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)/usr/local/include";
4580+ HEADER_SEARCH_PATHS = (
4581+ "$(BUILT_PRODUCTS_DIR)/usr/local/include",
4582+ "\"$(BUILT_PRODUCTS_DIR)/../../Headers\"",
4583+ );
4584 INFOPLIST_FILE = "U1Music-Info.plist";
4585 IPHONEOS_DEPLOYMENT_TARGET = 5.0;
4586 LIBRARY_SEARCH_PATHS = (
4587@@ -1577,6 +1639,7 @@
4588 "\"$(SRCROOT)/TestFlight SDK\"",
4589 "$(BUILT_PRODUCTS_DIR)/**",
4590 );
4591+ OTHER_LDFLAGS = "-ObjC";
4592 PRODUCT_NAME = "U1 Music";
4593 PROVISIONING_PROFILE = "";
4594 "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
4595@@ -1646,6 +1709,16 @@
4596 /* End XCConfigurationList section */
4597
4598 /* Begin XCVersionGroup section */
4599+ 526850AA16AEF9DD001F65A6 /* UOMusic.xcdatamodeld */ = {
4600+ isa = XCVersionGroup;
4601+ children = (
4602+ 526850AB16AEF9DD001F65A6 /* UOMusic.xcdatamodel */,
4603+ );
4604+ currentVersion = 526850AB16AEF9DD001F65A6 /* UOMusic.xcdatamodel */;
4605+ path = UOMusic.xcdatamodeld;
4606+ sourceTree = "<group>";
4607+ versionGroupType = wrapper.xcdatamodel;
4608+ };
4609 93DFFE4C135D71760061F29F /* music.xcdatamodeld */ = {
4610 isa = XCVersionGroup;
4611 children = (
4612
4613=== modified file 'U1Music_Prefix.pch'
4614--- U1Music_Prefix.pch 2012-09-25 21:28:26 +0000
4615+++ U1Music_Prefix.pch 2013-01-24 17:06:42 +0000
4616@@ -12,6 +12,10 @@
4617 #import <Foundation/Foundation.h>
4618 #import <UIKit/UIKit.h>
4619 #import <CoreData/CoreData.h>
4620+
4621+ #import <SystemConfiguration/SystemConfiguration.h>
4622+ #import <MobileCoreServices/MobileCoreServices.h>
4623+
4624 #import "Globals.h"
4625 #import "MOC.h"
4626 #import "NSManagedObjectContext+Additions.h"
4627
4628=== modified file 'music.xcdatamodeld/U1Music 2.2-31.xcdatamodel/elements'
4629Binary files music.xcdatamodeld/U1Music 2.2-31.xcdatamodel/elements 2012-01-07 04:48:49 +0000 and music.xcdatamodeld/U1Music 2.2-31.xcdatamodel/elements 2013-01-24 17:06:42 +0000 differ
4630=== modified file 'music.xcdatamodeld/U1Music 2.2-31.xcdatamodel/layout'
4631Binary files music.xcdatamodeld/U1Music 2.2-31.xcdatamodel/layout 2012-01-07 04:48:49 +0000 and music.xcdatamodeld/U1Music 2.2-31.xcdatamodel/layout 2013-01-24 17:06:42 +0000 differ

Subscribers

People subscribed via source and target branches