Merge lp:~rockstar/ubuntuone-ios-music/dial-down into lp:~ubuntuone-ios-client-team/ubuntuone-ios-music/moriarty

Proposed by Paul Hummer
Status: Merged
Merge reported by: Paul Hummer
Merged at revision: not available
Proposed branch: lp:~rockstar/ubuntuone-ios-music/dial-down
Merge into: lp:~ubuntuone-ios-client-team/ubuntuone-ios-music/moriarty
Prerequisite: lp:~rockstar/ubuntuone-ios-music/coredata
Diff against target: 1432 lines (+558/-320)
24 files modified
Music/AppDelegate.m (+6/-31)
Music/Categories/RKRequest+Plaintext.h (+0/-13)
Music/Categories/RKRequest+Plaintext.m (+0/-55)
Music/Models/Album.h (+2/-0)
Music/Models/Album.m (+28/-11)
Music/Models/Artist.m (+9/-8)
Music/Models/Playlist.m (+9/-8)
Music/Models/Song.m (+74/-32)
Music/Models/UOModel.h (+2/-2)
Music/Models/UOModel.m (+8/-3)
Music/Utilities/UOWebServiceController.h (+39/-0)
Music/Utilities/UOWebServiceController.m (+204/-0)
Music/View Controllers/AlbumViewController.h (+1/-1)
Music/View Controllers/AlbumViewController.m (+52/-25)
Music/View Controllers/AlbumsViewController.m (+9/-8)
Music/View Controllers/ArtistViewController.h (+1/-1)
Music/View Controllers/ArtistViewController.m (+58/-31)
Music/View Controllers/ArtistsViewController.m (+10/-10)
Music/View Controllers/PlaylistsViewController.m (+8/-7)
Music/View Controllers/SongsViewController.m (+6/-5)
Music/View Controllers/UOIndexedViewController.h (+2/-2)
Music/View Controllers/UOIndexedViewController.m (+21/-37)
U1Music.xcodeproj/project.pbxproj (+6/-21)
U1Music_Prefix.pch (+3/-9)
To merge this branch: bzr merge lp:~rockstar/ubuntuone-ios-music/dial-down
Reviewer Review Type Date Requested Status
Michał Karnicki (community) Approve
Review via email: mp+141684@code.launchpad.net

Description of the change

This branch adds the core data support to the ancilliary views that are dialed
down to through selection. It also warranted an upgrade to Core Data so that
we could only fetch when absolutely necessary. I *think* this is likely to be
the last big branch. Sorry it's so big.

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

