Merge lp:~rockstar/ubuntuone-ios-music/albumart-loading 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/albumart-loading
Merge into: lp:~ubuntuone-ios-client-team/ubuntuone-ios-music/moriarty
Prerequisite: lp:~rockstar/ubuntuone-ios-music/dial-down
Diff against target: 705 lines (+226/-30)
19 files modified
Music/AppDelegate.h (+4/-0)
Music/AppDelegate.m (+18/-2)
Music/Categories/NSString+Extras.m (+5/-3)
Music/Models/Album.h (+2/-2)
Music/Models/Album.m (+12/-3)
Music/Models/Artist.h (+1/-1)
Music/Models/Artist.m (+9/-1)
Music/Models/Song.h (+0/-1)
Music/Models/Song.m (+17/-1)
Music/Models/UOModel.h (+8/-0)
Music/Models/UOModel.m (+31/-0)
Music/Storyboard_iPhone.storyboard (+64/-11)
Music/UOMusic.xcdatamodeld/UOMusic.xcdatamodel/contents (+4/-4)
Music/Utilities/UOWebServiceController.m (+2/-0)
Music/View Controllers/AlbumViewController.m (+8/-0)
Music/View Controllers/ArtistViewController.m (+8/-0)
Music/View Controllers/Table Cells/AlbumCell.m (+11/-0)
Music/View Controllers/Table Cells/ArtistCell.m (+10/-0)
Music/View Controllers/Table Cells/SongCell.m (+12/-1)
To merge this branch: bzr merge lp:~rockstar/ubuntuone-ios-music/albumart-loading
Reviewer Review Type Date Requested Status
Michał Karnicki (community) Approve
Review via email: mp+141685@code.launchpad.net

Description of the change

This branch adds the album art fetching and display to the views in the places
they are prescribed. I think they're a little awkward now, but it's not
polishing time.

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=== modified file 'Music/AppDelegate.h'
2--- Music/AppDelegate.h 2013-01-02 23:52:23 +0000
3+++ Music/AppDelegate.h 2013-01-02 23:52:23 +0000
4@@ -16,8 +16,12 @@
5 @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
6 @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
7
8+@property (nonatomic, retain) NSOperationQueue *queue;
9+
10 - (void)saveContext;
11 - (NSURL *)applicationDocumentsDirectory;
12+- (NSURL *)applicationCachesDirectory;
13+- (NSURL *)albumArtDirectory;
14
15 + (AppDelegate *)delegate;
16
17
18=== modified file 'Music/AppDelegate.m'
19--- Music/AppDelegate.m 2013-01-02 23:52:23 +0000
20+++ Music/AppDelegate.m 2013-01-02 23:52:23 +0000
21@@ -38,6 +38,7 @@
22
23 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
24
25+ self.queue = [[NSOperationQueue alloc] init];
26 self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
27
28 /* rockstar - WTF? This should just work with the target settings. */
29@@ -172,11 +173,26 @@
30 #pragma mark - Application's Documents directory
31
32 // Returns the URL to the application's Documents directory.
33-- (NSURL *)applicationDocumentsDirectory
34-{
35+- (NSURL *)applicationDocumentsDirectory {
36 return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
37 }
38
39+- (NSURL *)applicationCachesDirectory {
40+ return [[[NSFileManager defaultManager] URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
41+}
42+
43+- (NSURL *)albumArtDirectory {
44+ NSURL *path = [[self applicationCachesDirectory] URLByAppendingPathComponent:@"albumArt"];
45+ if (![[NSFileManager defaultManager] fileExistsAtPath:[path path]]) {
46+ NSError *error;
47+ [[NSFileManager defaultManager] createDirectoryAtPath:[path path] withIntermediateDirectories:YES attributes:nil error:&error];
48+ if (error) {
49+ abort();
50+ }
51+ }
52+ return path;
53+}
54+
55 - (void)checkAuthentication {
56 if (![[UOAuthManager sharedAuthManager] hasCredentials]) {
57 UITabBarController *rootViewController = (UITabBarController *)self.window.rootViewController;
58
59=== modified file 'Music/Categories/NSString+Extras.m'
60--- Music/Categories/NSString+Extras.m 2013-01-02 23:52:23 +0000
61+++ Music/Categories/NSString+Extras.m 2013-01-02 23:52:23 +0000
62@@ -45,9 +45,11 @@
63 return [[self dearticlizedString] substringToIndex:1];
64 }
65
66-- (NSString *)urlParameterEncodedString;
67-{
68- NSString *result = (__bridge id)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)self, NULL, (__bridge CFStringRef)@":/?#[]@!$&’()*+,;=", kCFStringEncodingUTF8);
69+- (NSString *)urlParameterEncodedString {
70+ CFStringRef resultRef = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)self, NULL, (__bridge CFStringRef)@":/?#[]@!$&’()*+,;=", kCFStringEncodingUTF8);
71+ NSString *result = [(__bridge id)resultRef copy];
72+ CFRelease(resultRef);
73+
74 return result;
75 }
76
77
78=== modified file 'Music/Models/Album.h'
79--- Music/Models/Album.h 2013-01-02 23:52:23 +0000
80+++ Music/Models/Album.h 2013-01-02 23:52:23 +0000
81@@ -16,8 +16,7 @@
82 @property (nonatomic, retain) NSString *albumId;
83 @property (nonatomic, retain) NSString *title;
84 @property (nonatomic, retain) NSString *url;
85-@property (nonatomic, retain) NSString *artUrl;
86-@property (nonatomic, retain) NSString *art;
87+@property (nonatomic, retain) NSString *artHash;
88
89 @property (nonatomic, retain, readonly) NSString *dearticlizedTitle;
90 @property (nonatomic, retain, readonly) NSString *index;
91@@ -26,4 +25,5 @@
92 @property (nonatomic, retain, readonly) Artist *artist;
93
94 @property (nonatomic, retain) NSSet *songs;
95+
96 @end
97
98=== modified file 'Music/Models/Album.m'
99--- Music/Models/Album.m 2013-01-02 23:52:23 +0000
100+++ Music/Models/Album.m 2013-01-02 23:52:23 +0000
101@@ -11,13 +11,13 @@
102 #import <RestKit/CoreData.h>
103 #import "Artist.h"
104 #import "NSString+Extras.h"
105+#import "AppDelegate.h"
106
107 @implementation Album
108 @dynamic albumId;
109 @dynamic title;
110 @dynamic url;
111-@dynamic art;
112-@dynamic artUrl;
113+@dynamic artHash;
114 @dynamic dearticlizedTitle;
115
116 @synthesize index;
117@@ -27,6 +27,8 @@
118
119 @dynamic songs;
120
121+#pragma mark - UOModel methods
122+
123 + (RKEntityMapping *)objectMapping {
124 RKObjectManager *manager = [RKObjectManager sharedManager];
125
126@@ -35,7 +37,7 @@
127 [mapping addAttributeMappingsFromDictionary:@{
128 @"id": @"albumId",
129 @"album_url": @"url",
130- @"cover_art": @"art",
131+ @"cover_art": @"artHash",
132 @"album_art_url": @"artUrl",
133 @"title": @"title",
134 @"artist_id": @"artistId"
135@@ -48,6 +50,12 @@
136 return @"response.albums";
137 }
138
139+- (NSString *)artPath {
140+ return [[[[AppDelegate delegate] albumArtDirectory] URLByAppendingPathComponent:[NSString stringWithFormat:@"album-%@.jpg", self.albumId]] path];
141+}
142+
143+#pragma mark - Model specific methods
144+
145 - (void)setTitle:(NSString *)title {
146 [self setPrimitiveValue:title forKey:@"title"];
147 [self setValue:[[title dearticlizedString] uppercaseString] forKey:@"dearticlizedTitle"];
148@@ -82,4 +90,5 @@
149 return _index;
150 }
151
152+
153 @end
154
155=== modified file 'Music/Models/Artist.h'
156--- Music/Models/Artist.h 2013-01-02 23:52:23 +0000
157+++ Music/Models/Artist.h 2013-01-02 23:52:23 +0000
158@@ -15,10 +15,10 @@
159 @property (nonatomic, retain) NSString *artistId;
160 @property (nonatomic, retain) NSString *name;
161 @property (nonatomic, retain) NSString *url;
162-@property (nonatomic, retain) NSString *artUrl;
163
164 @property (nonatomic, retain, readonly) NSString *dearticlizedName;
165 @property (nonatomic, retain, readonly) NSString *index;
166
167 @property (nonatomic, retain) NSSet *albums;
168+
169 @end
170
171=== modified file 'Music/Models/Artist.m'
172--- Music/Models/Artist.m 2013-01-02 23:52:23 +0000
173+++ Music/Models/Artist.m 2013-01-02 23:52:23 +0000
174@@ -9,17 +9,19 @@
175 #import "Artist.h"
176 #import <RestKit/RestKit.h>
177 #import "NSString+Extras.h"
178+#import "AppDelegate.h"
179
180 @implementation Artist
181 @dynamic artistId;
182 @dynamic name;
183 @dynamic url;
184-@dynamic artUrl;
185 @dynamic albums;
186 @dynamic dearticlizedName;
187
188 @synthesize index;
189
190+#pragma mark - UOModel methods
191+
192 + (RKEntityMapping *)objectMapping {
193 RKObjectManager *manager = [RKObjectManager sharedManager];
194
195@@ -38,6 +40,12 @@
196 return @"response.artists";
197 }
198
199+- (NSString *)artPath {
200+ return [[[[AppDelegate delegate] albumArtDirectory] URLByAppendingPathComponent:[NSString stringWithFormat:@"artist-%@.jpg", self.artistId]] path];
201+}
202+
203+#pragma mark - Model specific methods
204+
205 - (void)setName:(NSString *)name {
206 [self setPrimitiveValue:name forKey:@"name"];
207 [self setValue:[[name dearticlizedString] uppercaseString] forKey:@"dearticlizedName"];
208
209=== modified file 'Music/Models/Song.h'
210--- Music/Models/Song.h 2013-01-02 23:52:23 +0000
211+++ Music/Models/Song.h 2013-01-02 23:52:23 +0000
212@@ -15,7 +15,6 @@
213 @interface Song : UOModel
214
215 @property (nonatomic, retain) NSString *url;
216-@property (nonatomic, retain) NSString *artUrl;
217 @property (nonatomic, retain) NSString *suffix;
218 @property (nonatomic, retain) NSString *track;
219 @property (nonatomic, retain) NSString *title;
220
221=== modified file 'Music/Models/Song.m'
222--- Music/Models/Song.m 2013-01-02 23:52:23 +0000
223+++ Music/Models/Song.m 2013-01-02 23:52:23 +0000
224@@ -11,11 +11,11 @@
225 #import "Artist.h"
226 #import "Album.h"
227 #import "NSString+Extras.h"
228+#import "AppDelegate.h"
229
230 @implementation Song
231
232 @dynamic url;
233-@dynamic artUrl;
234 @dynamic suffix;
235 @dynamic track;
236 @dynamic title;
237@@ -32,11 +32,15 @@
238 @dynamic dearticlizedTitle;
239
240 @synthesize index;
241+/* Override to fall through to album's artUrl */
242+@synthesize artUrl;
243
244 @dynamic album;
245 @dynamic artist;
246 @dynamic albumArtist;
247
248+#pragma mark - UOModel methods
249+
250 + (RKEntityMapping *)objectMapping {
251 RKObjectManager *manager = [RKObjectManager sharedManager];
252
253@@ -44,7 +48,9 @@
254 [mapping setIdentificationAttributes:@[@"songId"]];
255 [mapping addAttributeMappingsFromDictionary:@{
256 @"song_url": @"url",
257+ /* Disabled, since we want to fall through to album's art.
258 @"song_art_url": @"artUrl",
259+ */
260 @"suffix": @"suffix",
261 @"track": @"track",
262 @"title": @"title",
263@@ -69,6 +75,16 @@
264 return @"response.songs";
265 }
266
267+- (NSString *)artPath {
268+ return self.album.artPath;
269+}
270+
271+#pragma mark - Model specific methods
272+
273+- (NSString *)artUrl {
274+ return self.album.artUrl;
275+}
276+
277 - (void)setTitle:(NSString *)_title {
278 [self setPrimitiveValue:_title forKey:@"title"];
279 [self setValue:[[_title dearticlizedString] uppercaseString] forKey:@"dearticlizedTitle"];
280
281=== modified file 'Music/Models/UOModel.h'
282--- Music/Models/UOModel.h 2013-01-02 23:52:23 +0000
283+++ Music/Models/UOModel.h 2013-01-02 23:52:23 +0000
284@@ -14,4 +14,12 @@
285 + (void)registerMapping;
286 + (RKEntityMapping *)objectMapping;
287 + (NSString *)keyPath;
288+
289+/* Not used for playlist */
290+@property (nonatomic, retain) NSString *artUrl;
291+
292+/* Used for fetching art */
293+@property (nonatomic, readonly) UIImage *art;
294+- (NSString *)artPath;
295+- (void)fetchArt:(void (^)(UIImage *))completionBlock;
296 @end
297
298=== modified file 'Music/Models/UOModel.m'
299--- Music/Models/UOModel.m 2013-01-02 23:52:23 +0000
300+++ Music/Models/UOModel.m 2013-01-02 23:52:23 +0000
301@@ -8,9 +8,13 @@
302
303 #import "UOModel.h"
304 #import <RestKit/RestKit.h>
305+#import "AppDelegate.h"
306+#import "UOAuthManager.h"
307
308 @implementation UOModel
309
310+@dynamic artUrl;
311+
312 + (void)registerMapping {
313 RKObjectManager *manager = [RKObjectManager sharedManager];
314
315@@ -32,4 +36,31 @@
316 return @"";
317 }
318
319+- (UIImage *)art {
320+ NSString *path = [self artPath];
321+ if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
322+ return nil;
323+ }
324+ return [UIImage imageWithContentsOfFile:path];
325+}
326+
327+- (void)fetchArt:(void (^)(UIImage *))completionBlock {
328+ NSOperationQueue *queue = [[AppDelegate delegate] queue];
329+ NSString *path = [self artPath];
330+ NSURLRequest *echo = [UOAuthManager oauthRequestForPath:self.artUrl];
331+ NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:self.artUrl]];
332+ [request setHTTPMethod:@"GET"];
333+ [request addValue:[echo valueForHTTPHeaderField:@"Authorization"] forHTTPHeaderField:@"Authorization"];
334+
335+ [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
336+ UIImage *image = [UIImage imageWithData:data];
337+ [UIImageJPEGRepresentation(image, 1) writeToFile:path atomically:YES];
338+ completionBlock(image);
339+ }];
340+}
341+
342+- (NSString *)artPath {
343+ return nil;
344+}
345+
346 @end
347
348=== modified file 'Music/Storyboard_iPhone.storyboard'
349--- Music/Storyboard_iPhone.storyboard 2013-01-02 23:52:23 +0000
350+++ Music/Storyboard_iPhone.storyboard 2013-01-02 23:52:23 +0000
351@@ -36,7 +36,7 @@
352 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
353 <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
354 <prototypes>
355- <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Cell" textLabel="Wy4-11-qhh" detailTextLabel="PUO-bG-eLt" style="IBUITableViewCellStyleSubtitle" id="TCk-Kb-c61" customClass="ArtistCell">
356+ <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">
357 <rect key="frame" x="0.0" y="22" width="320" height="44"/>
358 <autoresizingMask key="autoresizingMask"/>
359 <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
360@@ -44,19 +44,23 @@
361 <autoresizingMask key="autoresizingMask"/>
362 <subviews>
363 <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Wy4-11-qhh">
364- <rect key="frame" x="10" y="2" width="38" height="22"/>
365+ <rect key="frame" x="53" y="2" width="38" height="22"/>
366 <autoresizingMask key="autoresizingMask"/>
367 <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
368 <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
369 <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
370 </label>
371 <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="PUO-bG-eLt">
372- <rect key="frame" x="10" y="24" width="47" height="18"/>
373+ <rect key="frame" x="53" y="24" width="47" height="18"/>
374 <autoresizingMask key="autoresizingMask"/>
375 <fontDescription key="fontDescription" type="system" pointSize="14"/>
376 <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
377 <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
378 </label>
379+ <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="default-album-art-120.png" id="EvX-DO-a8s">
380+ <rect key="frame" x="0.0" y="0.0" width="43" height="43"/>
381+ <autoresizingMask key="autoresizingMask"/>
382+ </imageView>
383 </subviews>
384 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
385 </view>
386@@ -85,12 +89,32 @@
387 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
388 <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
389 <prototypes>
390- <tableViewCell contentMode="scaleToFill" selectionStyle="blue" indentationWidth="10" reuseIdentifier="Cell" id="Y5x-0G-rno" customClass="AlbumCell">
391+ <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">
392 <rect key="frame" x="0.0" y="22" width="320" height="44"/>
393 <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
394 <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
395 <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
396 <autoresizingMask key="autoresizingMask"/>
397+ <subviews>
398+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="G72-IX-jh9">
399+ <rect key="frame" x="53" y="2" width="38" height="22"/>
400+ <autoresizingMask key="autoresizingMask"/>
401+ <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
402+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
403+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
404+ </label>
405+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="VIc-Rn-YXm">
406+ <rect key="frame" x="53" y="24" width="47" height="18"/>
407+ <autoresizingMask key="autoresizingMask"/>
408+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
409+ <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
410+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
411+ </label>
412+ <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="default-album-art-120.png" id="F2l-py-JAO">
413+ <rect key="frame" x="0.0" y="0.0" width="43" height="43"/>
414+ <autoresizingMask key="autoresizingMask"/>
415+ </imageView>
416+ </subviews>
417 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
418 </view>
419 <connections>
420@@ -146,12 +170,32 @@
421 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
422 <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
423 <prototypes>
424- <tableViewCell contentMode="scaleToFill" selectionStyle="blue" indentationWidth="10" reuseIdentifier="Cell" id="vAU-q1-3Z9" customClass="SongCell">
425+ <tableViewCell contentMode="scaleToFill" selectionStyle="blue" indentationWidth="10" reuseIdentifier="Cell" textLabel="0Be-Uu-e1M" detailTextLabel="cgX-vu-iNg" imageView="xX5-x4-y65" style="IBUITableViewCellStyleSubtitle" id="vAU-q1-3Z9" customClass="SongCell">
426 <rect key="frame" x="0.0" y="22" width="320" height="44"/>
427 <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
428 <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
429 <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
430 <autoresizingMask key="autoresizingMask"/>
431+ <subviews>
432+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="0Be-Uu-e1M">
433+ <rect key="frame" x="53" y="2" width="38" height="22"/>
434+ <autoresizingMask key="autoresizingMask"/>
435+ <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
436+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
437+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
438+ </label>
439+ <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="cgX-vu-iNg">
440+ <rect key="frame" x="53" y="24" width="47" height="18"/>
441+ <autoresizingMask key="autoresizingMask"/>
442+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
443+ <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
444+ <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
445+ </label>
446+ <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="default-album-art-120.png" id="xX5-x4-y65">
447+ <rect key="frame" x="0.0" y="0.0" width="43" height="43"/>
448+ <autoresizingMask key="autoresizingMask"/>
449+ </imageView>
450+ </subviews>
451 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
452 </view>
453 </tableViewCell>
454@@ -218,7 +262,7 @@
455 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
456 <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
457 <prototypes>
458- <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Cell" textLabel="lHq-bS-Zm9" detailTextLabel="03B-YT-E7s" style="IBUITableViewCellStyleSubtitle" id="5s2-Qn-BOB" customClass="AlbumCell">
459+ <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">
460 <rect key="frame" x="0.0" y="22" width="320" height="44"/>
461 <autoresizingMask key="autoresizingMask"/>
462 <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
463@@ -226,19 +270,23 @@
464 <autoresizingMask key="autoresizingMask"/>
465 <subviews>
466 <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="lHq-bS-Zm9">
467- <rect key="frame" x="10" y="2" width="38" height="22"/>
468+ <rect key="frame" x="53" y="2" width="38" height="22"/>
469 <autoresizingMask key="autoresizingMask"/>
470 <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
471 <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
472 <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
473 </label>
474 <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="03B-YT-E7s">
475- <rect key="frame" x="10" y="24" width="47" height="18"/>
476+ <rect key="frame" x="53" y="24" width="47" height="18"/>
477 <autoresizingMask key="autoresizingMask"/>
478 <fontDescription key="fontDescription" type="system" pointSize="14"/>
479 <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
480 <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
481 </label>
482+ <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="default-album-art-120.png" id="apM-jL-xHe">
483+ <rect key="frame" x="0.0" y="0.0" width="43" height="43"/>
484+ <autoresizingMask key="autoresizingMask"/>
485+ </imageView>
486 </subviews>
487 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
488 </view>
489@@ -263,7 +311,7 @@
490 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
491 <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
492 <prototypes>
493- <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Cell" textLabel="OwY-7W-CUV" detailTextLabel="ORO-PT-T6b" style="IBUITableViewCellStyleSubtitle" id="jpK-Yt-5Y9" customClass="SongCell">
494+ <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">
495 <rect key="frame" x="0.0" y="22" width="320" height="44"/>
496 <autoresizingMask key="autoresizingMask"/>
497 <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
498@@ -271,19 +319,23 @@
499 <autoresizingMask key="autoresizingMask"/>
500 <subviews>
501 <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="OwY-7W-CUV">
502- <rect key="frame" x="10" y="2" width="38" height="22"/>
503+ <rect key="frame" x="53" y="2" width="38" height="22"/>
504 <autoresizingMask key="autoresizingMask"/>
505 <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
506 <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
507 <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
508 </label>
509 <label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ORO-PT-T6b">
510- <rect key="frame" x="10" y="24" width="47" height="18"/>
511+ <rect key="frame" x="53" y="24" width="47" height="18"/>
512 <autoresizingMask key="autoresizingMask"/>
513 <fontDescription key="fontDescription" type="system" pointSize="14"/>
514 <color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
515 <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
516 </label>
517+ <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="default-album-art-120.png" id="Ynd-vW-pQI">
518+ <rect key="frame" x="0.0" y="0.0" width="43" height="43"/>
519+ <autoresizingMask key="autoresizingMask"/>
520+ </imageView>
521 </subviews>
522 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
523 </view>
524@@ -559,6 +611,7 @@
525 <resources>
526 <image name="albums.png" width="30" height="30"/>
527 <image name="artists.png" width="30" height="30"/>
528+ <image name="default-album-art-120.png" width="60" height="60"/>
529 <image name="playlists.png" width="30" height="30"/>
530 <image name="settings.png" width="30" height="30"/>
531 <image name="songs.png" width="30" height="30"/>
532
533=== modified file 'Music/UOMusic.xcdatamodeld/UOMusic.xcdatamodel/contents'
534--- Music/UOMusic.xcdatamodeld/UOMusic.xcdatamodel/contents 2013-01-02 23:52:23 +0000
535+++ Music/UOMusic.xcdatamodeld/UOMusic.xcdatamodel/contents 2013-01-02 23:52:23 +0000
536@@ -2,7 +2,7 @@
537 <model name="" userDefinedModelVersionIdentifier="UOMusic0" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1811" systemVersion="12C60" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic">
538 <entity name="Album" representedClassName="Album" syncable="YES">
539 <attribute name="albumId" attributeType="String" indexed="YES" syncable="YES"/>
540- <attribute name="art" optional="YES" attributeType="String" syncable="YES"/>
541+ <attribute name="artHash" optional="YES" attributeType="String" syncable="YES"/>
542 <attribute name="artUrl" optional="YES" attributeType="String" syncable="YES"/>
543 <attribute name="dearticlizedTitle" attributeType="String" syncable="YES"/>
544 <attribute name="index" optional="YES" transient="YES" attributeType="String" syncable="YES"/>
545@@ -12,6 +12,7 @@
546 <relationship name="songs" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Song" inverseName="album" inverseEntity="Song" syncable="YES"/>
547 </entity>
548 <entity name="Artist" representedClassName="Artist" syncable="YES">
549+ <attribute name="art" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/>
550 <attribute name="artistId" attributeType="String" indexed="YES" syncable="YES"/>
551 <attribute name="artUrl" optional="YES" attributeType="String" syncable="YES"/>
552 <attribute name="dearticlizedName" attributeType="String" syncable="YES"/>
553@@ -30,7 +31,6 @@
554 <attribute name="url" attributeType="String" syncable="YES"/>
555 </entity>
556 <entity name="Song" representedClassName="Song" syncable="YES">
557- <attribute name="artUrl" optional="YES" attributeType="String" syncable="YES"/>
558 <attribute name="bitRate" optional="YES" attributeType="String" syncable="YES"/>
559 <attribute name="contentType" optional="YES" attributeType="String" syncable="YES"/>
560 <attribute name="dearticlizedTitle" attributeType="String" syncable="YES"/>
561@@ -53,8 +53,8 @@
562 </entity>
563 <elements>
564 <element name="Album" positionX="468" positionY="180" width="128" height="180"/>
565- <element name="Artist" positionX="160" positionY="195" width="128" height="165"/>
566+ <element name="Artist" positionX="160" positionY="195" width="128" height="180"/>
567 <element name="Playlist" positionX="160" positionY="192" width="128" height="135"/>
568- <element name="Song" positionX="160" positionY="192" width="128" height="345"/>
569+ <element name="Song" positionX="160" positionY="192" width="128" height="330"/>
570 </elements>
571 </model>
572\ No newline at end of file
573
574=== modified file 'Music/Utilities/UOWebServiceController.m'
575--- Music/Utilities/UOWebServiceController.m 2013-01-02 23:52:23 +0000
576+++ Music/Utilities/UOWebServiceController.m 2013-01-02 23:52:23 +0000
577@@ -169,6 +169,7 @@
578 }
579
580 - (void)initRestKit {
581+ RKLogConfigureByName("RestKit/Network", RKLogLevelWarning);
582
583 NSURL *baseUrl = [NSURL URLWithString:@"https://one.ubuntu.com/api/music/v2/"];
584 RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseUrl];
585@@ -190,6 +191,7 @@
586 NSError *error;
587 [managedObjectStore addSQLitePersistentStoreAtPath:[RKApplicationDataDirectory() stringByAppendingPathComponent:@"UOMusic.sqlite"] fromSeedDatabaseAtPath:nil withConfiguration:nil options:nil error:&error];
588 if (error) {
589+ NSLog(@"Database model is out of date");
590 abort();
591 }
592 [objectManager setManagedObjectStore:managedObjectStore];
593
594=== modified file 'Music/View Controllers/AlbumViewController.m'
595--- Music/View Controllers/AlbumViewController.m 2013-01-02 23:52:23 +0000
596+++ Music/View Controllers/AlbumViewController.m 2013-01-02 23:52:23 +0000
597@@ -38,6 +38,14 @@
598
599 [_albumTitle setText:album.title];
600 [_albumDescription setText:album.artist.name];
601+ if (!album.art) {
602+ [album fetchArt:^(UIImage *image) {
603+ [self.albumArt setImage:image];
604+ [self.albumArt setNeedsDisplay];
605+ }];
606+ } else {
607+ [self.albumArt setImage:album.art];
608+ }
609
610 if ([album.songs count]) {
611 NSArray *sortDescriptors = [NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"track" ascending:NO], nil];
612
613=== modified file 'Music/View Controllers/ArtistViewController.m'
614--- Music/View Controllers/ArtistViewController.m 2013-01-02 23:52:23 +0000
615+++ Music/View Controllers/ArtistViewController.m 2013-01-02 23:52:23 +0000
616@@ -41,6 +41,14 @@
617 [self fetchArtist];
618
619 [_artistName setText:artist.name];
620+ if (!artist.art) {
621+ [artist fetchArt:^(UIImage *image) {
622+ [self.albumArt setImage:image];
623+ [self.albumArt setNeedsDisplay];
624+ }];
625+ } else {
626+ [self.albumArt setImage:artist.art];
627+ }
628
629 NSString *pluralizedNoun = @"albums";
630 if ([artist.albums count] == 1) {
631
632=== modified file 'Music/View Controllers/Table Cells/AlbumCell.m'
633--- Music/View Controllers/Table Cells/AlbumCell.m 2013-01-02 23:52:23 +0000
634+++ Music/View Controllers/Table Cells/AlbumCell.m 2013-01-02 23:52:23 +0000
635@@ -13,6 +13,17 @@
636
637 - (void)setAlbum:(Album *)album {
638 _album = album;
639+
640+ if (!album.art) {
641+ [self.imageView setImage:[UIImage imageNamed:@"default-album-art-120.png"]];
642+ [album fetchArt:^(UIImage *image) {
643+ [self.imageView setImage:image];
644+ [self setNeedsDisplay];
645+ }];
646+ } else {
647+ [self.imageView setImage:album.art];
648+ }
649+
650 [self.textLabel setText:album.title];
651
652 [self.detailTextLabel setText:album.artist.name];
653
654=== modified file 'Music/View Controllers/Table Cells/ArtistCell.m'
655--- Music/View Controllers/Table Cells/ArtistCell.m 2013-01-02 23:52:23 +0000
656+++ Music/View Controllers/Table Cells/ArtistCell.m 2013-01-02 23:52:23 +0000
657@@ -14,6 +14,16 @@
658 - (void)setArtist:(Artist *)artist {
659 _artist = artist;
660
661+ if (!artist.art) {
662+ [self.imageView setImage:[UIImage imageNamed:@"default-album-art-120.png"]];
663+ [artist fetchArt:^(UIImage *image) {
664+ [self.imageView setImage:image];
665+ [self setNeedsDisplay];
666+ }];
667+ } else {
668+ [self.imageView setImage:artist.art];
669+ }
670+
671 [self.textLabel setText:artist.name];
672 if ([artist.albums count] > 0) {
673 NSString *pluralizedNoun = @"albums";
674
675=== modified file 'Music/View Controllers/Table Cells/SongCell.m'
676--- Music/View Controllers/Table Cells/SongCell.m 2013-01-02 23:52:23 +0000
677+++ Music/View Controllers/Table Cells/SongCell.m 2013-01-02 23:52:23 +0000
678@@ -7,6 +7,7 @@
679 //
680
681 #import "SongCell.h"
682+#import "Artist.h"
683
684 @implementation SongCell
685 @synthesize song = _song;
686@@ -14,8 +15,18 @@
687 - (void)setSong:(Song *)song {
688 _song = song;
689
690+ if (!song.art) {
691+ [self.imageView setImage:[UIImage imageNamed:@"default-album-art-120.png"]];
692+ [song fetchArt:^(UIImage *image) {
693+ [self.imageView setImage:image];
694+ [self setNeedsDisplay];
695+ }];
696+ } else {
697+ [self.imageView setImage:song.art];
698+ }
699+
700 [self.textLabel setText:song.title];
701- //[self.detailTextLabel setText:song.artist];
702+ [self.detailTextLabel setText:song.artist.name];
703 }
704
705 @end

Subscribers

People subscribed via source and target branches