if ([error code] == 2) { // Network is down.
-- just nitpicking: a constant instead of comment would be better

int interval = -(60*60*24*5); // 5 days ago
-- this update interval feels arbitrary to me. How do we know that I haven't purchased a music album today?

Couple of lines moved in PlaylistsViewController.m
-- there was no change intentionally, right? I understand you just found a better place for that snippet.

Would it be difficult to add at least some basic tests exercising the updated Core Data model?

I noticed you've set 'Ubuntu One iOS Client Team' as the reviewer. I think you could go with Ubuntu One Client Engineering, I've already dumped the Android equivalent, as we basically became two one-manned sub-teams of Client Engineering after the re-org :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Music/AppDelegate.m'
--- Music/AppDelegate.m 2013-01-02 23:49:22 +0000
+++ Music/AppDelegate.m 2013-01-02 23:49:23 +0000
@@ -37,7 +37,6 @@
37@synthesize storyboard = _storyboard;37@synthesize storyboard = _storyboard;
3838
39- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {39- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
40 [self initRestKit];
4140
42 self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];41 self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
43 42
@@ -164,6 +163,12 @@
164 return _persistentStoreCoordinator;163 return _persistentStoreCoordinator;
165}164}
166165
166#pragma mark - Convenience methods
167
168+ (AppDelegate *)delegate {
169 return (AppDelegate *)[UIApplication sharedApplication].delegate;
170}
171
167#pragma mark - Application's Documents directory172#pragma mark - Application's Documents directory
168173
169// Returns the URL to the application's Documents directory.174// Returns the URL to the application's Documents directory.
@@ -180,34 +185,4 @@
180 [self.window makeKeyAndVisible];185 [self.window makeKeyAndVisible];
181}186}
182187
183#pragma mark - Convenience methods
184
185+ (AppDelegate *)delegate {
186 return (AppDelegate *)[UIApplication sharedApplication].delegate;
187}
188
189#pragma mark - Private methods
190
191- (void)initRestKit {
192 NSDictionary *credentials = [[UOAuthManager sharedAuthManager] oauthCredentials];
193 RKURL *baseURL = [RKURL URLWithBaseURLString:@"https://one.ubuntu.com/api/music/v2"];
194
195 RKObjectManager *objectManager = [RKObjectManager objectManagerWithBaseURL:baseURL];
196 objectManager.client.baseURL = baseURL;
197 objectManager.client.OAuth1ConsumerKey = [credentials objectForKey:UOOAuthConsumerKey];
198 objectManager.client.OAuth1ConsumerSecret = [credentials objectForKey:UOOAuthConsumerSecret];
199 objectManager.client.OAuth1AccessToken = [credentials objectForKey:UOOAuthToken];
200 objectManager.client.OAuth1AccessTokenSecret = [credentials objectForKey:UOOAuthTokenSecret];
201 objectManager.client.authenticationType = RKRequestAuthenticationTypeOAuth1;
202 static NSString *DatabaseName = @"UOMusic.sql";
203
204 RKManagedObjectStore *objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:DatabaseName];
205 objectManager.objectStore = objectStore;
206
207 [Album registerMapping];
208 [Artist registerMapping];
209 [Playlist registerMapping];
210 [Song registerMapping];
211}
212
213@end188@end
214189
=== removed file 'Music/Categories/RKRequest+Plaintext.h'
--- Music/Categories/RKRequest+Plaintext.h 2012-12-07 22:39:22 +0000
+++ Music/Categories/RKRequest+Plaintext.h 1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
1//
2// RKRequest+Plaintext.h
3// U1Music
4//
5// Created by Paul Hummer on 10/5/12.
6// Copyright (c) 2012 Canonical. All rights reserved.
7//
8
9#import <RestKit/RestKit.h>
10
11@interface RKRequest (Plaintext)
12
13@end
140
=== removed file 'Music/Categories/RKRequest+Plaintext.m'
--- Music/Categories/RKRequest+Plaintext.m 2012-12-07 22:39:22 +0000
+++ Music/Categories/RKRequest+Plaintext.m 1970-01-01 00:00:00 +0000
@@ -1,55 +0,0 @@
1//
2// RKRequest+Plaintext.m
3// U1Music
4//
5// Created by Paul Hummer on 10/5/12.
6// Copyright (c) 2012 Canonical. All rights reserved.
7//
8
9#import <RestKit/RestKit.h>
10#import "RKRequest+Plaintext.h"
11#import "UOAuthManager.h"
12
13@implementation RKRequest (Plaintext)
14
15/* rockstar: 5 Oct 2012 - This is as copy/pasted as I could possibly get. It's a hack, and
16 I'm so very very sorry. The fact remains that Ubuntu One doesn't currently support the
17 HMAC-SHA1 signature method, and RestKit's oauth library doesn't support Plaintext. I'm going
18 to work towards getting Plaintext support into RestKit.
19 */
20- (void)addHeadersToRequest
21{
22 NSString *header = nil;
23 for (header in self.additionalHTTPHeaders) {
24 [self.URLRequest setValue:[self.additionalHTTPHeaders valueForKey:header] forHTTPHeaderField:header];
25 }
26
27 [self.URLRequest setValue:nil forHTTPHeaderField:@"Content-Length"];
28
29 /* This is the specific part that needs to be overridden. The OAuth2 stuff has been removed,
30 and since we know that we're using OAuth, we don't check against it.
31 */
32 NSURLRequest *echo = nil;
33
34 // use the suitable parameters dict
35 NSDictionary *parameters = nil;
36 if ([self.params isKindOfClass:[RKParams class]])
37 parameters = [(RKParams *)self.params dictionaryOfPlainTextParams];
38 else
39 parameters = [self.URL queryParameters];
40
41 echo = [UOAuthManager oauthRequestForPath:[self.URL path]];
42 [self.URLRequest setValue:[echo valueForHTTPHeaderField:@"Authorization"] forHTTPHeaderField:@"Authorization"];
43 [self.URLRequest setValue:[echo valueForHTTPHeaderField:@"Accept-Encoding"] forHTTPHeaderField:@"Accept-Encoding"];
44 [self.URLRequest setValue:[echo valueForHTTPHeaderField:@"User-Agent"] forHTTPHeaderField:@"User-Agent"];
45
46 if (self.cachePolicy & RKRequestCachePolicyEtag) {
47 NSString *etag = [self.cache etagForRequest:self];
48 if (etag) {
49 RKLogTrace(@"Setting If-None-Match header to '%@'", etag);
50 [self.URLRequest setValue:etag forHTTPHeaderField:@"If-None-Match"];
51 }
52 }
53}
54
55@end
560
=== modified file 'Music/Models/Album.h'
--- Music/Models/Album.h 2013-01-02 23:49:22 +0000
+++ Music/Models/Album.h 2013-01-02 23:49:23 +0000
@@ -24,4 +24,6 @@
2424
25@property (nonatomic, retain) NSString *artistId;25@property (nonatomic, retain) NSString *artistId;
26@property (nonatomic, retain, readonly) Artist *artist;26@property (nonatomic, retain, readonly) Artist *artist;
27
28@property (nonatomic, retain) NSSet *songs;
27@end29@end
2830
=== modified file 'Music/Models/Album.m'
--- Music/Models/Album.m 2013-01-02 23:49:22 +0000
+++ Music/Models/Album.m 2013-01-02 23:49:23 +0000
@@ -8,6 +8,7 @@
88
9#import "Album.h"9#import "Album.h"
10#import <RestKit/RestKit.h>10#import <RestKit/RestKit.h>
11#import <RestKit/CoreData.h>
11#import "Artist.h"12#import "Artist.h"
12#import "NSString+Extras.h"13#import "NSString+Extras.h"
1314
@@ -24,18 +25,21 @@
24@synthesize artistId;25@synthesize artistId;
25@dynamic artist;26@dynamic artist;
2627
27+ (RKManagedObjectMapping *)objectMapping {28@dynamic songs;
29
30+ (RKEntityMapping *)objectMapping {
28 RKObjectManager *manager = [RKObjectManager sharedManager];31 RKObjectManager *manager = [RKObjectManager sharedManager];
29 32
30 RKManagedObjectMapping *mapping = [RKManagedObjectMapping mappingForClass:[self class] inManagedObjectStore:manager.objectStore];33 RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Album" inManagedObjectStore:manager.managedObjectStore];
31 [mapping mapKeyPath:@"id" toAttribute:@"albumId"];34 [mapping setIdentificationAttributes:@[@"albumId"]];
32 [mapping mapKeyPath:@"album_url" toAttribute:@"url"];35 [mapping addAttributeMappingsFromDictionary:@{
33 [mapping mapKeyPath:@"cover_art" toAttribute:@"art"];36 @"id": @"albumId",
34 [mapping mapKeyPath:@"album_art_url" toAttribute:@"artUrl"];37 @"album_url": @"url",
35 [mapping mapKeyPath:@"title" toAttribute:@"title"];38 @"cover_art": @"art",
36 [mapping mapKeyPath:@"artist_id" toAttribute:@"artistId"];39 @"album_art_url": @"artUrl",
37 40 @"title": @"title",
38 mapping.primaryKeyAttribute = @"albumId";41 @"artist_id": @"artistId"
42 }];
39 43
40 return mapping;44 return mapping;
41}45}
@@ -50,7 +54,20 @@
50}54}
5155
52- (void)setArtistId:(NSString *)_artistId {56- (void)setArtistId:(NSString *)_artistId {
53 Artist *_artist = [Artist findByPrimaryKey:_artistId inContext:self.managedObjectContext];57 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
58 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Artist" inManagedObjectContext:self.managedObjectContext];
59 [fetchRequest setEntity:entity];
60
61 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(artistId = %@)", _artistId];
62 [fetchRequest setPredicate:predicate];
63
64 NSError *error;
65 NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
66 if (error || [results count] != 1) {
67 abort();
68 }
69
70 Artist *_artist = [results objectAtIndex:0];
54 [self setPrimitiveValue:_artist forKey:@"artist"];71 [self setPrimitiveValue:_artist forKey:@"artist"];
55}72}
5673
5774
=== modified file 'Music/Models/Artist.m'
--- Music/Models/Artist.m 2013-01-02 23:49:22 +0000
+++ Music/Models/Artist.m 2013-01-02 23:49:23 +0000
@@ -20,16 +20,17 @@
2020
21@synthesize index;21@synthesize index;
2222
23+ (RKManagedObjectMapping *)objectMapping {23+ (RKEntityMapping *)objectMapping {
24 RKObjectManager *manager = [RKObjectManager sharedManager];24 RKObjectManager *manager = [RKObjectManager sharedManager];
25 25
26 RKManagedObjectMapping *mapping = [RKManagedObjectMapping mappingForClass:[self class] inManagedObjectStore:manager.objectStore];26 RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Artist" inManagedObjectStore:manager.managedObjectStore];
27 [mapping mapKeyPath:@"id" toAttribute:@"artistId"];27 [mapping setIdentificationAttributes:@[@"artistId"]];
28 [mapping mapKeyPath:@"artist" toAttribute:@"name"];28 [mapping addAttributeMappingsFromDictionary:@{
29 [mapping mapKeyPath:@"artist_url" toAttribute:@"url"];29 @"id" : @"artistId",
30 [mapping mapKeyPath:@"artist_art_url" toAttribute:@"artUrl"];30 @"artist": @"name",
31 31 @"artist_url": @"url",
32 mapping.primaryKeyAttribute = @"artistId";32 @"artist_art_url": @"artUrl",
33 }];
33 return mapping;34 return mapping;
34}35}
3536
3637
=== modified file 'Music/Models/Playlist.m'
--- Music/Models/Playlist.m 2013-01-02 23:49:22 +0000
+++ Music/Models/Playlist.m 2013-01-02 23:49:23 +0000
@@ -19,16 +19,17 @@
1919
20@synthesize index;20@synthesize index;
2121
22+ (RKManagedObjectMapping *)objectMapping {22+ (RKEntityMapping *)objectMapping {
23 RKObjectManager *manager = [RKObjectManager sharedManager];23 RKObjectManager *manager = [RKObjectManager sharedManager];
24 24
25 RKManagedObjectMapping *mapping = [RKManagedObjectMapping mappingForClass:[self class] inManagedObjectStore:manager.objectStore];25 RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Playlist" inManagedObjectStore:manager.managedObjectStore];
26 [mapping mapKeyPath:@"id" toAttribute:@"playlistId"];26 [mapping setIdentificationAttributes:@[@"playlistId"]];
27 [mapping mapKeyPath:@"playlist_url" toAttribute:@"url"];27 [mapping addAttributeMappingsFromDictionary:@{
28 [mapping mapKeyPath:@"name" toAttribute:@"title"];28 @"id": @"playlistId",
29 [mapping mapKeyPath:@"song_count" toAttribute:@"songCount"];29 @"playlist_url": @"url",
30 30 @"name": @"title",
31 mapping.primaryKeyAttribute = @"playlistId";31 @"song_count": @"songCount",
32 }];
32 return mapping;33 return mapping;
33}34}
3435
3536
=== modified file 'Music/Models/Song.m'
--- Music/Models/Song.m 2013-01-02 23:49:22 +0000
+++ Music/Models/Song.m 2013-01-02 23:49:23 +0000
@@ -33,35 +33,35 @@
3333
34@synthesize index;34@synthesize index;
3535
36@synthesize album = _album;36@dynamic album;
37@synthesize artist = _artist;37@dynamic artist;
38@synthesize albumArtist = _albumArtist;38@dynamic albumArtist;
3939
40+ (RKManagedObjectMapping *)objectMapping {40+ (RKEntityMapping *)objectMapping {
41 RKObjectManager *manager = [RKObjectManager sharedManager];41 RKObjectManager *manager = [RKObjectManager sharedManager];
42 42
43 RKManagedObjectMapping *mapping = [RKManagedObjectMapping mappingForClass:[self class] inManagedObjectStore:manager.objectStore];43 RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Song" inManagedObjectStore:manager.managedObjectStore];
44 44 [mapping setIdentificationAttributes:@[@"songId"]];
45 [mapping mapKeyPath:@"song_url" toAttribute:@"url"];45 [mapping addAttributeMappingsFromDictionary:@{
46 [mapping mapKeyPath:@"song_art_url" toAttribute:@"artUrl"];46 @"song_url": @"url",
47 [mapping mapKeyPath:@"suffix" toAttribute:@"suffix"];47 @"song_art_url": @"artUrl",
48 [mapping mapKeyPath:@"track" toAttribute:@"track"];48 @"suffix": @"suffix",
49 [mapping mapKeyPath:@"title" toAttribute:@"title"];49 @"track": @"track",
50 [mapping mapKeyPath:@"album_artist_id" toAttribute:@"albumArtistId"];50 @"title": @"title",
51 [mapping mapKeyPath:@"bit_rate" toAttribute:@"bitRate"];51 @"album_artist_id": @"albumArtistId",
52 [mapping mapKeyPath:@"id" toAttribute:@"songId"];52 @"bit_rate": @"bitRate",
53 [mapping mapKeyPath:@"duration" toAttribute:@"duration"];53 @"id": @"songId",
54 [mapping mapKeyPath:@"disc_number" toAttribute:@"discNumber"];54 @"duration": @"duration",
55 [mapping mapKeyPath:@"song_stream_url" toAttribute:@"streamUrl"];55 @"disc_number": @"discNumber",
56 [mapping mapKeyPath:@"content_type" toAttribute:@"contentType"];56 @"song_stream_url": @"streamUrl",
57 [mapping mapKeyPath:@"year" toAttribute:@"year"];57 @"content_type": @"contentType",
58 [mapping mapKeyPath:@"genre" toAttribute:@"genre"];58 @"year": @"year",
59 [mapping mapKeyPath:@"path" toAttribute:@"path"];59 @"genre": @"genre",
60 [mapping mapKeyPath:@"artist_id" toAttribute:@"artistId"];60 @"path": @"path",
61 [mapping mapKeyPath:@"album_id" toAttribute:@"albumId"];61 @"artist_id": @"artistId",
62 [mapping mapKeyPath:@"size" toAttribute:@"size"];62 @"album_id": @"albumId",
63 63 @"size": @"size"
64 mapping.primaryKeyAttribute = @"songId";64 }];
65 return mapping;65 return mapping;
66}66}
6767
@@ -81,24 +81,66 @@
81 return _index;81 return _index;
82}82}
8383
84- (void)setArtistId:(NSString *)artistId {84- (void)setArtistId:(NSString *)_artistId {
85 _artist = [Artist findByPrimaryKey:artistId inContext:self.managedObjectContext];85 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
86 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Artist" inManagedObjectContext:self.managedObjectContext];
87 [fetchRequest setEntity:entity];
88
89 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(artistId = %@)", _artistId];
90 [fetchRequest setPredicate:predicate];
91
92 NSError *error;
93 NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
94 if (error || [results count] != 1) {
95 abort();
96 }
97
98 Artist *_artist = [results objectAtIndex:0];
99 [self setPrimitiveValue:_artist forKey:@"artist"];
86}100}
87101
88- (NSString *)artistId {102- (NSString *)artistId {
89 return self.artist.artistId;103 return self.artist.artistId;
90}104}
91105
92- (void)setAlbumId:(NSString *)albumId {106- (void)setAlbumId:(NSString *)_albumId {
93 _album = [Album findByPrimaryKey:albumId inContext:self.managedObjectContext];107 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
108 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Album" inManagedObjectContext:self.managedObjectContext];
109 [fetchRequest setEntity:entity];
110
111 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(albumId = %@)", _albumId];
112 [fetchRequest setPredicate:predicate];
113
114 NSError *error;
115 NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
116 if (error || [results count] != 1) {
117 abort();
118 }
119
120 Artist *_artist = [results objectAtIndex:0];
121 [self setPrimitiveValue:_artist forKey:@"album"];
94}122}
95123
96- (NSString *)albumId {124- (NSString *)albumId {
97 return self.album.albumId;125 return self.album.albumId;
98}126}
99127
100- (void)setAlbumArtistId:(NSString *)albumArtistId {128- (void)setAlbumArtistId:(NSString *)_albumArtistId {
101 _albumArtist = [Artist findByPrimaryKey:albumArtistId inContext:self.managedObjectContext];129 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
130 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Artist" inManagedObjectContext:self.managedObjectContext];
131 [fetchRequest setEntity:entity];
132
133 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(artistId = %@)", _albumArtistId];
134 [fetchRequest setPredicate:predicate];
135
136 NSError *error;
137 NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
138 if (error || [results count] != 1) {
139 abort();
140 }
141
142 Artist *_artist = [results objectAtIndex:0];
143 [self setPrimitiveValue:_artist forKey:@"albumArtist"];
102}144}
103145
104- (NSString *)albumArtistId {146- (NSString *)albumArtistId {
105147
=== modified file 'Music/Models/UOModel.h'
--- Music/Models/UOModel.h 2013-01-02 23:49:22 +0000
+++ Music/Models/UOModel.h 2013-01-02 23:49:23 +0000
@@ -8,10 +8,10 @@
88
9#import <CoreData/CoreData.h>9#import <CoreData/CoreData.h>
1010
11@class RKManagedObjectMapping;11@class RKEntityMapping;
1212
13@interface UOModel : NSManagedObject13@interface UOModel : NSManagedObject
14+ (void)registerMapping;14+ (void)registerMapping;
15+ (RKManagedObjectMapping *)objectMapping;15+ (RKEntityMapping *)objectMapping;
16+ (NSString *)keyPath;16+ (NSString *)keyPath;
17@end17@end
1818
=== modified file 'Music/Models/UOModel.m'
--- Music/Models/UOModel.m 2013-01-02 23:49:22 +0000
+++ Music/Models/UOModel.m 2013-01-02 23:49:23 +0000
@@ -13,13 +13,18 @@
1313
14+ (void)registerMapping {14+ (void)registerMapping {
15 RKObjectManager *manager = [RKObjectManager sharedManager];15 RKObjectManager *manager = [RKObjectManager sharedManager];
16 [manager.mappingProvider setMapping:[self objectMapping] forKeyPath:[self keyPath]];16
17 RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[self objectMapping]
18 pathPattern:nil
19 keyPath:[self keyPath]
20 statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
21 [manager addResponseDescriptor:responseDescriptor];
17}22}
1823
19+ (RKManagedObjectMapping *)objectMapping {24+ (RKEntityMapping *)objectMapping {
20 RKObjectManager *manager = [RKObjectManager sharedManager];25 RKObjectManager *manager = [RKObjectManager sharedManager];
21 26
22 RKManagedObjectMapping *mapping = [RKManagedObjectMapping mappingForClass:[self class] inManagedObjectStore:manager.objectStore];27 RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"" inManagedObjectStore:manager.managedObjectStore];
23 return mapping;28 return mapping;
24}29}
2530
2631
=== added file 'Music/Utilities/UOWebServiceController.h'
--- Music/Utilities/UOWebServiceController.h 1970-01-01 00:00:00 +0000
+++ Music/Utilities/UOWebServiceController.h 2013-01-02 23:49:23 +0000
@@ -0,0 +1,39 @@
1//
2// UOWebServiceController.h
3// U1Music
4//
5// Created by Paul Hummer on 12/12/12.
6// Copyright (c) 2012 Canonical. All rights reserved.
7//
8
9#import <Foundation/Foundation.h>
10#import <RestKit/RestKit.h>
11
12#define ALBUMS_LAST_UPDATED @"albumsLastUpdated"
13#define ARTISTS_LAST_UPDATED @"artistsLastUpdated"
14#define PLAYLISTS_LAST_UPDATED @"playlistsLastUpdated"
15#define SONGS_LAST_UPDATED @"songsLastUpdated"
16
17@protocol UOWebServiceDelegate <NSObject>
18
19- (void)webserviceUpdateComplete;
20- (void)webserviceUpdateError:(NSError *)error;
21
22@end
23
24@interface UOWebServiceController : NSObject
25+ (UOWebServiceController *)controller;
26
27- (void)updateAlbums:(id<UOWebServiceDelegate>)delegate;
28- (void)updateAlbums:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache;
29
30- (void)updateArtists:(id<UOWebServiceDelegate>)delegate;
31- (void)updateArtists:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache;
32
33- (void)updatePlaylists:(id<UOWebServiceDelegate>)delegate;
34- (void)updatePlaylists:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache;
35
36- (void)updateSongs:(id<UOWebServiceDelegate>)delegate;
37- (void)updateSongs:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache;
38
39@end
040
=== added file 'Music/Utilities/UOWebServiceController.m'
--- Music/Utilities/UOWebServiceController.m 1970-01-01 00:00:00 +0000
+++ Music/Utilities/UOWebServiceController.m 2013-01-02 23:49:23 +0000
@@ -0,0 +1,204 @@
1//
2// UOWebServiceController.m
3// U1Music
4//
5// Created by Paul Hummer on 12/12/12.
6// Copyright (c) 2012 Canonical. All rights reserved.
7//
8
9#import "UOWebServiceController.h"
10#import <RestKit/RestKit.h>
11#import <RestKit/CoreData.h>
12#import "UONetworkStatusCoordinator.h"
13#import "UOAuthManager.h"
14#import "AppDelegate.h"
15
16#import "Album.h"
17#import "Artist.h"
18#import "Playlist.h"
19#import "Song.h"
20
21@interface UOWebServiceController ()
22- (void)updateAlbumsWithBlock:(void(^)(void))completionBlock;
23- (void)updateArtistsWithBlock:(void(^)(void))completionBlock;
24- (void)updateSongsWithBlock:(void(^)(void))completionBlock;
25@end
26
27@implementation UOWebServiceController
28
29- (id)init {
30 self = [super init];
31 [self initRestKit];
32 return self;
33}
34
35#pragma mark - Static methods
36
37+ (UOWebServiceController *)controller {
38 static UOWebServiceController *instance = nil;
39 static dispatch_once_t once;
40 dispatch_once(&once, ^{
41 instance = [[UOWebServiceController alloc] init];
42 });
43 return instance;
44}
45
46#pragma mark - Network operations
47
48- (void)updateAlbums:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache {
49 if (clearCache || [self needsUpdating:ALBUMS_LAST_UPDATED]) {
50 [self updateArtistsWithBlock:^(void) {
51 [[RKObjectManager sharedManager] getObjectsAtPath:@"albums/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
52 [delegate webserviceUpdateComplete];
53 } failure:^(RKObjectRequestOperation *operation, NSError *error) {
54 [[NSUserDefaults standardUserDefaults] setObject:nil forKey:ALBUMS_LAST_UPDATED];
55 [delegate webserviceUpdateError:error];
56 }];
57 }];
58 }
59}
60
61- (void)updateAlbums:(id<UOWebServiceDelegate>)delegate {
62 [self updateAlbums:delegate clearCache:NO];
63}
64
65- (void)updateAlbumsWithBlock:(void (^)(void))completionBlock {
66 if ([self needsUpdating:ALBUMS_LAST_UPDATED]) {
67 [self updateArtistsWithBlock:^(void) {
68 [[RKObjectManager sharedManager] getObjectsAtPath:@"albums/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
69 [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:ALBUMS_LAST_UPDATED];
70 completionBlock();
71 } failure:^(RKObjectRequestOperation *operation, NSError *error) {
72 [[NSUserDefaults standardUserDefaults] setObject:nil forKey:ALBUMS_LAST_UPDATED];
73 }];
74 }];
75 } else {
76 completionBlock();
77 }
78}
79
80- (void)updateArtists:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache {
81 if (clearCache || [self needsUpdating:ARTISTS_LAST_UPDATED]) {
82 [[RKObjectManager sharedManager] getObjectsAtPath:@"artists/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
83 [delegate webserviceUpdateComplete];
84 } failure:^(RKObjectRequestOperation *operation, NSError *error) {
85 [[NSUserDefaults standardUserDefaults] setObject:nil forKey:ARTISTS_LAST_UPDATED];
86 [delegate webserviceUpdateError:error];
87 }];
88 }
89}
90
91- (void)updateArtists:(id<UOWebServiceDelegate>)delegate {
92 [self updateArtists:delegate clearCache:NO];
93}
94
95- (void)updateArtistsWithBlock:(void(^)(void))completionBlock {
96 if ([self needsUpdating:ARTISTS_LAST_UPDATED]) {
97 [[RKObjectManager sharedManager] getObjectsAtPath:@"artists/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
98 [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:ARTISTS_LAST_UPDATED];
99 completionBlock();
100 } failure:^(RKObjectRequestOperation *operation, NSError *error) {
101 [[NSUserDefaults standardUserDefaults] setObject:nil forKey:ARTISTS_LAST_UPDATED];
102 }];
103 } else {
104 completionBlock();
105 }
106}
107
108- (void)updatePlaylists:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache {
109 if (clearCache || [self needsUpdating:PLAYLISTS_LAST_UPDATED]) {
110 [self updateSongsWithBlock:^(void) {
111 [[RKObjectManager sharedManager] getObjectsAtPath:@"playlists/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
112 [delegate webserviceUpdateComplete];
113 } failure:^(RKObjectRequestOperation *operation, NSError *error) {
114 [[NSUserDefaults standardUserDefaults] setObject:nil forKey:PLAYLISTS_LAST_UPDATED];
115 [delegate webserviceUpdateError:error];
116 }];
117 }];
118 }
119}
120
121- (void)updatePlaylists:(id<UOWebServiceDelegate>)delegate {
122 [self updatePlaylists:delegate clearCache:NO];
123}
124
125- (void)updateSongs:(id<UOWebServiceDelegate>)delegate clearCache:(BOOL)clearCache {
126 if (clearCache || [self needsUpdating:SONGS_LAST_UPDATED]) {
127 [self updateAlbumsWithBlock:^(void) {
128 [[RKObjectManager sharedManager] getObjectsAtPath:@"songs/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
129 [delegate webserviceUpdateComplete];
130 } failure:^(RKObjectRequestOperation *operation, NSError *error) {
131 [[NSUserDefaults standardUserDefaults] setObject:nil forKey:SONGS_LAST_UPDATED];
132 [delegate webserviceUpdateError:error];
133 }];
134 }];
135 }
136}
137
138- (void)updateSongs:(id<UOWebServiceDelegate>)delegate {
139 [self updateSongs:delegate clearCache:NO];
140}
141
142- (void)updateSongsWithBlock:(void (^)(void))completionBlock {
143 if ([self needsUpdating:SONGS_LAST_UPDATED]) {
144 [self updateAlbumsWithBlock:^(void) {
145 [[RKObjectManager sharedManager] getObjectsAtPath:@"songs/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
146 [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:SONGS_LAST_UPDATED];
147 completionBlock();
148 } failure:^(RKObjectRequestOperation *operation, NSError *error) {
149 [[NSUserDefaults standardUserDefaults] setObject:nil forKey:SONGS_LAST_UPDATED];
150 }];
151 }];
152 } else {
153 completionBlock();
154 }
155}
156
157#pragma mark - Private methods
158
159- (BOOL)needsUpdating:(NSString *)key {
160 int interval = -(60*60*24*5); // 5 days ago
161 NSDate *freshInterval = [NSDate dateWithTimeIntervalSinceNow:interval];
162 NSDate *lastUpdatedAt = [[NSUserDefaults standardUserDefaults] objectForKey:key];
163
164 BOOL updateNeeded = (lastUpdatedAt == nil || [freshInterval compare:lastUpdatedAt] == NSOrderedDescending);
165 if (updateNeeded) {
166 [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:key];
167 }
168 return updateNeeded;
169}
170
171- (void)initRestKit {
172
173 NSURL *baseUrl = [NSURL URLWithString:@"https://one.ubuntu.com/api/music/v2/"];
174 RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseUrl];
175
176 /* Handle Plaintext auth */
177 NSURLRequest *echo = [UOAuthManager oauthRequestForPath:[baseUrl path]];
178 [objectManager.HTTPClient setDefaultHeader:@"Authorization" value:[echo valueForHTTPHeaderField:@"Authorization"]];
179 [objectManager.HTTPClient setDefaultHeader:@"Accept-Encoding" value:[echo valueForHTTPHeaderField:@"Accept-Encoding"]];
180 [objectManager.HTTPClient setDefaultHeader:@"User-Agent" value:[echo valueForHTTPHeaderField:@"User-Agent"]];
181
182 /* Show animated network I/O indicator when doing network I/O */
183 [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
184
185 /* Set up managed object store */
186 NSManagedObjectModel *managedObjectModel = [[AppDelegate delegate] managedObjectModel];
187 RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
188
189 /* Why the hell is RestKit not smart enough to do this automatically? Annoy. */
190 NSError *error;
191 [managedObjectStore addSQLitePersistentStoreAtPath:[RKApplicationDataDirectory() stringByAppendingPathComponent:@"UOMusic.sqlite"] fromSeedDatabaseAtPath:nil withConfiguration:nil options:nil error:&error];
192 if (error) {
193 abort();
194 }
195 [objectManager setManagedObjectStore:managedObjectStore];
196 [managedObjectStore createManagedObjectContexts];
197
198 [Album registerMapping];
199 [Artist registerMapping];
200 [Playlist registerMapping];
201 [Song registerMapping];
202}
203
204@end
0205
=== modified file 'Music/View Controllers/AlbumViewController.h'
--- Music/View Controllers/AlbumViewController.h 2012-11-18 16:01:56 +0000
+++ Music/View Controllers/AlbumViewController.h 2013-01-02 23:49:23 +0000
@@ -11,5 +11,5 @@
11@class Album;11@class Album;
1212
13@interface AlbumViewController : UIViewController13@interface AlbumViewController : UIViewController
14@property (nonatomic, retain) Album *album;14@property (nonatomic, retain) NSString *albumId;
15@end15@end
1616
=== modified file 'Music/View Controllers/AlbumViewController.m'
--- Music/View Controllers/AlbumViewController.m 2013-01-02 23:49:22 +0000
+++ Music/View Controllers/AlbumViewController.m 2013-01-02 23:49:23 +0000
@@ -11,10 +11,12 @@
11#import <RestKit/RestKit.h>11#import <RestKit/RestKit.h>
12#import "SongCell.h"12#import "SongCell.h"
13#import "Song.h"13#import "Song.h"
14#import "UONetworkStatusCoordinator.h"14#import "UOWebServiceController.h"
1515
16@interface AlbumViewController () <RKObjectLoaderDelegate, UITableViewDataSource> {16@interface AlbumViewController () <UITableViewDataSource, UOWebServiceDelegate> {
17 NSArray *tableData;17 NSArray *tableData;
18
19 Album *album;
18}20}
19@property (weak, nonatomic) IBOutlet UIImageView *albumArt;21@property (weak, nonatomic) IBOutlet UIImageView *albumArt;
20@property (weak, nonatomic) IBOutlet UILabel *albumTitle;22@property (weak, nonatomic) IBOutlet UILabel *albumTitle;
@@ -24,18 +26,26 @@
24@end26@end
2527
26@implementation AlbumViewController28@implementation AlbumViewController
29@synthesize albumId = _albumId;
2730
28- (void)viewDidLoad {31- (void)viewDidLoad {
29 [self.tableView setDataSource:self];32 [self.tableView setDataSource:self];
30}33}
3134
32- (void)viewWillAppear:(BOOL)animated {35- (void)viewWillAppear:(BOOL)animated {
33 [_albumTitle setText:_album.title];36 [self fetchAlbum];
34 //[_albumDescription setText:_album.artist];37
35 tableData = [NSArray array];38
36 [self.tableView reloadData];39 [_albumTitle setText:album.title];
37 40 [_albumDescription setText:album.artist.name];
38 [self update];41
42 if ([album.songs count]) {
43 NSArray *sortDescriptors = [NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"track" ascending:NO], nil];
44 tableData = [album.songs sortedArrayUsingDescriptors:sortDescriptors];
45 [self.tableView reloadData];
46 } else {
47 [[UOWebServiceController controller] updateSongs:self];
48 }
39}49}
4050
41- (void)viewDidUnload {51- (void)viewDidUnload {
@@ -62,24 +72,41 @@
6272
63#pragma mark - Private methods73#pragma mark - Private methods
6474
65- (void)update {75- (void)fetchAlbum {
66 [UONetworkStatusCoordinator addNetworkActivity];76 NSManagedObjectContext *managedObjectContext = [[[RKObjectManager sharedManager] managedObjectStore] persistentStoreManagedObjectContext];
67 77
68 NSString *endpoint = [NSString stringWithFormat:@"/albums/%@/", _album.albumId];78 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
69 [[RKObjectManager sharedManager] loadObjectsAtResourcePath:endpoint delegate:self];79 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Album" inManagedObjectContext:managedObjectContext];
70}80 [fetchRequest setEntity:entity];
7181
72#pragma mark - RKObjectLoaderDelegate methods82 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(albumId = %@)", _albumId];
7383 [fetchRequest setPredicate:predicate];
74- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {84
75 [UONetworkStatusCoordinator removeNetworkActivity];85 NSError *error;
86 NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
87 if (error || [results count] != 1) {
88 abort();
89 }
90 album = [results objectAtIndex:0];
91}
92
93#pragma mark - UOWebServiceDelegate methods
94
95- (void)webserviceUpdateComplete {
96 NSManagedObjectContext *managedObjectContext = [[[RKObjectManager sharedManager] managedObjectStore] persistentStoreManagedObjectContext];
97 [managedObjectContext refreshObject:album mergeChanges:NO];
98
99 NSArray *sortDescriptors = [NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"dearticlizedTitle" ascending:YES], nil];
100 tableData = [album.songs sortedArrayUsingDescriptors:sortDescriptors];
101
102 [self.tableView reloadData];
103}
104
105- (void)webserviceUpdateError:(NSError *)error {
106 if ([error code] == 2) { // Network is down.
107 return;
108 }
76 NSLog(@"Error: %@", [error localizedDescription]);109 NSLog(@"Error: %@", [error localizedDescription]);
77}110}
78111
79- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
80 [UONetworkStatusCoordinator removeNetworkActivity];
81 tableData = [objects copy];
82 [self.tableView reloadData];
83}
84
85@end112@end
86113
=== modified file 'Music/View Controllers/AlbumsViewController.m'
--- Music/View Controllers/AlbumsViewController.m 2013-01-02 23:49:22 +0000
+++ Music/View Controllers/AlbumsViewController.m 2013-01-02 23:49:23 +0000
@@ -12,6 +12,7 @@
12#import "Album.h"12#import "Album.h"
13#import "AlbumCell.h"13#import "AlbumCell.h"
14#import "AlbumViewController.h"14#import "AlbumViewController.h"
15#import "UOWebServiceController.h"
1516
16@interface AlbumsViewController ()17@interface AlbumsViewController ()
1718
@@ -21,8 +22,10 @@
2122
22#pragma mark - UOIndexedViewControllers methods23#pragma mark - UOIndexedViewControllers methods
2324
24- (NSString *)endpoint {25- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
25 return @"/albums/";26 Album *album = [self.fetchedResultsController objectAtIndexPath:indexPath];
27 AlbumCell *albumCell = (AlbumCell *)cell;
28 [albumCell setAlbum:album];
26}29}
2730
28- (NSString *)entityName {31- (NSString *)entityName {
@@ -30,7 +33,7 @@
30}33}
3134
32- (NSString *)lastUpdatedKey {35- (NSString *)lastUpdatedKey {
33 return @"albumsLastUpdated";36 return ALBUMS_LAST_UPDATED;
34}37}
3538
36- (NSArray *)sortDescriptors {39- (NSArray *)sortDescriptors {
@@ -39,10 +42,8 @@
39 nil];42 nil];
40}43}
4144
42- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {45- (void)update {
43 Album *album = [self.fetchedResultsController objectAtIndexPath:indexPath];46 [[UOWebServiceController controller] updateAlbums:self];
44 AlbumCell *albumCell = (AlbumCell *)cell;
45 [albumCell setAlbum:album];
46}47}
4748
48#pragma mark - Storyboard methods49#pragma mark - Storyboard methods
@@ -53,7 +54,7 @@
53 NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];54 NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
54 Album *album = [self.fetchedResultsController objectAtIndexPath:indexPath];55 Album *album = [self.fetchedResultsController objectAtIndexPath:indexPath];
55 56
56 albumViewController.album = album;57 albumViewController.albumId = album.albumId;
57}58}
5859
59@end60@end
6061
=== modified file 'Music/View Controllers/ArtistViewController.h'
--- Music/View Controllers/ArtistViewController.h 2012-11-18 15:47:37 +0000
+++ Music/View Controllers/ArtistViewController.h 2013-01-02 23:49:23 +0000
@@ -11,5 +11,5 @@
11@class Artist;11@class Artist;
1212
13@interface ArtistViewController : UIViewController13@interface ArtistViewController : UIViewController
14@property (nonatomic, retain) Artist *artist;14@property (nonatomic, retain) NSString *artistId;
15@end15@end
1616
=== modified file 'Music/View Controllers/ArtistViewController.m'
--- Music/View Controllers/ArtistViewController.m 2013-01-02 23:49:22 +0000
+++ Music/View Controllers/ArtistViewController.m 2013-01-02 23:49:23 +0000
@@ -14,9 +14,13 @@
14#import "Album.h"14#import "Album.h"
15#import "AlbumCell.h"15#import "AlbumCell.h"
16#import "AlbumViewController.h"16#import "AlbumViewController.h"
17#import "UOWebServiceController.h"
18#import "AppDelegate.h"
1719
18@interface ArtistViewController () <RKObjectLoaderDelegate,UITableViewDataSource> {20@interface ArtistViewController () <UITableViewDataSource, UOWebServiceDelegate> {
19 NSArray *tableData;21 NSArray *tableData;
22
23 Artist *artist;
20}24}
21@property (weak, nonatomic) IBOutlet UIImageView *albumArt;25@property (weak, nonatomic) IBOutlet UIImageView *albumArt;
22@property (weak, nonatomic) IBOutlet UILabel *artistName;26@property (weak, nonatomic) IBOutlet UILabel *artistName;
@@ -26,20 +30,26 @@
26@end30@end
2731
28@implementation ArtistViewController32@implementation ArtistViewController
29@synthesize artist = _artist;33@synthesize artistId = _artistId;
3034
31- (void)viewDidLoad {35- (void)viewDidLoad {
32 [self.tableView setDataSource:self];36 [self.tableView setDataSource:self];
33}37}
3438
35- (void)viewWillAppear:(BOOL)animated {39- (void)viewWillAppear:(BOOL)animated {
36 [_artistName setText:_artist.name];40 [[UOWebServiceController controller] updateAlbums:self];
37 // TODO: rockstar - fix this once we have that data again.41 [self fetchArtist];
38 [_artistDescription setText:@"5 songs"];42
39 tableData = [NSArray array];43 [_artistName setText:artist.name];
44
45 NSString *pluralizedNoun = @"albums";
46 if ([artist.albums count] == 1) {
47 pluralizedNoun = @"album";
48 }
49 [_artistDescription setText:[NSString stringWithFormat:@"%d %@", [artist.albums count], pluralizedNoun]];
50 NSArray *sortDescriptors = [NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"dearticlizedTitle" ascending:YES], nil];
51 tableData = [artist.albums sortedArrayUsingDescriptors:sortDescriptors];
40 [self.tableView reloadData];52 [self.tableView reloadData];
41
42 [self update];
43}53}
4454
45- (void)viewDidUnload {55- (void)viewDidUnload {
@@ -64,33 +74,50 @@
64 return cell;74 return cell;
65}75}
6676
67#pragma mark - Private methods
68
69- (void)update {
70 [UONetworkStatusCoordinator addNetworkActivity];
71
72 NSString *endpoint = [NSString stringWithFormat:@"/artists/%@/", _artist.artistId];
73 [[RKObjectManager sharedManager] loadObjectsAtResourcePath:endpoint delegate:self];
74}
75
76#pragma mark - RKObjectLoaderDelegate methods
77
78- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
79 [UONetworkStatusCoordinator removeNetworkActivity];
80 NSLog(@"Error: %@", [error localizedDescription]);
81}
82
83- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
84 [UONetworkStatusCoordinator removeNetworkActivity];
85 tableData = [objects copy];
86 [self.tableView reloadData];
87}
88
89- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {77- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
90 AlbumViewController *albumViewController = [segue destinationViewController];78 AlbumViewController *albumViewController = [segue destinationViewController];
91 NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];79 NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
92 Album *album = [tableData objectAtIndex:indexPath.row];80 Album *album = [tableData objectAtIndex:indexPath.row];
93 albumViewController.album = album;81 albumViewController.albumId = album.albumId;
82}
83
84#pragma mark - UOWebServiceDelegate methods
85
86- (void)webserviceUpdateComplete {
87 NSManagedObjectContext *managedObjectContext = [[[RKObjectManager sharedManager] managedObjectStore] persistentStoreManagedObjectContext];
88 [managedObjectContext refreshObject:artist mergeChanges:NO];
89
90 NSArray *sortDescriptors = [NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"dearticlizedTitle" ascending:YES], nil];
91 tableData = [artist.albums sortedArrayUsingDescriptors:sortDescriptors];
92
93 [self.tableView reloadData];
94}
95
96- (void)webserviceUpdateError:(NSError *)error {
97 if ([error code] == 2) { // Network is down.
98 return;
99 }
100 NSLog(@"Error: %@", [error localizedDescription]);
101}
102
103#pragma mark - Private methods
104
105- (void)fetchArtist {
106 NSManagedObjectContext *managedObjectContext = [[[RKObjectManager sharedManager] managedObjectStore] persistentStoreManagedObjectContext];
107
108 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
109 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Artist" inManagedObjectContext:managedObjectContext];
110 [fetchRequest setEntity:entity];
111
112 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(artistId = %@)", _artistId];
113 [fetchRequest setPredicate:predicate];
114
115 NSError *error;
116 NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
117 if (error || [results count] != 1) {
118 abort();
119 }
120 artist = [results objectAtIndex:0];
94}121}
95122
96@end123@end
97124
=== modified file 'Music/View Controllers/ArtistsViewController.m'
--- Music/View Controllers/ArtistsViewController.m 2013-01-02 23:49:22 +0000
+++ Music/View Controllers/ArtistsViewController.m 2013-01-02 23:49:23 +0000
@@ -15,6 +15,7 @@
1515
16#import "UONetworkStatusCoordinator.h"16#import "UONetworkStatusCoordinator.h"
17#import "ArtistViewController.h"17#import "ArtistViewController.h"
18#import "UOWebServiceController.h"
1819
19@interface ArtistsViewController ()20@interface ArtistsViewController ()
20@end21@end
@@ -23,8 +24,11 @@
2324
24#pragma mark - UOIndexedViewController methods25#pragma mark - UOIndexedViewController methods
2526
26- (NSString *)endpoint {27- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
27 return @"/artists/";28 Artist *artist = [self.fetchedResultsController objectAtIndexPath:indexPath];
29 ArtistCell *artistCell = (ArtistCell *)cell;
30
31 [artistCell setArtist:artist];
28}32}
2933
30- (NSString *)entityName {34- (NSString *)entityName {
@@ -32,8 +36,7 @@
32}36}
3337
34- (NSString *)lastUpdatedKey {38- (NSString *)lastUpdatedKey {
35 39return ARTISTS_LAST_UPDATED;
36 return @"artistsLastUpdated";
37}40}
3841
39- (NSArray *)sortDescriptors {42- (NSArray *)sortDescriptors {
@@ -42,11 +45,8 @@
42 nil];45 nil];
43}46}
4447
45- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {48- (void)update {
46 Artist *artist = [self.fetchedResultsController objectAtIndexPath:indexPath];49 [[UOWebServiceController controller] updateArtists:self];
47 ArtistCell *artistCell = (ArtistCell *)cell;
48
49 [artistCell setArtist:artist];
50}50}
5151
52#pragma mark - Storyboard methods52#pragma mark - Storyboard methods
@@ -56,7 +56,7 @@
56 NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];56 NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
57 Artist *artist = [self.fetchedResultsController objectAtIndexPath:indexPath];57 Artist *artist = [self.fetchedResultsController objectAtIndexPath:indexPath];
58 58
59 artistViewController.artist = artist;59 artistViewController.artistId = artist.artistId;
60}60}
6161
62@end62@end
6363
=== modified file 'Music/View Controllers/PlaylistsViewController.m'
--- Music/View Controllers/PlaylistsViewController.m 2013-01-02 23:49:22 +0000
+++ Music/View Controllers/PlaylistsViewController.m 2013-01-02 23:49:23 +0000
@@ -11,6 +11,7 @@
11#import "Playlist.h"11#import "Playlist.h"
12#import "PlaylistCell.h"12#import "PlaylistCell.h"
13#import "NSString+Extras.h"13#import "NSString+Extras.h"
14#import "UOWebServiceController.h"
1415
15@interface PlaylistsViewController ()16@interface PlaylistsViewController ()
1617
@@ -20,8 +21,10 @@
2021
21#pragma mark - UOIndexedViewController methods22#pragma mark - UOIndexedViewController methods
2223
23- (NSString *)endpoint {24- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
24 return @"/playlists/";25 PlaylistCell *playlistCell = (PlaylistCell *)cell;
26 Playlist *playlist = [self.fetchedResultsController objectAtIndexPath:indexPath];
27 [playlistCell setPlaylist:playlist];
25}28}
2629
27- (NSString *)entityName {30- (NSString *)entityName {
@@ -29,7 +32,7 @@
29}32}
3033
31- (NSString *)lastUpdatedKey {34- (NSString *)lastUpdatedKey {
32 return @"playlistsLastUpdated";35 return PLAYLISTS_LAST_UPDATED;
33}36}
3437
35- (NSArray *)sortDescriptors {38- (NSArray *)sortDescriptors {
@@ -38,10 +41,8 @@
38 nil];41 nil];
39}42}
4043
41- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {44- (void)update {
42 PlaylistCell *playlistCell = (PlaylistCell *)cell;45 [[UOWebServiceController controller] updatePlaylists:self];
43 Playlist *playlist = [self.fetchedResultsController objectAtIndexPath:indexPath];
44 [playlistCell setPlaylist:playlist];
45}46}
4647
47@end48@end
4849
=== modified file 'Music/View Controllers/SongsViewController.m'
--- Music/View Controllers/SongsViewController.m 2013-01-02 23:49:22 +0000
+++ Music/View Controllers/SongsViewController.m 2013-01-02 23:49:23 +0000
@@ -11,6 +11,7 @@
11#import "Song.h"11#import "Song.h"
12#import "SongCell.h"12#import "SongCell.h"
13#import "NSString+Extras.h"13#import "NSString+Extras.h"
14#import "UOWebServiceController.h"
1415
15@interface SongsViewController ()16@interface SongsViewController ()
1617
@@ -20,16 +21,12 @@
2021
21#pragma mark - UOIndexedViewControllers methods22#pragma mark - UOIndexedViewControllers methods
2223
23- (NSString *)endpoint {
24 return @"/songs/";
25}
26
27- (NSString *)entityName {24- (NSString *)entityName {
28 return @"Song";25 return @"Song";
29}26}
3027
31- (NSString *)lastUpdatedKey {28- (NSString *)lastUpdatedKey {
32 return @"songsLastUpdated";29 return SONGS_LAST_UPDATED;
33}30}
3431
35- (NSArray *)sortDescriptors {32- (NSArray *)sortDescriptors {
@@ -44,4 +41,8 @@
44 [songCell setSong:song];41 [songCell setSong:song];
45}42}
4643
44- (void)viewWillAppear:(BOOL)animated {
45 [[UOWebServiceController controller] updateSongs:self];
46}
47
47@end48@end
4849
=== modified file 'Music/View Controllers/UOIndexedViewController.h'
--- Music/View Controllers/UOIndexedViewController.h 2013-01-02 23:49:22 +0000
+++ Music/View Controllers/UOIndexedViewController.h 2013-01-02 23:49:23 +0000
@@ -8,8 +8,9 @@
88
9#import <UIKit/UIKit.h>9#import <UIKit/UIKit.h>
10#import <RestKit/RestKit.h>10#import <RestKit/RestKit.h>
11#import "UOWebServiceController.h"
1112
12@interface UOIndexedViewController : UITableViewController <NSFetchedResultsControllerDelegate, RKObjectLoaderDelegate> {13@interface UOIndexedViewController : UITableViewController <NSFetchedResultsControllerDelegate,UOWebServiceDelegate> {
13 NSMutableDictionary *groupedTableData;14 NSMutableDictionary *groupedTableData;
14 NSArray *indexes;15 NSArray *indexes;
15 BOOL indexed;16 BOOL indexed;
@@ -26,5 +27,4 @@
2627
27- (NSFetchedResultsController *)fetchedResultsController;28- (NSFetchedResultsController *)fetchedResultsController;
2829
29- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error;
30@end30@end
3131
=== modified file 'Music/View Controllers/UOIndexedViewController.m'
--- Music/View Controllers/UOIndexedViewController.m 2013-01-02 23:49:22 +0000
+++ Music/View Controllers/UOIndexedViewController.m 2013-01-02 23:49:23 +0000
@@ -8,11 +8,8 @@
88
9#import "UOIndexedViewController.h"9#import "UOIndexedViewController.h"
10#import <RestKit/RestKit.h>10#import <RestKit/RestKit.h>
11#import "UONetworkStatusCoordinator.h"
12#import "AppDelegate.h"11#import "AppDelegate.h"
1312
14#define ARTISTS_LAST_UPDATED @"artistsLastUpdateAt"
15
16@interface UOIndexedViewController () {13@interface UOIndexedViewController () {
17 NSFetchedResultsController *_fetchedResultsController;14 NSFetchedResultsController *_fetchedResultsController;
18}15}
@@ -21,15 +18,6 @@
2118
22@implementation UOIndexedViewController19@implementation UOIndexedViewController
2320
24- (id)initWithStyle:(UITableViewStyle)style
25{
26 self = [super initWithStyle:style];
27 if (self) {
28 // Custom initialization
29 }
30 return self;
31}
32
33#pragma mark - Abstract methods21#pragma mark - Abstract methods
3422
35- (NSString *)endpoint {23- (NSString *)endpoint {
@@ -56,11 +44,7 @@
56 return;44 return;
57}45}
5846
59#pragma mark - Data retrieval methods
60
61- (void)update {47- (void)update {
62 [UONetworkStatusCoordinator addNetworkActivity];
63 [[RKObjectManager sharedManager] loadObjectsAtResourcePath:self.endpoint delegate:self];
64}48}
6549
66#pragma mark - UIViewController lifecycle50#pragma mark - UIViewController lifecycle
@@ -71,16 +55,7 @@
71}55}
7256
73- (void)viewWillAppear:(BOOL)animated {57- (void)viewWillAppear:(BOOL)animated {
74 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];58 [self update];
75 /* In general, using static time difference intervals is bad. However, a precision of "7 days ago"
76 is probably good enough for our needs.
77 */
78 NSDate *oneWeekAgo = [NSDate dateWithTimeIntervalSinceNow:-604800];
79 NSDate *lastUpdatedAt = [userDefaults objectForKey:[self lastUpdatedKey]];
80 if (lastUpdatedAt == nil || [oneWeekAgo compare:lastUpdatedAt] == NSOrderedDescending ) {
81 NSLog(@"Data is stale. Calling update");
82 [self update];
83 }
84}59}
8560
86- (void)didReceiveMemoryWarning61- (void)didReceiveMemoryWarning
@@ -117,8 +92,22 @@
117 return [self.fetchedResultsController sectionIndexTitles];92 return [self.fetchedResultsController sectionIndexTitles];
118}93}
11994
95#pragma mark - UOWebServiceDelegate methods
96
97- (void)webserviceUpdateComplete {
98 _fetchedResultsController = nil;
99 [self.tableView reloadData];
100}
101
102- (void)webserviceUpdateError:(NSError *)error {
103 if ([error code] == 2) { // Network is down.
104 return;
105 }
106 NSLog(@"Error: %@", [error localizedDescription]);
107}
108
120#pragma mark - RKObjectLoaderDelegate methods109#pragma mark - RKObjectLoaderDelegate methods
121110/*
122- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {111- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
123 [UONetworkStatusCoordinator removeNetworkActivity];112 [UONetworkStatusCoordinator removeNetworkActivity];
124 if ([error code] == 2) { // Network is down.113 if ([error code] == 2) { // Network is down.
@@ -134,6 +123,7 @@
134 [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:[self lastUpdatedKey]];123 [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:[self lastUpdatedKey]];
135 [self.tableView reloadData];124 [self.tableView reloadData];
136}125}
126 */
137127
138#pragma mark - Fetched results controller128#pragma mark - Fetched results controller
139129
@@ -142,18 +132,12 @@
142 return _fetchedResultsController;132 return _fetchedResultsController;
143 }133 }
144 134
145 NSManagedObjectContext *managedObjectContext = [AppDelegate delegate].managedObjectContext;135 NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[self entityName]];
146
147 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
148 NSEntityDescription *entityDescription = [NSEntityDescription entityForName:[self entityName] inManagedObjectContext:managedObjectContext];
149 [fetchRequest setEntity:entityDescription];
150
151 [fetchRequest setFetchBatchSize:20];136 [fetchRequest setFetchBatchSize:20];
152
153 [fetchRequest setSortDescriptors:[self sortDescriptors]];137 [fetchRequest setSortDescriptors:[self sortDescriptors]];
154 138
155 _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest139 _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
156 managedObjectContext:[RKManagedObjectStore defaultObjectStore].managedObjectContextForCurrentThread140 managedObjectContext:[[AppDelegate delegate] managedObjectContext]
157 sectionNameKeyPath:[self sectionNameKeyPath]141 sectionNameKeyPath:[self sectionNameKeyPath]
158 cacheName:nil];142 cacheName:nil];
159 _fetchedResultsController.delegate = self;143 _fetchedResultsController.delegate = self;
160144
=== modified file 'U1Music.xcodeproj/project.pbxproj'
--- U1Music.xcodeproj/project.pbxproj 2013-01-02 23:49:22 +0000
+++ U1Music.xcodeproj/project.pbxproj 2013-01-02 23:49:23 +0000
@@ -32,7 +32,6 @@
32 52206BD01655355000A3A0A8 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 52206BCF1655354F00A3A0A8 /* SettingsViewController.m */; };32 52206BD01655355000A3A0A8 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 52206BCF1655354F00A3A0A8 /* SettingsViewController.m */; };
33 52206BE61655BE8700A3A0A8 /* SettingsAuthenticationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 52206BE51655BE8700A3A0A8 /* SettingsAuthenticationViewController.m */; };33 52206BE61655BE8700A3A0A8 /* SettingsAuthenticationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 52206BE51655BE8700A3A0A8 /* SettingsAuthenticationViewController.m */; };
34 52206BE91655BF4900A3A0A8 /* SettingsAboutViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 52206BE81655BF4900A3A0A8 /* SettingsAboutViewController.m */; };34 52206BE91655BF4900A3A0A8 /* SettingsAboutViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 52206BE81655BF4900A3A0A8 /* SettingsAboutViewController.m */; };
35 52220B9E1672A75F0078D5DC /* RKRequest+Plaintext.m in Sources */ = {isa = PBXBuildFile; fileRef = 52220B9D1672A75F0078D5DC /* RKRequest+Plaintext.m */; };
36 523B3CE215B5D64F004394F4 /* grabber.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CE015B5D64F004394F4 /* grabber.png */; };35 523B3CE215B5D64F004394F4 /* grabber.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CE015B5D64F004394F4 /* grabber.png */; };
37 523B3CE315B5D64F004394F4 /* grabber@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CE115B5D64F004394F4 /* grabber@2x.png */; };36 523B3CE315B5D64F004394F4 /* grabber@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CE115B5D64F004394F4 /* grabber@2x.png */; };
38 523B3CF915B73BA0004394F4 /* download-grey.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CF515B73BA0004394F4 /* download-grey.png */; };37 523B3CF915B73BA0004394F4 /* download-grey.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CF515B73BA0004394F4 /* download-grey.png */; };
@@ -83,6 +82,7 @@
83 52AC3D811604513E00B4785D /* uncached.png in Resources */ = {isa = PBXBuildFile; fileRef = 52AC3D651604513E00B4785D /* uncached.png */; };82 52AC3D811604513E00B4785D /* uncached.png in Resources */ = {isa = PBXBuildFile; fileRef = 52AC3D651604513E00B4785D /* uncached.png */; };
84 52AC3D821604513E00B4785D /* uncached@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 52AC3D661604513E00B4785D /* uncached@2x.png */; };83 52AC3D821604513E00B4785D /* uncached@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 52AC3D661604513E00B4785D /* uncached@2x.png */; };
85 52AC3D841604539000B4785D /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 52AC3D831604539000B4785D /* Default-568h@2x.png */; };84 52AC3D841604539000B4785D /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 52AC3D831604539000B4785D /* Default-568h@2x.png */; };
85 52B7A030167986BC00243D7D /* UOWebServiceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 52B7A02F167986BC00243D7D /* UOWebServiceController.m */; };
86 536D620B1144495400DFCE56 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 536D620A1144495400DFCE56 /* SystemConfiguration.framework */; };86 536D620B1144495400DFCE56 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 536D620A1144495400DFCE56 /* SystemConfiguration.framework */; };
87 537DE2D9113F008C00875852 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 537DE2D8113F008C00875852 /* CoreFoundation.framework */; };87 537DE2D9113F008C00875852 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 537DE2D8113F008C00875852 /* CoreFoundation.framework */; };
88 53F675D8113B092C00822059 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53F675D7113B092C00822059 /* MediaPlayer.framework */; };88 53F675D8113B092C00822059 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53F675D7113B092C00822059 /* MediaPlayer.framework */; };
@@ -152,13 +152,6 @@
152 remoteGlobalIDString = 25160E78145651060060A5C5;152 remoteGlobalIDString = 25160E78145651060060A5C5;
153 remoteInfo = RestKitFrameworkTests;153 remoteInfo = RestKitFrameworkTests;
154 };154 };
155 52206B9D16550AEE00A3A0A8 /* PBXContainerItemProxy */ = {
156 isa = PBXContainerItemProxy;
157 containerPortal = 52206B8A16550AED00A3A0A8 /* RestKit.xcodeproj */;
158 proxyType = 2;
159 remoteGlobalIDString = 259C301615128079003066A2;
160 remoteInfo = RestKitResources;
161 };
162 528515931604F16D004A1F7C /* PBXContainerItemProxy */ = {155 528515931604F16D004A1F7C /* PBXContainerItemProxy */ = {
163 isa = PBXContainerItemProxy;156 isa = PBXContainerItemProxy;
164 containerPortal = 5285158E1604F16B004A1F7C /* UbuntuOneAuthKit.xcodeproj */;157 containerPortal = 5285158E1604F16B004A1F7C /* UbuntuOneAuthKit.xcodeproj */;
@@ -219,8 +212,6 @@
219 52206BE51655BE8700A3A0A8 /* SettingsAuthenticationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SettingsAuthenticationViewController.m; path = "Music/View Controllers/SettingsAuthenticationViewController.m"; sourceTree = SOURCE_ROOT; };212 52206BE51655BE8700A3A0A8 /* SettingsAuthenticationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SettingsAuthenticationViewController.m; path = "Music/View Controllers/SettingsAuthenticationViewController.m"; sourceTree = SOURCE_ROOT; };
220 52206BE71655BF4900A3A0A8 /* SettingsAboutViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SettingsAboutViewController.h; path = "Music/View Controllers/SettingsAboutViewController.h"; sourceTree = SOURCE_ROOT; };213 52206BE71655BF4900A3A0A8 /* SettingsAboutViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SettingsAboutViewController.h; path = "Music/View Controllers/SettingsAboutViewController.h"; sourceTree = SOURCE_ROOT; };
221 52206BE81655BF4900A3A0A8 /* SettingsAboutViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SettingsAboutViewController.m; path = "Music/View Controllers/SettingsAboutViewController.m"; sourceTree = SOURCE_ROOT; };214 52206BE81655BF4900A3A0A8 /* SettingsAboutViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SettingsAboutViewController.m; path = "Music/View Controllers/SettingsAboutViewController.m"; sourceTree = SOURCE_ROOT; };
222 52220B9C1672A75F0078D5DC /* RKRequest+Plaintext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "RKRequest+Plaintext.h"; path = "Music/Categories/RKRequest+Plaintext.h"; sourceTree = SOURCE_ROOT; };
223 52220B9D1672A75F0078D5DC /* RKRequest+Plaintext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "RKRequest+Plaintext.m"; path = "Music/Categories/RKRequest+Plaintext.m"; sourceTree = SOURCE_ROOT; };
224 523B3CDC15B4C42F004394F4 /* SongUITableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SongUITableView.h; sourceTree = "<group>"; };215 523B3CDC15B4C42F004394F4 /* SongUITableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SongUITableView.h; sourceTree = "<group>"; };
225 523B3CDD15B4C42F004394F4 /* SongUITableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SongUITableView.m; sourceTree = "<group>"; };216 523B3CDD15B4C42F004394F4 /* SongUITableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SongUITableView.m; sourceTree = "<group>"; };
226 523B3CE015B5D64F004394F4 /* grabber.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = grabber.png; sourceTree = "<group>"; };217 523B3CE015B5D64F004394F4 /* grabber.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = grabber.png; sourceTree = "<group>"; };
@@ -327,6 +318,8 @@
327 52AC3D651604513E00B4785D /* uncached.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = uncached.png; sourceTree = "<group>"; };318 52AC3D651604513E00B4785D /* uncached.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = uncached.png; sourceTree = "<group>"; };
328 52AC3D661604513E00B4785D /* uncached@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "uncached@2x.png"; sourceTree = "<group>"; };319 52AC3D661604513E00B4785D /* uncached@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "uncached@2x.png"; sourceTree = "<group>"; };
329 52AC3D831604539000B4785D /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };320 52AC3D831604539000B4785D /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
321 52B7A02E167986BC00243D7D /* UOWebServiceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UOWebServiceController.h; path = Music/Utilities/UOWebServiceController.h; sourceTree = SOURCE_ROOT; };
322 52B7A02F167986BC00243D7D /* UOWebServiceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UOWebServiceController.m; path = Music/Utilities/UOWebServiceController.m; sourceTree = SOURCE_ROOT; };
330 536D620A1144495400DFCE56 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };323 536D620A1144495400DFCE56 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
331 537DE2D8113F008C00875852 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };324 537DE2D8113F008C00875852 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
332 53F675D7113B092C00822059 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };325 53F675D7113B092C00822059 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
@@ -666,7 +659,6 @@
666 52206B9816550AEE00A3A0A8 /* RestKitTests.octest */,659 52206B9816550AEE00A3A0A8 /* RestKitTests.octest */,
667 52206B9A16550AEE00A3A0A8 /* RestKit.framework */,660 52206B9A16550AEE00A3A0A8 /* RestKit.framework */,
668 52206B9C16550AEE00A3A0A8 /* RestKitFrameworkTests.octest */,661 52206B9C16550AEE00A3A0A8 /* RestKitFrameworkTests.octest */,
669 52206B9E16550AEE00A3A0A8 /* RestKitResources.bundle */,
670 );662 );
671 name = Products;663 name = Products;
672 sourceTree = "<group>";664 sourceTree = "<group>";
@@ -736,6 +728,8 @@
736 children = (728 children = (
737 5244A7FE1656A10200882601 /* UONetworkStatusCoordinator.h */,729 5244A7FE1656A10200882601 /* UONetworkStatusCoordinator.h */,
738 5244A7FF1656A10200882601 /* UONetworkStatusCoordinator.m */,730 5244A7FF1656A10200882601 /* UONetworkStatusCoordinator.m */,
731 52B7A02E167986BC00243D7D /* UOWebServiceController.h */,
732 52B7A02F167986BC00243D7D /* UOWebServiceController.m */,
739 );733 );
740 name = Utilities;734 name = Utilities;
741 sourceTree = "<group>";735 sourceTree = "<group>";
@@ -745,8 +739,6 @@
745 children = (739 children = (
746 5244A8031657245A00882601 /* NSString+Extras.h */,740 5244A8031657245A00882601 /* NSString+Extras.h */,
747 5244A8041657245A00882601 /* NSString+Extras.m */,741 5244A8041657245A00882601 /* NSString+Extras.m */,
748 52220B9C1672A75F0078D5DC /* RKRequest+Plaintext.h */,
749 52220B9D1672A75F0078D5DC /* RKRequest+Plaintext.m */,
750 );742 );
751 name = Categories;743 name = Categories;
752 sourceTree = "<group>";744 sourceTree = "<group>";
@@ -1378,13 +1370,6 @@
1378 remoteRef = 52206B9B16550AEE00A3A0A8 /* PBXContainerItemProxy */;1370 remoteRef = 52206B9B16550AEE00A3A0A8 /* PBXContainerItemProxy */;
1379 sourceTree = BUILT_PRODUCTS_DIR;1371 sourceTree = BUILT_PRODUCTS_DIR;
1380 };1372 };
1381 52206B9E16550AEE00A3A0A8 /* RestKitResources.bundle */ = {
1382 isa = PBXReferenceProxy;
1383 fileType = wrapper.cfbundle;
1384 path = RestKitResources.bundle;
1385 remoteRef = 52206B9D16550AEE00A3A0A8 /* PBXContainerItemProxy */;
1386 sourceTree = BUILT_PRODUCTS_DIR;
1387 };
1388 528515941604F16D004A1F7C /* UbuntuOneAuthKit.a */ = {1373 528515941604F16D004A1F7C /* UbuntuOneAuthKit.a */ = {
1389 isa = PBXReferenceProxy;1374 isa = PBXReferenceProxy;
1390 fileType = archive.ar;1375 fileType = archive.ar;
@@ -1531,7 +1516,7 @@
1531 5244A81A1657C63700882601 /* PlaylistCell.m in Sources */,1516 5244A81A1657C63700882601 /* PlaylistCell.m in Sources */,
1532 5244A83A165B528800882601 /* UOMusic.xcdatamodeld in Sources */,1517 5244A83A165B528800882601 /* UOMusic.xcdatamodeld in Sources */,
1533 5244A83D165C627900882601 /* UOModel.m in Sources */,1518 5244A83D165C627900882601 /* UOModel.m in Sources */,
1534 52220B9E1672A75F0078D5DC /* RKRequest+Plaintext.m in Sources */,1519 52B7A030167986BC00243D7D /* UOWebServiceController.m in Sources */,
1535 );1520 );
1536 runOnlyForDeploymentPostprocessing = 0;1521 runOnlyForDeploymentPostprocessing = 0;
1537 };1522 };
15381523
=== modified file 'U1Music_Prefix.pch'
--- U1Music_Prefix.pch 2012-09-25 21:28:26 +0000
+++ U1Music_Prefix.pch 2013-01-02 23:49:23 +0000
@@ -10,15 +10,9 @@
1010
11#ifdef __OBJC__11#ifdef __OBJC__
12 #import <Foundation/Foundation.h>12 #import <Foundation/Foundation.h>
13 #import <MobileCoreServices/MobileCoreServices.h>
14 #import <SystemConfiguration/SystemConfiguration.h>
13 #import <UIKit/UIKit.h>15 #import <UIKit/UIKit.h>
14 #import <CoreData/CoreData.h>16
15 #import "Globals.h"
16 #import "MOC.h"
17 #import "NSManagedObjectContext+Additions.h"
18 #import "NSString+Extras.h"
19 #import "TestFlight.h"17 #import "TestFlight.h"
20 #define RELEASE_SAFELY(__obj) [__obj release], __obj = nil;
21
22 #define UBUNTU_ONE_SERVICE_NAME @"com.ubuntu.one"
23 #define UBUNTU_ONE_DUMMY_USER_NAME @"_UBUNTU_ONE_USER_NAME"
24#endif18#endif

Subscribers

People subscribed via source and target branches