Merge lp:~urbanape/ubuntuone-ios-client/2.0-9-prerelease into lp:ubuntuone-ios-client

Proposed by Zachery Bir
Status: Merged
Approved by: Zachery Bir
Approved revision: 199
Merged at revision: 194
Proposed branch: lp:~urbanape/ubuntuone-ios-client/2.0-9-prerelease
Merge into: lp:ubuntuone-ios-client
Diff against target: 1954 lines (+431/-656)
46 files modified
musicstreaming/categories/NSMutableArray+Extras.h (+2/-0)
musicstreaming/categories/NSMutableArray+Extras.m (+34/-0)
musicstreaming/categories/NSMutableSet+Extras.h (+0/-26)
musicstreaming/categories/NSMutableSet+Extras.m (+0/-57)
musicstreaming/controls/MiniHudView.h (+0/-17)
musicstreaming/controls/MiniHudView.m (+0/-54)
musicstreaming/iSub-Info.plist (+1/-1)
musicstreaming/iSub.xcodeproj/project.pbxproj (+7/-17)
musicstreaming/models/Album.m (+2/-2)
musicstreaming/models/Artist.m (+2/-2)
musicstreaming/models/Playlist.h (+12/-9)
musicstreaming/models/Playlist.m (+43/-7)
musicstreaming/models/PlaylistSongIndex.h (+32/-0)
musicstreaming/models/PlaylistSongIndex.m (+27/-0)
musicstreaming/models/Song.h (+7/-6)
musicstreaming/models/Song.m (+9/-3)
musicstreaming/utilities/AlbumParser.m (+1/-0)
musicstreaming/utilities/Globals.h (+12/-1)
musicstreaming/utilities/Globals.m (+12/-1)
musicstreaming/utilities/PlaylistListParser.m (+15/-9)
musicstreaming/utilities/PlaylistParser.h (+2/-2)
musicstreaming/utilities/PlaylistParser.m (+9/-5)
musicstreaming/utilities/Subsonic.h (+1/-1)
musicstreaming/utilities/Subsonic.m (+4/-7)
musicstreaming/utilities/operations/AbstractNetworkOperation.h (+12/-1)
musicstreaming/utilities/operations/AbstractNetworkOperation.m (+12/-1)
musicstreaming/utilities/operations/AlbumArtLoader.h (+12/-1)
musicstreaming/utilities/operations/AlbumArtLoader.m (+14/-3)
musicstreaming/utilities/operations/AlbumArtLoadingOperation.h (+12/-1)
musicstreaming/utilities/operations/AlbumArtLoadingOperation.m (+12/-1)
musicstreaming/utilities/operations/DownloadOperation.h (+12/-1)
musicstreaming/utilities/operations/DownloadOperation.m (+12/-1)
musicstreaming/utilities/operations/Downloader.h (+12/-1)
musicstreaming/utilities/operations/Downloader.m (+12/-1)
musicstreaming/view_controllers/ArtistViewController.m (+0/-1)
musicstreaming/view_controllers/PlaylistEditAlbumViewController.m (+2/-2)
musicstreaming/view_controllers/PlaylistEditSongListViewController.m (+4/-2)
musicstreaming/view_controllers/PlaylistEditViewController.h (+2/-4)
musicstreaming/view_controllers/PlaylistEditViewController.m (+11/-29)
musicstreaming/view_controllers/PlaylistListViewController.m (+13/-13)
musicstreaming/view_controllers/PlaylistViewController.m (+40/-25)
musicstreaming/view_controllers/SongViewController.m (+0/-1)
musicstreaming/view_controllers/SubsonicTableViewController.h (+0/-2)
musicstreaming/view_controllers/SubsonicTableViewController.m (+3/-21)
musicstreaming/view_controllers/SubsonicViewController.m (+0/-3)
musicstreaming/xibs/PlaylistEditViewController.xib (+0/-314)
To merge this branch: bzr merge lp:~urbanape/ubuntuone-ios-client/2.0-9-prerelease
Reviewer Review Type Date Requested Status
Jason Foreman (community) Approve
Review via email: mp+65364@code.launchpad.net

Description of the change

This branch uses disc_number to aid sort in album view. Currently, this only works server-side with lp:~urbanape/ubuntuone-servers/include-disc-number-by-default, but will be exposed on production shortly. In the interim, songs will continue to be ordered by tracks, doubling up tracks in multi-disc albums.

To post a comment you must log in.
Revision history for this message
Zachery Bir (urbanape) wrote :

Also fixed the playlist edit views and hardened against playlist connectivity for creation, editing, and deletion.

199. By Zachery Bir

Remove unneeded code, and an unneeded .xib, properly organize the PlaylistEditViewController to not get clever with nested tab bar controllers

Revision history for this message
Jason Foreman (threeve) wrote :

Looks good to me!

review: Approve
200. By Zachery Bir

Put back in just enough to make the loading/refreshing work properly

201. By Zachery Bir

Bumped to build number 10

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'musicstreaming/categories/NSMutableArray+Extras.h'
2--- musicstreaming/categories/NSMutableArray+Extras.h 2011-03-29 14:22:42 +0000
3+++ musicstreaming/categories/NSMutableArray+Extras.h 2011-06-21 18:28:35 +0000
4@@ -21,4 +21,6 @@
5
6 @interface NSMutableArray (Extras)
7 - (void)shuffle;
8+- (void)addKeyValueObjectFromArray:(NSArray *)array;
9+- (NSString*)urlEncodedString;
10 @end
11
12=== modified file 'musicstreaming/categories/NSMutableArray+Extras.m'
13--- musicstreaming/categories/NSMutableArray+Extras.m 2011-03-29 14:22:42 +0000
14+++ musicstreaming/categories/NSMutableArray+Extras.m 2011-06-21 18:28:35 +0000
15@@ -19,6 +19,19 @@
16
17 #import "NSMutableArray+Extras.h"
18
19+// helper function: get the string form of any object
20+static NSString *toString(id object)
21+{
22+ return [NSString stringWithFormat: @"%@", object];
23+}
24+
25+// helper function: get the url encoded string form of any object
26+static NSString *urlEncode(id object)
27+{
28+ NSString *string = toString(object);
29+ return [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
30+}
31+
32 @implementation NSMutableArray (Extras)
33 - (void)shuffle
34 {
35@@ -32,4 +45,25 @@
36 [self exchangeObjectAtIndex:i withObjectAtIndex:n];
37 }
38 }
39+
40+- (void)addKeyValueObjectFromArray:(NSArray *)array
41+{
42+ [self addObject:[NSDictionary dictionaryWithObjects:array
43+ forKeys:[NSArray arrayWithObjects:@"key", @"value", nil]]];
44+}
45+
46+- (NSString*)urlEncodedString
47+{
48+ NSMutableArray *parts = [NSMutableArray array];
49+
50+ for (id object in self)
51+ {
52+ id key = [object objectForKey:@"key"];
53+ id value = [object objectForKey:@"value"];
54+ NSString *part = [NSString stringWithFormat:@"%@=%@",urlEncode(key),urlEncode(value)];
55+ [parts addObject:part];
56+ }
57+ return [parts componentsJoinedByString:@"&"];
58+}
59+
60 @end
61
62=== removed file 'musicstreaming/categories/NSMutableSet+Extras.h'
63--- musicstreaming/categories/NSMutableSet+Extras.h 2011-04-08 01:55:24 +0000
64+++ musicstreaming/categories/NSMutableSet+Extras.h 1970-01-01 00:00:00 +0000
65@@ -1,26 +0,0 @@
66-//
67-// NSMutableSet+Extras.h
68-// iSub
69-//
70-// Created by Zachery Bir on 4/7/11.
71-// Copyright 2011 Canonical Ltd.
72-//
73-// This program is free software: you can redistribute it and/or modify it
74-// under the terms of the GNU Affero General Public License version 3,
75-// as published by the Free Software Foundation.
76-//
77-// This program is distributed in the hope that it will be useful, but
78-// WITHOUT ANY WARRANTY; without even the implied warranties of
79-// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
80-// PURPOSE. See the GNU Affero General Public License for more details.
81-//
82-// You should have received a copy of the GNU Affero General Public License
83-// along with this program. If not, see <http://www.gnu.org/licenses/>.
84-
85-#import <Foundation/Foundation.h>
86-
87-
88-@interface NSMutableSet (Extras)
89-- (void)addKeyValueObjectFromArray:(NSArray *)array;
90-- (NSString*)urlEncodedString;
91-@end
92
93=== removed file 'musicstreaming/categories/NSMutableSet+Extras.m'
94--- musicstreaming/categories/NSMutableSet+Extras.m 2011-04-08 01:55:24 +0000
95+++ musicstreaming/categories/NSMutableSet+Extras.m 1970-01-01 00:00:00 +0000
96@@ -1,57 +0,0 @@
97-//
98-// NSMutableSet+Extras.m
99-// iSub
100-//
101-// Created by Zachery Bir on 4/7/11.
102-// Copyright 2011 Canonical Ltd.
103-//
104-// This program is free software: you can redistribute it and/or modify it
105-// under the terms of the GNU Affero General Public License version 3,
106-// as published by the Free Software Foundation.
107-//
108-// This program is distributed in the hope that it will be useful, but
109-// WITHOUT ANY WARRANTY; without even the implied warranties of
110-// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
111-// PURPOSE. See the GNU Affero General Public License for more details.
112-//
113-// You should have received a copy of the GNU Affero General Public License
114-// along with this program. If not, see <http://www.gnu.org/licenses/>.
115-
116-#import "NSMutableSet+Extras.h"
117-
118-// helper function: get the string form of any object
119-static NSString *toString(id object)
120-{
121- return [NSString stringWithFormat: @"%@", object];
122-}
123-
124-// helper function: get the url encoded string form of any object
125-static NSString *urlEncode(id object)
126-{
127- NSString *string = toString(object);
128- return [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
129-}
130-
131-@implementation NSMutableSet (Extras)
132-
133-- (void)addKeyValueObjectFromArray:(NSArray *)array
134-{
135- [self addObject:[NSDictionary dictionaryWithObjects:array
136- forKeys:[NSArray arrayWithObjects:@"key", @"value", nil]]];
137-}
138-
139-- (NSString*)urlEncodedString
140-{
141- NSMutableArray *parts = [NSMutableArray array];
142-
143- for (id object in self)
144- {
145- id key = [object objectForKey:@"key"];
146- id value = [object objectForKey:@"value"];
147- NSString *part = [NSString stringWithFormat:@"%@=%@",urlEncode(key),urlEncode(value)];
148- [parts addObject:part];
149- }
150- return [parts componentsJoinedByString:@"&"];
151-}
152-
153-@end
154
155=== removed file 'musicstreaming/controls/MiniHudView.h'
156--- musicstreaming/controls/MiniHudView.h 2011-05-02 07:47:25 +0000
157+++ musicstreaming/controls/MiniHudView.h 1970-01-01 00:00:00 +0000
158@@ -1,17 +0,0 @@
159-//
160-// MiniHudView.h
161-// iSub
162-//
163-// Created by Aaron Brethorst on 5/2/11.
164-// Copyright 2011 Canonical. All rights reserved.
165-//
166-
167-#import <UIKit/UIKit.h>
168-
169-@interface MiniHudView : UIView
170-{
171- UIActivityIndicatorView *spinner;
172-}
173-- (void)show:(BOOL)yn;
174-- (void)hide:(BOOL)yn;
175-@end
176
177=== removed file 'musicstreaming/controls/MiniHudView.m'
178--- musicstreaming/controls/MiniHudView.m 2011-05-02 07:47:25 +0000
179+++ musicstreaming/controls/MiniHudView.m 1970-01-01 00:00:00 +0000
180@@ -1,54 +0,0 @@
181-//
182-// MiniHudView.m
183-// iSub
184-//
185-// Created by Aaron Brethorst on 5/2/11.
186-// Copyright 2011 Canonical. All rights reserved.
187-//
188-
189-#import "MiniHudView.h"
190-#import <QuartzCore/QuartzCore.h>
191-
192-@implementation MiniHudView
193-
194-- (id)initWithFrame:(CGRect)aFrame
195-{
196- if ((self = [super initWithFrame:aFrame]))
197- {
198- self.opaque = NO;
199- self.backgroundColor = [UIColor colorWithWhite:0.3 alpha:0.9f];
200- self.layer.cornerRadius = 8.0f;
201-
202- spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
203- spinner.frame = CGRectMake(5, 5, 20, 20);
204- [self addSubview:spinner];
205-
206- self.hidden = YES;
207- }
208- return self;
209-}
210-
211-- (void)layoutSubviews
212-{
213- [super layoutSubviews];
214-}
215-
216-- (void)show:(BOOL)yn
217-{
218- [spinner startAnimating];
219- self.hidden = NO;
220-}
221-
222-- (void)hide:(BOOL)yn
223-{
224- [spinner stopAnimating];
225- self.hidden = YES;
226-}
227-
228-- (void)dealloc
229-{
230- [spinner release];
231- [super dealloc];
232-}
233-
234-@end
235
236=== modified file 'musicstreaming/iSub-Info.plist'
237--- musicstreaming/iSub-Info.plist 2011-06-07 09:20:03 +0000
238+++ musicstreaming/iSub-Info.plist 2011-06-21 18:28:35 +0000
239@@ -41,7 +41,7 @@
240 </dict>
241 </array>
242 <key>CFBundleVersion</key>
243- <string>6</string>
244+ <string>10</string>
245 <key>LSRequiresIPhoneOS</key>
246 <false/>
247 <key>NSMainNibFile</key>
248
249=== modified file 'musicstreaming/iSub.xcodeproj/project.pbxproj'
250--- musicstreaming/iSub.xcodeproj/project.pbxproj 2011-06-16 16:39:50 +0000
251+++ musicstreaming/iSub.xcodeproj/project.pbxproj 2011-06-21 18:28:35 +0000
252@@ -21,14 +21,12 @@
253 91018B0B13573BBB0051EFDC /* UIImage+Resize.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B0A13573BBB0051EFDC /* UIImage+Resize.m */; };
254 91018B0E13573D150051EFDC /* UIImage+Alpha.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B0D13573D150051EFDC /* UIImage+Alpha.m */; };
255 91018B1113573D350051EFDC /* UIImage+RoundedCorner.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B1013573D350051EFDC /* UIImage+RoundedCorner.m */; };
256- 91018B25135922BF0051EFDC /* PlaylistEditViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 91018B24135922BE0051EFDC /* PlaylistEditViewController.xib */; };
257 91018B4B135A724B0051EFDC /* PlaylistEditAlbumListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B42135A724B0051EFDC /* PlaylistEditAlbumListViewController.m */; };
258 91018B4C135A724B0051EFDC /* PlaylistEditAlbumViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B44135A724B0051EFDC /* PlaylistEditAlbumViewController.m */; };
259 91018B4D135A724B0051EFDC /* PlaylistEditArtistListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B46135A724B0051EFDC /* PlaylistEditArtistListViewController.m */; };
260 91018B4E135A724B0051EFDC /* PlaylistEditArtistViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B48135A724B0051EFDC /* PlaylistEditArtistViewController.m */; };
261 91018B4F135A724B0051EFDC /* PlaylistEditSongListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91018B4A135A724B0051EFDC /* PlaylistEditSongListViewController.m */; };
262 9110DC38134C045A0046B8E4 /* AlbumParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 9110DC37134C04590046B8E4 /* AlbumParser.m */; };
263- 9110DC41134E4EEF0046B8E4 /* NSMutableSet+Extras.m in Sources */ = {isa = PBXBuildFile; fileRef = 9110DC40134E4EEF0046B8E4 /* NSMutableSet+Extras.m */; };
264 9110DC44134EAC740046B8E4 /* AlbumListParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 9110DC43134EAC730046B8E4 /* AlbumListParser.m */; };
265 9110DC571354A7490046B8E4 /* AlbumArtistUITableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9110DC561354A7470046B8E4 /* AlbumArtistUITableViewCell.m */; };
266 9112B0241383FF27003C1D93 /* albums.png in Resources */ = {isa = PBXBuildFile; fileRef = 9112B01E1383FF27003C1D93 /* albums.png */; };
267@@ -61,6 +59,7 @@
268 91BE4018138E8D2300D44D68 /* UIActionSheet+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = 91BE4015138E8D2300D44D68 /* UIActionSheet+Blocks.m */; };
269 91BE4019138E8D2300D44D68 /* UIAlertView+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = 91BE4017138E8D2300D44D68 /* UIAlertView+Blocks.m */; };
270 91BE401C138E8D3A00D44D68 /* RIButtonItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 91BE401B138E8D3A00D44D68 /* RIButtonItem.m */; };
271+ 91E0778913ABAD6200AA7CB2 /* PlaylistSongIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = 91E0778813ABAD6200AA7CB2 /* PlaylistSongIndex.m */; };
272 91E88609132DA82000618994 /* PlaylistParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 91E88608132DA82000618994 /* PlaylistParser.m */; };
273 9316628812264A74003B0EB7 /* NSDate+Extras.m in Sources */ = {isa = PBXBuildFile; fileRef = 9316628712264A74003B0EB7 /* NSDate+Extras.m */; };
274 932E7A6E1254747E00E7C8FF /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 932E7A6D1254747E00E7C8FF /* Default@2x.png */; };
275@@ -100,7 +99,6 @@
276 93D6B5111252CA71007880B0 /* music_512.png in Resources */ = {isa = PBXBuildFile; fileRef = 93D6B50D1252CA71007880B0 /* music_512.png */; };
277 93D6B5151252CB34007880B0 /* music_57@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93D6B5141252CB34007880B0 /* music_57@2x.png */; };
278 93D6B54B1252CE57007880B0 /* URLQueryStringParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D6B54A1252CE57007880B0 /* URLQueryStringParser.m */; };
279- 93DF12D9136E968E00D6C085 /* MiniHudView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93DF12D8136E968E00D6C085 /* MiniHudView.m */; };
280 93DFFE3F135D70B60061F29F /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93DFFE3E135D70B60061F29F /* CoreData.framework */; };
281 93DFFE45135D71030061F29F /* MOC.m in Sources */ = {isa = PBXBuildFile; fileRef = 93DFFE44135D71030061F29F /* MOC.m */; };
282 93DFFE4D135D71760061F29F /* music.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 93DFFE4C135D71760061F29F /* music.xcdatamodeld */; };
283@@ -163,7 +161,6 @@
284 91018B0D13573D150051EFDC /* UIImage+Alpha.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Alpha.m"; sourceTree = "<group>"; };
285 91018B0F13573D350051EFDC /* UIImage+RoundedCorner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+RoundedCorner.h"; sourceTree = "<group>"; };
286 91018B1013573D350051EFDC /* UIImage+RoundedCorner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+RoundedCorner.m"; sourceTree = "<group>"; };
287- 91018B24135922BE0051EFDC /* PlaylistEditViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PlaylistEditViewController.xib; sourceTree = "<group>"; };
288 91018B41135A724B0051EFDC /* PlaylistEditAlbumListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistEditAlbumListViewController.h; path = view_controllers/PlaylistEditAlbumListViewController.h; sourceTree = "<group>"; };
289 91018B42135A724B0051EFDC /* PlaylistEditAlbumListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PlaylistEditAlbumListViewController.m; path = view_controllers/PlaylistEditAlbumListViewController.m; sourceTree = "<group>"; };
290 91018B43135A724B0051EFDC /* PlaylistEditAlbumViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistEditAlbumViewController.h; path = view_controllers/PlaylistEditAlbumViewController.h; sourceTree = "<group>"; };
291@@ -176,8 +173,6 @@
292 91018B4A135A724B0051EFDC /* PlaylistEditSongListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PlaylistEditSongListViewController.m; path = view_controllers/PlaylistEditSongListViewController.m; sourceTree = "<group>"; };
293 9110DC36134C04590046B8E4 /* AlbumParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlbumParser.h; sourceTree = "<group>"; };
294 9110DC37134C04590046B8E4 /* AlbumParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlbumParser.m; sourceTree = "<group>"; };
295- 9110DC3F134E4EEF0046B8E4 /* NSMutableSet+Extras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableSet+Extras.h"; sourceTree = "<group>"; };
296- 9110DC40134E4EEF0046B8E4 /* NSMutableSet+Extras.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableSet+Extras.m"; sourceTree = "<group>"; };
297 9110DC42134EAC720046B8E4 /* AlbumListParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlbumListParser.h; sourceTree = "<group>"; };
298 9110DC43134EAC730046B8E4 /* AlbumListParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlbumListParser.m; sourceTree = "<group>"; };
299 9110DC551354A7460046B8E4 /* AlbumArtistUITableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = AlbumArtistUITableViewCell.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
300@@ -226,6 +221,8 @@
301 91BE4017138E8D2300D44D68 /* UIAlertView+Blocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertView+Blocks.m"; sourceTree = "<group>"; };
302 91BE401A138E8D3A00D44D68 /* RIButtonItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RIButtonItem.h; sourceTree = "<group>"; };
303 91BE401B138E8D3A00D44D68 /* RIButtonItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RIButtonItem.m; sourceTree = "<group>"; };
304+ 91E0778713ABAD6100AA7CB2 /* PlaylistSongIndex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaylistSongIndex.h; sourceTree = "<group>"; };
305+ 91E0778813ABAD6200AA7CB2 /* PlaylistSongIndex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlaylistSongIndex.m; sourceTree = "<group>"; };
306 91E88607132DA82000618994 /* PlaylistParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaylistParser.h; sourceTree = "<group>"; };
307 91E88608132DA82000618994 /* PlaylistParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlaylistParser.m; sourceTree = "<group>"; };
308 9316628612264A74003B0EB7 /* NSDate+Extras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+Extras.h"; sourceTree = "<group>"; };
309@@ -288,8 +285,6 @@
310 93D6B5141252CB34007880B0 /* music_57@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "music_57@2x.png"; sourceTree = "<group>"; };
311 93D6B5491252CE57007880B0 /* URLQueryStringParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLQueryStringParser.h; sourceTree = "<group>"; };
312 93D6B54A1252CE57007880B0 /* URLQueryStringParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = URLQueryStringParser.m; sourceTree = "<group>"; };
313- 93DF12D7136E968E00D6C085 /* MiniHudView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MiniHudView.h; sourceTree = "<group>"; };
314- 93DF12D8136E968E00D6C085 /* MiniHudView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MiniHudView.m; sourceTree = "<group>"; };
315 93DFFE3E135D70B60061F29F /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
316 93DFFE43135D71030061F29F /* MOC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MOC.h; sourceTree = "<group>"; };
317 93DFFE44135D71030061F29F /* MOC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MOC.m; sourceTree = "<group>"; };
318@@ -549,8 +544,6 @@
319 93D6B213124F0F62007880B0 /* NSNumber+Extras.m */,
320 93D6B2D1124FDA56007880B0 /* NSMutableArray+Extras.h */,
321 93D6B2D2124FDA56007880B0 /* NSMutableArray+Extras.m */,
322- 9110DC3F134E4EEF0046B8E4 /* NSMutableSet+Extras.h */,
323- 9110DC40134E4EEF0046B8E4 /* NSMutableSet+Extras.m */,
324 91018B0913573BBB0051EFDC /* UIImage+Resize.h */,
325 91018B0A13573BBB0051EFDC /* UIImage+Resize.m */,
326 91018B0C13573D150051EFDC /* UIImage+Alpha.h */,
327@@ -593,8 +586,6 @@
328 936F230912284D1900070F43 /* NamedTextFieldCell.m */,
329 912D1262134A162000721EE4 /* AlertPrompt.h */,
330 912D1263134A162000721EE4 /* AlertPrompt.m */,
331- 93DF12D7136E968E00D6C085 /* MiniHudView.h */,
332- 93DF12D8136E968E00D6C085 /* MiniHudView.m */,
333 );
334 name = Controls;
335 path = controls;
336@@ -607,14 +598,16 @@
337 93DFFE44135D71030061F29F /* MOC.m */,
338 93F3344E1247FA2C006C6707 /* Album.h */,
339 93F3344F1247FA2C006C6707 /* Album.m */,
340+ 93F334501247FA2C006C6707 /* Artist.h */,
341 93F334511247FA2C006C6707 /* Artist.m */,
342- 93F334501247FA2C006C6707 /* Artist.h */,
343 936F208E12273D9000070F43 /* Song.h */,
344 936F208F12273D9000070F43 /* Song.m */,
345 936F20661227364200070F43 /* Playlist.h */,
346 936F20671227364200070F43 /* Playlist.m */,
347 9646DB7B13A8FF4700CB42D2 /* CachedSongsPlaylist.h */,
348 9646DB7C13A8FF4700CB42D2 /* CachedSongsPlaylist.m */,
349+ 91E0778713ABAD6100AA7CB2 /* PlaylistSongIndex.h */,
350+ 91E0778813ABAD6200AA7CB2 /* PlaylistSongIndex.m */,
351 );
352 name = Models;
353 path = models;
354@@ -670,7 +663,6 @@
355 93F334641247FB02006C6707 /* SongViewController.xib */,
356 93F334651247FB02006C6707 /* MainWindow.xib */,
357 93F334661247FB02006C6707 /* SearchableTableViewController.xib */,
358- 91018B24135922BE0051EFDC /* PlaylistEditViewController.xib */,
359 );
360 name = Xibs;
361 path = xibs;
362@@ -825,7 +817,6 @@
363 932E7AA01255265A00E7C8FF /* about.css in Resources */,
364 932E7AA11255265A00E7C8FF /* about.html in Resources */,
365 932E7B0B12552CD500E7C8FF /* arrow.png in Resources */,
366- 91018B25135922BF0051EFDC /* PlaylistEditViewController.xib in Resources */,
367 9112B0241383FF27003C1D93 /* albums.png in Resources */,
368 9112B0251383FF27003C1D93 /* artists.png in Resources */,
369 9112B0261383FF27003C1D93 /* playlists.png in Resources */,
370@@ -894,7 +885,6 @@
371 912D1264134A162000721EE4 /* AlertPrompt.m in Sources */,
372 912D1267134B609700721EE4 /* PlaylistEditViewController.m in Sources */,
373 9110DC38134C045A0046B8E4 /* AlbumParser.m in Sources */,
374- 9110DC41134E4EEF0046B8E4 /* NSMutableSet+Extras.m in Sources */,
375 9110DC44134EAC740046B8E4 /* AlbumListParser.m in Sources */,
376 9110DC571354A7490046B8E4 /* AlbumArtistUITableViewCell.m in Sources */,
377 91018B0B13573BBB0051EFDC /* UIImage+Resize.m in Sources */,
378@@ -909,7 +899,6 @@
379 93DFFE45135D71030061F29F /* MOC.m in Sources */,
380 93DFFE4D135D71760061F29F /* music.xcdatamodeld in Sources */,
381 93DFFE54135D72420061F29F /* NSManagedObjectContext+Additions.m in Sources */,
382- 93DF12D9136E968E00D6C085 /* MiniHudView.m in Sources */,
383 937FAA11137CFC1B00507E51 /* AlbumArtLoader.m in Sources */,
384 937FAA12137CFC1B00507E51 /* AlbumArtLoadingOperation.m in Sources */,
385 937FAA15137CFC5000507E51 /* Downloader.m in Sources */,
386@@ -923,6 +912,7 @@
387 9674C2C513A7DC01004509E4 /* UORadialProgressControl.m in Sources */,
388 9646DB7D13A8FF4700CB42D2 /* CachedSongsPlaylist.m in Sources */,
389 96FB790A13AA628700D8D4A4 /* UONetworkStatusCoordinator.m in Sources */,
390+ 91E0778913ABAD6200AA7CB2 /* PlaylistSongIndex.m in Sources */,
391 );
392 runOnlyForDeploymentPostprocessing = 0;
393 };
394
395=== modified file 'musicstreaming/models/Album.m'
396--- musicstreaming/models/Album.m 2011-06-14 17:06:21 +0000
397+++ musicstreaming/models/Album.m 2011-06-21 18:28:35 +0000
398@@ -30,7 +30,7 @@
399
400 #import "Album.h"
401 #import "Artist.h"
402-#import "NSMutableSet+Extras.h"
403+#import "NSMutableArray+Extras.h"
404 #import "NSString+Extras.h"
405 #import "AlbumParser.h"
406 #import "Subsonic.h"
407@@ -83,7 +83,7 @@
408 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
409 NSError *error = nil;
410
411- NSMutableSet *parameters = [NSMutableSet set];
412+ NSMutableArray *parameters = [NSMutableArray array];
413 [parameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"id", self.albumId, nil]];
414 NSURL *url = [[Subsonic sharedSubsonic] getBaseURL:@"getAlbum.view" parameters:parameters];
415 NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
416
417=== modified file 'musicstreaming/models/Artist.m'
418--- musicstreaming/models/Artist.m 2011-06-14 17:06:21 +0000
419+++ musicstreaming/models/Artist.m 2011-06-21 18:28:35 +0000
420@@ -31,7 +31,7 @@
421 #import "Artist.h"
422 #import "Album.h"
423 #import "Subsonic.h"
424-#import "NSMutableSet+Extras.h"
425+#import "NSMutableArray+Extras.h"
426 #import "NSString+Extras.h"
427 #import "ArtistParser.h"
428
429@@ -99,7 +99,7 @@
430 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
431 NSError *error = nil;
432
433- NSMutableSet *parameters = [NSMutableSet set];
434+ NSMutableArray *parameters = [NSMutableArray array];
435 [parameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"id", self.artistId, nil]];
436 NSURL *url = [[Subsonic sharedSubsonic] getBaseURL:@"getMusicDirectory.view" parameters:parameters];
437 NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
438
439=== modified file 'musicstreaming/models/Playlist.h'
440--- musicstreaming/models/Playlist.h 2011-06-15 16:49:27 +0000
441+++ musicstreaming/models/Playlist.h 2011-06-21 18:28:35 +0000
442@@ -19,26 +19,29 @@
443
444 #import <Foundation/Foundation.h>
445
446-@class Song;
447+@class Song, PlaylistSongIndex;
448
449 @interface Playlist : NSManagedObject
450 {
451 }
452+@property(nonatomic,retain) NSString *name;
453 @property(nonatomic,retain) NSString *playlistId;
454-@property(nonatomic,retain) NSString *name;
455-@property(nonatomic,retain) NSSet *songs;
456+@property(nonatomic,retain) NSSet *playlistSongIndexes;
457+@property(nonatomic,readonly) NSArray *songs;
458
459-+ (BOOL)playlistWithIdExists:(NSString*)aPlaylistId;
460-+ (Playlist*)playlistWithId:(NSString*)aPlaylistId;
461++ (BOOL)playlistWithNameExists:(NSString*)aPlaylistName;
462++ (Playlist*)playlistWithName:(NSString*)aPlaylistName;
463 - (BOOL)matchesSearchQuery:(NSString *)query;
464 - (NSError*)loadSongs;
465 - (BOOL)isEditable;
466+- (void)addSong:(Song *)song;
467+- (void)removeSong:(Song *)song;
468 @end
469
470 // coalesce these into one @interface Album (CoreDataGeneratedAccessors) section
471 @interface Playlist (CoreDataGeneratedAccessors)
472-- (void)addSongsObject:(Song *)value;
473-- (void)removeSongsObject:(Song *)value;
474-- (void)addSongs:(NSSet *)value;
475-- (void)removeSongs:(NSSet *)value;
476+- (void)addPlaylistSongIndexesObject:(PlaylistSongIndex *)value;
477+- (void)removePlaylistSongIndexesObject:(PlaylistSongIndex *)value;
478+- (void)addPlaylistSongIndexes:(NSSet *)value;
479+- (void)removePlaylistSongIndexes:(NSSet *)value;
480 @end
481
482=== modified file 'musicstreaming/models/Playlist.m'
483--- musicstreaming/models/Playlist.m 2011-06-15 16:49:27 +0000
484+++ musicstreaming/models/Playlist.m 2011-06-21 18:28:35 +0000
485@@ -19,25 +19,27 @@
486
487 #import "Playlist.h"
488 #import "Subsonic.h"
489-#import "NSMutableSet+Extras.h"
490+#import "NSMutableArray+Extras.h"
491 #import "PlaylistParser.h"
492+#import "PlaylistSongIndex.h"
493+#import "Song.h"
494
495 @implementation Playlist
496
497-@dynamic playlistId, name, songs;
498+@dynamic playlistId, name, playlistSongIndexes;
499
500-+ (BOOL)playlistWithIdExists:(NSString *)aPlaylistId
501++ (BOOL)playlistWithNameExists:(NSString *)aPlaylistName
502 {
503- return (nil != [Playlist playlistWithId:aPlaylistId]);
504+ return (nil != [Playlist playlistWithName:aPlaylistName]);
505 }
506
507-+ (Playlist *)playlistWithId:(NSString *)aPlaylistId
508++ (Playlist *)playlistWithName:(NSString *)aPlaylistName
509 {
510 NSFetchRequest * fetch = [[NSFetchRequest alloc] init];
511 NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Playlist" inManagedObjectContext:PerThreadManagedObjectContext()];
512 [fetch setEntity:entityDescription];
513
514- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"playlistId == %@", aPlaylistId];
515+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", aPlaylistName];
516 [fetch setPredicate:predicate];
517
518 NSError * error = nil;
519@@ -59,7 +61,7 @@
520 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
521 NSError *error = nil;
522
523- NSMutableSet *parameters = [NSMutableSet set];
524+ NSMutableArray *parameters = [NSMutableArray array];
525 [parameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"id", self.playlistId, nil]];
526 NSURL *url = [[Subsonic sharedSubsonic] getBaseURL:@"getPlaylist.view" parameters:parameters];
527 NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
528@@ -81,6 +83,40 @@
529 return [error autorelease];
530 }
531
532+- (NSArray *)songs
533+{
534+ // return playlistSongIndexes sorted by index
535+ NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES];
536+ NSArray *results = [[self.playlistSongIndexes sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]] valueForKey:@"songEntity"];
537+ return results;
538+}
539+
540+// Do the crazy PlaylistSongIndex lookup/clobber dance inside these methods
541+- (void)addSong:(Song *)song
542+{
543+ PlaylistSongIndex *playlistSongIndex = [NSEntityDescription insertNewObjectForEntityForName:@"PlaylistSongIndex" inManagedObjectContext:PerThreadManagedObjectContext()];
544+ playlistSongIndex.playlistEntity = self;
545+ playlistSongIndex.songEntity = song;
546+ playlistSongIndex.index = [NSNumber numberWithUnsignedInt:[self.playlistSongIndexes count]];
547+ SaveContext();
548+}
549+
550+- (void)removeSong:(Song *)song
551+{
552+ // Look up (potentially) all records where playlistEntity is self, and songEntity is song, and blow them away
553+ NSSet *condemned = [self.playlistSongIndexes filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"songEntity = %@", song]];
554+ for (PlaylistSongIndex *playlistSongIndex in condemned)
555+ {
556+ [PerThreadManagedObjectContext() deleteObject:playlistSongIndex];
557+ }
558+ SaveContext();
559+
560+ [[self.playlistSongIndexes sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES]]] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
561+ ((PlaylistSongIndex *)obj).index = [NSNumber numberWithUnsignedInt:idx];
562+ }];
563+ SaveContext();
564+}
565+
566 - (NSString*)description
567 {
568 return [NSString stringWithFormat:@"%@ (%@) MOC %@", self.name, self.playlistId, [self managedObjectContext]];
569
570=== added file 'musicstreaming/models/PlaylistSongIndex.h'
571--- musicstreaming/models/PlaylistSongIndex.h 1970-01-01 00:00:00 +0000
572+++ musicstreaming/models/PlaylistSongIndex.h 2011-06-21 18:28:35 +0000
573@@ -0,0 +1,32 @@
574+//
575+// PlaylistSongIndex.h
576+// iSub
577+//
578+// Created by Zachery Bir on 6/17/11.
579+// Copyright 2011 Canonical Ltd.
580+//
581+// This program is free software: you can redistribute it and/or modify it
582+// under the terms of the GNU Affero General Public License version 3,
583+// as published by the Free Software Foundation.
584+//
585+// This program is distributed in the hope that it will be useful, but
586+// WITHOUT ANY WARRANTY; without even the implied warranties of
587+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
588+// PURPOSE. See the GNU Affero General Public License for more details.
589+//
590+// You should have received a copy of the GNU Affero General Public License
591+// along with this program. If not, see <http://www.gnu.org/licenses/>.
592+
593+#import <Foundation/Foundation.h>
594+
595+@class Playlist, Song;
596+
597+@interface PlaylistSongIndex : NSManagedObject {
598+@private
599+
600+}
601+@property (nonatomic, retain) NSNumber *index;
602+
603+@property (nonatomic, retain) Playlist *playlistEntity;
604+@property (nonatomic, retain) Song *songEntity;
605+@end
606
607=== added file 'musicstreaming/models/PlaylistSongIndex.m'
608--- musicstreaming/models/PlaylistSongIndex.m 1970-01-01 00:00:00 +0000
609+++ musicstreaming/models/PlaylistSongIndex.m 2011-06-21 18:28:35 +0000
610@@ -0,0 +1,27 @@
611+//
612+// PlaylistSongIndex.m
613+// iSub
614+//
615+// Created by Zachery Bir on 6/17/11.
616+// Copyright 2011 Canonical Ltd.
617+//
618+// This program is free software: you can redistribute it and/or modify it
619+// under the terms of the GNU Affero General Public License version 3,
620+// as published by the Free Software Foundation.
621+//
622+// This program is distributed in the hope that it will be useful, but
623+// WITHOUT ANY WARRANTY; without even the implied warranties of
624+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
625+// PURPOSE. See the GNU Affero General Public License for more details.
626+//
627+// You should have received a copy of the GNU Affero General Public License
628+// along with this program. If not, see <http://www.gnu.org/licenses/>.
629+
630+#import "PlaylistSongIndex.h"
631+
632+
633+@implementation PlaylistSongIndex
634+
635+@dynamic index, playlistEntity, songEntity;
636+
637+@end
638
639=== modified file 'musicstreaming/models/Song.h'
640--- musicstreaming/models/Song.h 2011-06-13 19:00:38 +0000
641+++ musicstreaming/models/Song.h 2011-06-21 18:28:35 +0000
642@@ -28,7 +28,7 @@
643 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
644 // DAMAGE.
645
646-@class Artist, Album, Playlist;
647+@class Artist, Album, PlaylistSongIndex;
648
649 @interface Song : NSManagedObject
650 {
651@@ -43,11 +43,12 @@
652 @property (nonatomic, retain) NSNumber *duration;
653 @property (nonatomic, retain) NSNumber *bitRate;
654 @property (nonatomic, retain) NSNumber *track;
655+@property (nonatomic, retain) NSNumber *discNumber;
656 @property (nonatomic, retain) NSNumber *year;
657 @property (nonatomic, retain) NSNumber *size;
658 @property (nonatomic, retain) Artist *artistEntity;
659 @property (nonatomic, retain) Album *albumEntity;
660-@property (nonatomic, retain) NSSet *playlistEntities;
661+@property (nonatomic, retain) NSSet *playlistSongIndexes;
662 @property (nonatomic, retain) NSString *cachedSongPath;
663
664 + (BOOL)songWithIdExists:(NSString*)aSongId;
665@@ -59,8 +60,8 @@
666 @end
667
668 @interface Song (CoreDataGeneratedAccessors)
669-- (void)addPlaylistEntitiesObject:(Playlist *)value;
670-- (void)removePlaylistEntitiesObject:(Playlist *)value;
671-- (void)addPlaylistEntities:(NSSet *)value;
672-- (void)removePlaylistEntities:(NSSet *)value;
673+- (void)addPlaylistSongIndexesObject:(PlaylistSongIndex *)value;
674+- (void)removePlaylistSongIndexesObject:(PlaylistSongIndex *)value;
675+- (void)addPlaylistSongIndexes:(NSSet *)value;
676+- (void)removePlaylistSongIndexes:(NSSet *)value;
677 @end
678
679=== modified file 'musicstreaming/models/Song.m'
680--- musicstreaming/models/Song.m 2011-06-14 17:06:21 +0000
681+++ musicstreaming/models/Song.m 2011-06-21 18:28:35 +0000
682@@ -34,8 +34,8 @@
683 #import "NSString+Extras.h"
684
685 @implementation Song
686-@dynamic title, songId, artist, album, genre, coverArtId, path, duration, bitRate, track, year, size;
687-@dynamic artistEntity, albumEntity, playlistEntities, cachedSongPath;
688+@dynamic title, songId, artist, album, genre, coverArtId, path, duration, bitRate, track, discNumber, year, size;
689+@dynamic artistEntity, albumEntity, playlistSongIndexes, cachedSongPath;
690
691 + (BOOL)songWithIdExists:(NSString*)aSongId
692 {
693@@ -77,7 +77,13 @@
694
695 - (NSComparisonResult)compare:(Song*)s
696 {
697- return [self.track compare:s.track];
698+ NSUInteger selfPathArray[] = {[self.discNumber integerValue], [self.track integerValue]};
699+ NSUInteger otherPathArray[] = {[s.discNumber integerValue], [s.track integerValue]};
700+
701+ NSIndexPath *selfPath = [NSIndexPath indexPathWithIndexes:selfPathArray length:2];
702+ NSIndexPath *otherPath = [NSIndexPath indexPathWithIndexes:otherPathArray length:2];
703+
704+ return [selfPath compare:otherPath];
705 }
706
707 - (NSString*)description
708
709=== modified file 'musicstreaming/music.xcdatamodeld/music.xcdatamodel/elements'
710Binary files musicstreaming/music.xcdatamodeld/music.xcdatamodel/elements 2011-06-13 19:00:38 +0000 and musicstreaming/music.xcdatamodeld/music.xcdatamodel/elements 2011-06-21 18:28:35 +0000 differ
711=== modified file 'musicstreaming/music.xcdatamodeld/music.xcdatamodel/layout'
712Binary files musicstreaming/music.xcdatamodeld/music.xcdatamodel/layout 2011-06-13 19:00:38 +0000 and musicstreaming/music.xcdatamodeld/music.xcdatamodel/layout 2011-06-21 18:28:35 +0000 differ
713=== modified file 'musicstreaming/utilities/AlbumParser.m'
714--- musicstreaming/utilities/AlbumParser.m 2011-06-14 17:06:21 +0000
715+++ musicstreaming/utilities/AlbumParser.m 2011-06-21 18:28:35 +0000
716@@ -71,6 +71,7 @@
717 song.duration = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"duration"]];
718 song.bitRate = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"bitRate"]];
719 song.track = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"track"]];
720+ song.discNumber = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"disc_number"]];
721 song.year = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"year"]];
722 song.size = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"size"]];
723
724
725=== modified file 'musicstreaming/utilities/Globals.h'
726--- musicstreaming/utilities/Globals.h 2011-06-07 09:20:03 +0000
727+++ musicstreaming/utilities/Globals.h 2011-06-21 18:28:35 +0000
728@@ -3,8 +3,19 @@
729 // iSub
730 //
731 // Created by Aaron Brethorst on 5/13/11.
732-// Copyright 2011 Canonical. All rights reserved.
733+// Copyright 2011 Canonical Ltd.
734+//
735+// This program is free software: you can redistribute it and/or modify it
736+// under the terms of the GNU Affero General Public License version 3,
737+// as published by the Free Software Foundation.
738+//
739+// This program is distributed in the hope that it will be useful, but
740+// WITHOUT ANY WARRANTY; without even the implied warranties of
741+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
742+// PURPOSE. See the GNU Affero General Public License for more details.
743 //
744+// You should have received a copy of the GNU Affero General Public License
745+// along with this program. If not, see <http://www.gnu.org/licenses/>.
746
747 #import <Foundation/Foundation.h>
748
749
750=== modified file 'musicstreaming/utilities/Globals.m'
751--- musicstreaming/utilities/Globals.m 2011-06-07 09:20:03 +0000
752+++ musicstreaming/utilities/Globals.m 2011-06-21 18:28:35 +0000
753@@ -3,8 +3,19 @@
754 // iSub
755 //
756 // Created by Aaron Brethorst on 5/13/11.
757-// Copyright 2011 Canonical. All rights reserved.
758+// Copyright 2011 Canonical Ltd.
759+//
760+// This program is free software: you can redistribute it and/or modify it
761+// under the terms of the GNU Affero General Public License version 3,
762+// as published by the Free Software Foundation.
763+//
764+// This program is distributed in the hope that it will be useful, but
765+// WITHOUT ANY WARRANTY; without even the implied warranties of
766+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
767+// PURPOSE. See the GNU Affero General Public License for more details.
768 //
769+// You should have received a copy of the GNU Affero General Public License
770+// along with this program. If not, see <http://www.gnu.org/licenses/>.
771
772 #import "Globals.h"
773
774
775=== modified file 'musicstreaming/utilities/PlaylistListParser.m'
776--- musicstreaming/utilities/PlaylistListParser.m 2011-05-27 18:23:44 +0000
777+++ musicstreaming/utilities/PlaylistListParser.m 2011-06-21 18:28:35 +0000
778@@ -37,15 +37,21 @@
779 }
780 else if ([elementName isEqualToString:@"playlist"])
781 {
782- if (![Playlist playlistWithIdExists:[attributeDict objectForKey:@"id"]] && ![[attributeDict objectForKey:@"title"] isEqual:@".AppleDouble"])
783- {
784- Playlist *playlist = [NSEntityDescription insertNewObjectForEntityForName:@"Playlist" inManagedObjectContext:PerThreadManagedObjectContext()];
785-
786- playlist.name = [attributeDict objectForKey:@"name"];
787- playlist.playlistId = [attributeDict objectForKey:@"id"];
788-
789- SaveContext();
790- }
791+ Playlist *playlist = nil;
792+
793+ if (![Playlist playlistWithNameExists:[attributeDict objectForKey:@"name"]] && ![[attributeDict objectForKey:@"title"] isEqual:@".AppleDouble"])
794+ {
795+ playlist = [NSEntityDescription insertNewObjectForEntityForName:@"Playlist" inManagedObjectContext:PerThreadManagedObjectContext()];
796+ }
797+ else
798+ {
799+ playlist = [Playlist playlistWithName:[attributeDict objectForKey:@"name"]];
800+ }
801+
802+ playlist.name = [attributeDict objectForKey:@"name"];
803+ playlist.playlistId = [attributeDict objectForKey:@"id"];
804+
805+ SaveContext();
806 }
807 }
808
809
810=== modified file 'musicstreaming/utilities/PlaylistParser.h'
811--- musicstreaming/utilities/PlaylistParser.h 2011-05-27 18:23:44 +0000
812+++ musicstreaming/utilities/PlaylistParser.h 2011-06-21 18:28:35 +0000
813@@ -24,9 +24,9 @@
814 @interface PlaylistParser : NSObject <NSXMLParserDelegate>
815 {
816 Playlist *playlist;
817- NSMutableArray *songs;
818+ NSMutableSet *songs;
819 NSNumberFormatter *numberFormatter;
820 }
821 @property(nonatomic,retain) NSManagedObjectID *playlistObjectId;
822-@property(nonatomic,retain) NSMutableArray *songs;
823+@property(nonatomic,retain) NSMutableSet *songs;
824 @end
825
826=== modified file 'musicstreaming/utilities/PlaylistParser.m'
827--- musicstreaming/utilities/PlaylistParser.m 2011-05-27 18:23:44 +0000
828+++ musicstreaming/utilities/PlaylistParser.m 2011-06-21 18:28:35 +0000
829@@ -20,6 +20,7 @@
830 #import "PlaylistParser.h"
831 #import "Playlist.h"
832 #import "Song.h"
833+#import "PlaylistSongIndex.h"
834 #import "NSDictionary+Extras.h"
835
836 @implementation PlaylistParser
837@@ -30,7 +31,7 @@
838 {
839 if ((self = [super init]))
840 {
841- songs = [[NSMutableArray alloc] init];
842+ songs = [[NSMutableSet alloc] init];
843 numberFormatter = [[NSNumberFormatter alloc] init];
844 }
845 return self;
846@@ -76,11 +77,14 @@
847
848 }
849
850- // do something with the order of songs.
851- [song addPlaylistEntitiesObject:playlist];
852- [playlist addSongsObject:song];
853- SaveContext();
854+ PlaylistSongIndex *playlistSongIndex = [NSEntityDescription insertNewObjectForEntityForName:@"PlaylistSongIndex" inManagedObjectContext:PerThreadManagedObjectContext()];
855+ playlistSongIndex.playlistEntity = playlist;
856+ playlistSongIndex.songEntity = song;
857+ playlistSongIndex.index = [NSNumber numberWithUnsignedInt:[songs count]];
858+ [songs addObject:playlistSongIndex];
859 }
860+ playlist.playlistSongIndexes = songs;
861+ SaveContext();
862 }
863
864 - (void) dealloc
865
866=== modified file 'musicstreaming/utilities/Subsonic.h'
867--- musicstreaming/utilities/Subsonic.h 2011-06-14 17:06:21 +0000
868+++ musicstreaming/utilities/Subsonic.h 2011-06-21 18:28:35 +0000
869@@ -42,7 +42,7 @@
870 + (Subsonic *)sharedSubsonic;
871 - (NSURL *)getCredsURL;
872 - (NSURL *)getBaseURL:(NSString *)action;
873-- (NSURL *)getBaseURL:(NSString *)action parameters:(NSSet*)extraParameters;
874+- (NSURL *)getBaseURL:(NSString *)action parameters:(NSArray*)extraParameters;
875 - (NSURL *)getStreamingURLForSongId:(NSString*)songId;
876 - (void)removeCredentials;
877 - (void)storeUsername:(NSString*)username password:(NSString*)password;
878
879=== modified file 'musicstreaming/utilities/Subsonic.m'
880--- musicstreaming/utilities/Subsonic.m 2011-06-14 17:06:21 +0000
881+++ musicstreaming/utilities/Subsonic.m 2011-06-21 18:28:35 +0000
882@@ -22,7 +22,7 @@
883 #include <netinet/in.h>
884 #include <netdb.h>
885 #include <arpa/inet.h>
886-#import "NSMutableSet+Extras.h"
887+#import "NSMutableArray+Extras.h"
888 #import "Reachability.h"
889
890 @interface Subsonic ()
891@@ -42,9 +42,7 @@
892 if ((self = [super init]))
893 {
894 self.defaultURL = @"https://streaming.one.ubuntu.com/rest";
895-// self.defaultURL = @"http://10.59.1.19:35204/musicstreaming/rest";
896 self.credsURL = @"https://one.ubuntu.com/phones/creds/ios?scheme=x-ubuntuone-music";
897-// self.credsURL = @"http://10.59.1.19:41858/phones/creds/ios?scheme=x-ubuntuone-music";
898 self.reachability = [Reachability reachabilityWithHostName:[[NSURL URLWithString:self.defaultURL] host]];
899 [self.reachability startNotifer];
900 }
901@@ -98,7 +96,7 @@
902
903 - (NSURL *)getStreamingURLForSongId:(NSString*)songId
904 {
905- NSMutableSet *parameters = [NSMutableSet set];
906+ NSMutableArray *parameters = [NSMutableArray array];
907 [parameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"id", songId, nil]];
908 return [self getBaseURL:@"stream.view" parameters:parameters];
909 }
910@@ -113,11 +111,11 @@
911 return [self getBaseURL:action parameters:nil];
912 }
913
914-- (NSURL *)getBaseURL:(NSString *)action parameters:(NSSet*)extraParameters
915+- (NSURL *)getBaseURL:(NSString *)action parameters:(NSArray*)extraParameters
916 {
917 if (self.defaultUserName && self.defaultPassword)
918 {
919- NSMutableSet *params = [NSMutableSet setWithSet:extraParameters];
920+ NSMutableArray *params = [NSMutableArray arrayWithArray:extraParameters];
921
922 [params addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"u", self.defaultUserName, nil]];
923 [params addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"p", self.defaultPassword, nil]];
924@@ -125,7 +123,6 @@
925 [params addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"c", @"iSub", nil]];
926
927 NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@?%@", self.defaultURL, action, [params urlEncodedString]]];
928- NSLog(@"URL generated: %@", url);
929 return url;
930 }
931 else
932
933=== modified file 'musicstreaming/utilities/operations/AbstractNetworkOperation.h'
934--- musicstreaming/utilities/operations/AbstractNetworkOperation.h 2011-05-13 05:54:19 +0000
935+++ musicstreaming/utilities/operations/AbstractNetworkOperation.h 2011-06-21 18:28:35 +0000
936@@ -3,8 +3,19 @@
937 // iSub
938 //
939 // Created by Aaron Brethorst on 5/12/11.
940-// Copyright 2011 Canonical. All rights reserved.
941+// Copyright 2011 Canonical Ltd.
942+//
943+// This program is free software: you can redistribute it and/or modify it
944+// under the terms of the GNU Affero General Public License version 3,
945+// as published by the Free Software Foundation.
946+//
947+// This program is distributed in the hope that it will be useful, but
948+// WITHOUT ANY WARRANTY; without even the implied warranties of
949+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
950+// PURPOSE. See the GNU Affero General Public License for more details.
951 //
952+// You should have received a copy of the GNU Affero General Public License
953+// along with this program. If not, see <http://www.gnu.org/licenses/>.
954
955 #import <Foundation/Foundation.h>
956
957
958=== modified file 'musicstreaming/utilities/operations/AbstractNetworkOperation.m'
959--- musicstreaming/utilities/operations/AbstractNetworkOperation.m 2011-06-16 16:52:07 +0000
960+++ musicstreaming/utilities/operations/AbstractNetworkOperation.m 2011-06-21 18:28:35 +0000
961@@ -3,8 +3,19 @@
962 // iSub
963 //
964 // Created by Aaron Brethorst on 5/12/11.
965-// Copyright 2011 Canonical. All rights reserved.
966+// Copyright 2011 Canonical Ltd.
967+//
968+// This program is free software: you can redistribute it and/or modify it
969+// under the terms of the GNU Affero General Public License version 3,
970+// as published by the Free Software Foundation.
971+//
972+// This program is distributed in the hope that it will be useful, but
973+// WITHOUT ANY WARRANTY; without even the implied warranties of
974+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
975+// PURPOSE. See the GNU Affero General Public License for more details.
976 //
977+// You should have received a copy of the GNU Affero General Public License
978+// along with this program. If not, see <http://www.gnu.org/licenses/>.
979
980 #import "AbstractNetworkOperation.h"
981
982
983=== modified file 'musicstreaming/utilities/operations/AlbumArtLoader.h'
984--- musicstreaming/utilities/operations/AlbumArtLoader.h 2011-05-27 18:20:22 +0000
985+++ musicstreaming/utilities/operations/AlbumArtLoader.h 2011-06-21 18:28:35 +0000
986@@ -3,8 +3,19 @@
987 // iSub
988 //
989 // Created by Aaron Brethorst on 5/4/11.
990-// Copyright 2011 Canonical. All rights reserved.
991+// Copyright 2011 Canonical Ltd.
992+//
993+// This program is free software: you can redistribute it and/or modify it
994+// under the terms of the GNU Affero General Public License version 3,
995+// as published by the Free Software Foundation.
996+//
997+// This program is distributed in the hope that it will be useful, but
998+// WITHOUT ANY WARRANTY; without even the implied warranties of
999+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1000+// PURPOSE. See the GNU Affero General Public License for more details.
1001 //
1002+// You should have received a copy of the GNU Affero General Public License
1003+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1004
1005 #import <UIKit/UIKit.h>
1006 #import "AlbumArtLoadingOperation.h"
1007
1008=== modified file 'musicstreaming/utilities/operations/AlbumArtLoader.m'
1009--- musicstreaming/utilities/operations/AlbumArtLoader.m 2011-06-07 09:20:03 +0000
1010+++ musicstreaming/utilities/operations/AlbumArtLoader.m 2011-06-21 18:28:35 +0000
1011@@ -3,12 +3,23 @@
1012 // iSub
1013 //
1014 // Created by Aaron Brethorst on 5/4/11.
1015-// Copyright 2011 Canonical. All rights reserved.
1016+// Copyright 2011 Canonical Ltd.
1017+//
1018+// This program is free software: you can redistribute it and/or modify it
1019+// under the terms of the GNU Affero General Public License version 3,
1020+// as published by the Free Software Foundation.
1021+//
1022+// This program is distributed in the hope that it will be useful, but
1023+// WITHOUT ANY WARRANTY; without even the implied warranties of
1024+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1025+// PURPOSE. See the GNU Affero General Public License for more details.
1026 //
1027+// You should have received a copy of the GNU Affero General Public License
1028+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1029
1030 #import "AlbumArtLoader.h"
1031 #import "Subsonic.h"
1032-#import "NSMutableSet+Extras.h"
1033+#import "NSMutableArray+Extras.h"
1034 #import "UIImage+Resize.h"
1035
1036 @interface AlbumArtLoader ()
1037@@ -117,7 +128,7 @@
1038
1039 - (NSString*)URLFromCoverArtID:(NSString*)artID
1040 {
1041- NSMutableSet *parameters = [NSMutableSet set];
1042+ NSMutableArray *parameters = [NSMutableArray array];
1043 [parameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"id", artID, nil]];
1044
1045 // Always get the largest we can handle
1046
1047=== modified file 'musicstreaming/utilities/operations/AlbumArtLoadingOperation.h'
1048--- musicstreaming/utilities/operations/AlbumArtLoadingOperation.h 2011-05-27 18:20:22 +0000
1049+++ musicstreaming/utilities/operations/AlbumArtLoadingOperation.h 2011-06-21 18:28:35 +0000
1050@@ -3,8 +3,19 @@
1051 // iSub
1052 //
1053 // Created by Aaron Brethorst on 5/4/11.
1054-// Copyright 2011 Canonical. All rights reserved.
1055+// Copyright 2011 Canonical Ltd.
1056+//
1057+// This program is free software: you can redistribute it and/or modify it
1058+// under the terms of the GNU Affero General Public License version 3,
1059+// as published by the Free Software Foundation.
1060+//
1061+// This program is distributed in the hope that it will be useful, but
1062+// WITHOUT ANY WARRANTY; without even the implied warranties of
1063+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1064+// PURPOSE. See the GNU Affero General Public License for more details.
1065 //
1066+// You should have received a copy of the GNU Affero General Public License
1067+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1068
1069 #import <UIKit/UIKit.h>
1070 #import "AbstractNetworkOperation.h"
1071
1072=== modified file 'musicstreaming/utilities/operations/AlbumArtLoadingOperation.m'
1073--- musicstreaming/utilities/operations/AlbumArtLoadingOperation.m 2011-06-07 09:20:03 +0000
1074+++ musicstreaming/utilities/operations/AlbumArtLoadingOperation.m 2011-06-21 18:28:35 +0000
1075@@ -3,8 +3,19 @@
1076 // iSub
1077 //
1078 // Created by Aaron Brethorst on 5/4/11.
1079-// Copyright 2011 Canonical. All rights reserved.
1080+// Copyright 2011 Canonical Ltd.
1081+//
1082+// This program is free software: you can redistribute it and/or modify it
1083+// under the terms of the GNU Affero General Public License version 3,
1084+// as published by the Free Software Foundation.
1085+//
1086+// This program is distributed in the hope that it will be useful, but
1087+// WITHOUT ANY WARRANTY; without even the implied warranties of
1088+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1089+// PURPOSE. See the GNU Affero General Public License for more details.
1090 //
1091+// You should have received a copy of the GNU Affero General Public License
1092+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1093
1094 // adapted from http://www.dribin.org/dave/blog/archives/2009/05/05/concurrent_operations/
1095
1096
1097=== modified file 'musicstreaming/utilities/operations/DownloadOperation.h'
1098--- musicstreaming/utilities/operations/DownloadOperation.h 2011-05-13 06:58:25 +0000
1099+++ musicstreaming/utilities/operations/DownloadOperation.h 2011-06-21 18:28:35 +0000
1100@@ -3,8 +3,19 @@
1101 // iSub
1102 //
1103 // Created by Aaron Brethorst on 5/12/11.
1104-// Copyright 2011 Canonical. All rights reserved.
1105+// Copyright 2011 Canonical Ltd.
1106+//
1107+// This program is free software: you can redistribute it and/or modify it
1108+// under the terms of the GNU Affero General Public License version 3,
1109+// as published by the Free Software Foundation.
1110+//
1111+// This program is distributed in the hope that it will be useful, but
1112+// WITHOUT ANY WARRANTY; without even the implied warranties of
1113+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1114+// PURPOSE. See the GNU Affero General Public License for more details.
1115 //
1116+// You should have received a copy of the GNU Affero General Public License
1117+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1118
1119 #import <UIKit/UIKit.h>
1120 #import "AbstractNetworkOperation.h"
1121
1122=== modified file 'musicstreaming/utilities/operations/DownloadOperation.m'
1123--- musicstreaming/utilities/operations/DownloadOperation.m 2011-05-13 06:58:25 +0000
1124+++ musicstreaming/utilities/operations/DownloadOperation.m 2011-06-21 18:28:35 +0000
1125@@ -3,8 +3,19 @@
1126 // iSub
1127 //
1128 // Created by Aaron Brethorst on 5/12/11.
1129-// Copyright 2011 Canonical. All rights reserved.
1130+// Copyright 2011 Canonical Ltd.
1131+//
1132+// This program is free software: you can redistribute it and/or modify it
1133+// under the terms of the GNU Affero General Public License version 3,
1134+// as published by the Free Software Foundation.
1135+//
1136+// This program is distributed in the hope that it will be useful, but
1137+// WITHOUT ANY WARRANTY; without even the implied warranties of
1138+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1139+// PURPOSE. See the GNU Affero General Public License for more details.
1140 //
1141+// You should have received a copy of the GNU Affero General Public License
1142+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1143
1144 #import "DownloadOperation.h"
1145
1146
1147=== modified file 'musicstreaming/utilities/operations/Downloader.h'
1148--- musicstreaming/utilities/operations/Downloader.h 2011-06-13 19:00:38 +0000
1149+++ musicstreaming/utilities/operations/Downloader.h 2011-06-21 18:28:35 +0000
1150@@ -3,8 +3,19 @@
1151 // iSub
1152 //
1153 // Created by Aaron Brethorst on 5/12/11.
1154-// Copyright 2011 Canonical. All rights reserved.
1155+// Copyright 2011 Canonical Ltd.
1156+//
1157+// This program is free software: you can redistribute it and/or modify it
1158+// under the terms of the GNU Affero General Public License version 3,
1159+// as published by the Free Software Foundation.
1160+//
1161+// This program is distributed in the hope that it will be useful, but
1162+// WITHOUT ANY WARRANTY; without even the implied warranties of
1163+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1164+// PURPOSE. See the GNU Affero General Public License for more details.
1165 //
1166+// You should have received a copy of the GNU Affero General Public License
1167+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1168
1169 #import <UIKit/UIKit.h>
1170 #import "DownloadOperation.h"
1171
1172=== modified file 'musicstreaming/utilities/operations/Downloader.m'
1173--- musicstreaming/utilities/operations/Downloader.m 2011-06-14 17:20:13 +0000
1174+++ musicstreaming/utilities/operations/Downloader.m 2011-06-21 18:28:35 +0000
1175@@ -3,8 +3,19 @@
1176 // iSub
1177 //
1178 // Created by Aaron Brethorst on 5/12/11.
1179-// Copyright 2011 Canonical. All rights reserved.
1180+// Copyright 2011 Canonical Ltd.
1181+//
1182+// This program is free software: you can redistribute it and/or modify it
1183+// under the terms of the GNU Affero General Public License version 3,
1184+// as published by the Free Software Foundation.
1185+//
1186+// This program is distributed in the hope that it will be useful, but
1187+// WITHOUT ANY WARRANTY; without even the implied warranties of
1188+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1189+// PURPOSE. See the GNU Affero General Public License for more details.
1190 //
1191+// You should have received a copy of the GNU Affero General Public License
1192+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1193
1194 #import "Downloader.h"
1195 #import "DownloadOperation.h"
1196
1197=== modified file 'musicstreaming/view_controllers/ArtistViewController.m'
1198--- musicstreaming/view_controllers/ArtistViewController.m 2011-06-16 19:12:54 +0000
1199+++ musicstreaming/view_controllers/ArtistViewController.m 2011-06-21 18:28:35 +0000
1200@@ -120,7 +120,6 @@
1201 - (void)finishLoadingData
1202 {
1203 [self.tableView reloadData];
1204- [self hideLoadingUI];
1205 [super finishLoadingData];
1206 }
1207
1208
1209=== modified file 'musicstreaming/view_controllers/PlaylistEditAlbumViewController.m'
1210--- musicstreaming/view_controllers/PlaylistEditAlbumViewController.m 2011-05-27 18:37:16 +0000
1211+++ musicstreaming/view_controllers/PlaylistEditAlbumViewController.m 2011-06-21 18:28:35 +0000
1212@@ -87,11 +87,11 @@
1213 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
1214
1215 if (cell.accessoryType == UITableViewCellAccessoryNone) {
1216- [self.originator.playlist addSongsObject:selection];
1217+ [self.originator.playlist addSong:selection];
1218 cell.accessoryType = UITableViewCellAccessoryCheckmark;
1219
1220 } else {
1221- [self.originator.playlist removeSongsObject:selection];
1222+ [self.originator.playlist removeSong:selection];
1223 cell.accessoryType = UITableViewCellAccessoryNone;
1224 }
1225
1226
1227=== modified file 'musicstreaming/view_controllers/PlaylistEditSongListViewController.m'
1228--- musicstreaming/view_controllers/PlaylistEditSongListViewController.m 2011-05-27 18:37:16 +0000
1229+++ musicstreaming/view_controllers/PlaylistEditSongListViewController.m 2011-06-21 18:28:35 +0000
1230@@ -19,6 +19,7 @@
1231
1232 #import "PlaylistEditSongListViewController.h"
1233 #import "PlaylistEditViewController.h"
1234+#import "PlaylistSongIndex.h"
1235 #import "Playlist.h"
1236 #import "Song.h"
1237
1238@@ -104,11 +105,12 @@
1239 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
1240
1241 if (cell.accessoryType == UITableViewCellAccessoryNone) {
1242- [self.originator.playlist addSongsObject:selection];
1243+ [self.originator.playlist addSong:selection];
1244 cell.accessoryType = UITableViewCellAccessoryCheckmark;
1245
1246 } else {
1247- [self.originator.playlist removeSongsObject:selection];
1248+
1249+ [self.originator.playlist removeSong:selection];
1250 cell.accessoryType = UITableViewCellAccessoryNone;
1251 }
1252
1253
1254=== modified file 'musicstreaming/view_controllers/PlaylistEditViewController.h'
1255--- musicstreaming/view_controllers/PlaylistEditViewController.h 2011-04-19 01:55:39 +0000
1256+++ musicstreaming/view_controllers/PlaylistEditViewController.h 2011-06-21 18:28:35 +0000
1257@@ -22,16 +22,14 @@
1258 @class Playlist;
1259 @class SubsonicTableViewController;
1260
1261-@interface PlaylistEditViewController : UIViewController <UITabBarControllerDelegate>
1262+@interface PlaylistEditViewController : UITabBarController
1263 {
1264 Playlist *playlist;
1265 SubsonicTableViewController *originator;
1266- UITabBarController *tabBarController;
1267 }
1268-+ (UINavigationController *)navigableViewControllerWithPlaylist:(Playlist *)playlist originator:(SubsonicTableViewController *)originator;
1269++ (PlaylistEditViewController *)playlistEditViewControllerWithPlaylist:(Playlist *)playlist originator:(SubsonicTableViewController *)originator;
1270 - (id)initWithPlaylist:(Playlist *)aPlaylist;
1271 - (void)finish:(id)sender;
1272 @property(nonatomic,retain) Playlist *playlist;
1273 @property(nonatomic,retain) SubsonicTableViewController *originator;
1274-@property(nonatomic,retain) IBOutlet UITabBarController *tabBarController;
1275 @end
1276
1277=== modified file 'musicstreaming/view_controllers/PlaylistEditViewController.m'
1278--- musicstreaming/view_controllers/PlaylistEditViewController.m 2011-05-27 18:37:16 +0000
1279+++ musicstreaming/view_controllers/PlaylistEditViewController.m 2011-06-21 18:28:35 +0000
1280@@ -27,51 +27,33 @@
1281 #import "Playlist.h"
1282 #import "Song.h"
1283 #import "SongListParser.h"
1284-#import "NSMutableSet+Extras.h"
1285+#import "NSMutableArray+Extras.h"
1286
1287 @implementation PlaylistEditViewController
1288-@synthesize playlist, originator, tabBarController;
1289+@synthesize playlist, originator;
1290
1291-+ (UINavigationController *)navigableViewControllerWithPlaylist:(Playlist *)playlist originator:(SubsonicTableViewController *)originator
1292++ (PlaylistEditViewController *)playlistEditViewControllerWithPlaylist:(Playlist *)playlist originator:(SubsonicTableViewController *)originator
1293 {
1294 PlaylistEditViewController *playlistEditViewController = [[[PlaylistEditViewController alloc] initWithPlaylist:playlist] autorelease];
1295 playlistEditViewController.originator = originator;
1296- UINavigationController *nav = [[[UINavigationController alloc] initWithRootViewController:playlistEditViewController] autorelease];
1297- nav.navigationBarHidden = YES;
1298- return nav;
1299+ return playlistEditViewController;
1300 }
1301
1302 - (id)initWithPlaylist:(Playlist *)aPlaylist
1303 {
1304- if ((self = [super initWithNibName:@"PlaylistEditViewController" bundle:nil]))
1305+ if ((self = [super initWithNibName:nil bundle:nil]))
1306 {
1307 self.playlist = aPlaylist;
1308 self.originator = nil;
1309+
1310+ // Hacky way to avoid the strange push-down of the tab bar buttons
1311+// self.view.frame = CGRectMake(0, 0, 320, 460);
1312+
1313+ [self setViewControllers:[NSArray arrayWithObjects:[PlaylistEditArtistListViewController navigableViewControllerWithOriginator:self], [PlaylistEditAlbumListViewController navigableViewControllerWithOriginator:self], [PlaylistEditSongListViewController navigableViewControllerWithOriginator:self], nil] animated:YES];
1314 }
1315 return self;
1316 }
1317
1318-- (void)viewDidLoad
1319-{
1320- [super viewDidLoad];
1321-
1322- // Hacky way to avoid the strange push-down of the tab bar buttons
1323- tabBarController.view.frame = CGRectMake(0, 0, 320, 460);
1324-
1325- [self.view addSubview:[tabBarController view]];
1326-
1327- [tabBarController setViewControllers:[NSArray arrayWithObjects:[PlaylistEditArtistListViewController navigableViewControllerWithOriginator:self], [PlaylistEditAlbumListViewController navigableViewControllerWithOriginator:self], [PlaylistEditSongListViewController navigableViewControllerWithOriginator:self], nil] animated:YES];
1328-
1329- tabBarController.delegate = self;
1330-}
1331-
1332-#pragma mark - UITabBarControllerDelegate
1333-
1334-- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
1335-{
1336- self.navigationItem.title = viewController.title;
1337-}
1338-
1339 #pragma mark - Memory management
1340
1341 - (void)dealloc
1342@@ -84,7 +66,7 @@
1343
1344 - (void)finish:(id)sender
1345 {
1346- NSMutableSet *extraParameters = [NSMutableSet set];
1347+ NSMutableArray *extraParameters = [NSMutableArray array];
1348 if (nil != self.playlist.playlistId)
1349 {
1350 [extraParameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"playlistId", self.playlist.playlistId, nil]];
1351
1352=== modified file 'musicstreaming/view_controllers/PlaylistListViewController.m'
1353--- musicstreaming/view_controllers/PlaylistListViewController.m 2011-06-16 19:12:54 +0000
1354+++ musicstreaming/view_controllers/PlaylistListViewController.m 2011-06-21 18:28:35 +0000
1355@@ -46,17 +46,17 @@
1356 {
1357 if ((self = [super initWithTitle:title]))
1358 {
1359-// UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,40)];
1360-// header.autoresizingMask = UIViewAutoresizingFlexibleWidth;
1361-//
1362-// UIButton *createButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
1363-// createButton.frame = CGRectMake(5, 5, 310, 30);
1364-// [createButton setTitle:NSLocalizedString(@"Create new playlist", @"") forState:UIControlStateNormal];
1365-// [createButton addTarget:self action:@selector(createNewPlaylist) forControlEvents:UIControlEventTouchUpInside];
1366-// [header addSubview:createButton];
1367-//
1368-// self.tableView.tableHeaderView = header;
1369-// [header release];
1370+ UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,40)];
1371+ header.autoresizingMask = UIViewAutoresizingFlexibleWidth;
1372+
1373+ UIButton *createButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
1374+ createButton.frame = CGRectMake(5, 5, 310, 30);
1375+ [createButton setTitle:NSLocalizedString(@"Create new playlist", @"") forState:UIControlStateNormal];
1376+ [createButton addTarget:self action:@selector(createNewPlaylist) forControlEvents:UIControlEventTouchUpInside];
1377+ [header addSubview:createButton];
1378+
1379+ self.tableView.tableHeaderView = header;
1380+ [header release];
1381 }
1382 return self;
1383 }
1384@@ -142,8 +142,8 @@
1385 {
1386 Playlist *playlist = [NSEntityDescription insertNewObjectForEntityForName:@"Playlist" inManagedObjectContext:PerThreadManagedObjectContext()];
1387 playlist.name = [(AlertPrompt *)alertPrompt enteredText];
1388- UINavigationController *playlistEditViewController = [PlaylistEditViewController navigableViewControllerWithPlaylist:playlist originator:self];
1389- playlistEditViewController.navigationBar.barStyle = UIBarStyleBlack;
1390+ SaveContext();
1391+ PlaylistEditViewController *playlistEditViewController = [PlaylistEditViewController playlistEditViewControllerWithPlaylist:playlist originator:self];
1392 [self.navigationController presentModalViewController:playlistEditViewController animated:YES];
1393 }
1394 else
1395
1396=== modified file 'musicstreaming/view_controllers/PlaylistViewController.m'
1397--- musicstreaming/view_controllers/PlaylistViewController.m 2011-06-16 19:12:54 +0000
1398+++ musicstreaming/view_controllers/PlaylistViewController.m 2011-06-21 18:28:35 +0000
1399@@ -22,7 +22,11 @@
1400 #import "Playlist.h"
1401 #import "PlaylistParser.h"
1402 #import "Song.h"
1403-#import "NSMutableSet+Extras.h"
1404+#import "NSMutableArray+Extras.h"
1405+
1406+@interface PlaylistViewController ()
1407+- (void)deleteLocalPlaylist;
1408+@end
1409
1410 @implementation PlaylistViewController
1411
1412@@ -80,9 +84,9 @@
1413 [self.songs removeAllObjects];
1414 if ([self.playlist isKindOfClass:[NSManagedObject class]])
1415 [PerThreadManagedObjectContext() refreshObject:self.playlist mergeChanges:YES]; //force the playlist to reload its set of songs from the persistent store.
1416- [self.songs addObjectsFromArray:[self.playlist.songs allObjects]];
1417+ [self.songs addObjectsFromArray:self.playlist.songs];
1418 // this should sort based on something else (like the index on the playlist or something)
1419- [self.songs sortUsingSelector:@selector(compare:)];
1420+// [self.songs sortUsingSelector:@selector(compare:)];
1421 }
1422
1423 [self.tableView reloadData];
1424@@ -93,13 +97,16 @@
1425 {
1426 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1427
1428- NSError *error = [self.playlist loadSongs];
1429-
1430- if (error)
1431+ if (self.playlist.playlistId) // Protect against CouchDB access being down, at least allow for local playlists.
1432 {
1433- [self performSelectorOnMainThread:@selector(failedLoadingData:) withObject:error waitUntilDone:NO];
1434+ NSError *error = [self.playlist loadSongs];
1435+
1436+ if (error)
1437+ {
1438+ [self performSelectorOnMainThread:@selector(failedLoadingData:) withObject:error waitUntilDone:NO];
1439+ }
1440 }
1441-
1442+
1443 [self performSelectorOnMainThread:@selector(loadLocalData) withObject:nil waitUntilDone:NO];
1444 [self performSelectorOnMainThread:@selector(finishLoadingData) withObject:nil waitUntilDone:NO];
1445 [pool release];
1446@@ -204,38 +211,46 @@
1447
1448 - (void)editPlaylist
1449 {
1450- return;
1451- // Need to figure out what to do here
1452- UINavigationController *playlistEditViewController = [PlaylistEditViewController navigableViewControllerWithPlaylist:self.playlist originator:self];
1453- playlistEditViewController.navigationBar.barStyle = UIBarStyleBlack;
1454+ PlaylistEditViewController *playlistEditViewController = [PlaylistEditViewController playlistEditViewControllerWithPlaylist:self.playlist originator:self];
1455 [self.navigationController presentModalViewController:playlistEditViewController animated:YES];
1456 }
1457
1458 - (void)clearPlaylist
1459 {
1460- return;
1461- // Need to figure out what to do here
1462- self.playlist.songs = [NSMutableArray array];
1463+ self.playlist.playlistSongIndexes = nil;
1464 self.songs = nil;
1465+ SaveContext();
1466 [self.tableView reloadData];
1467 }
1468
1469 - (void)deletePlaylist
1470 {
1471- // Need to figure out what to do here
1472- NSMutableSet *extraParameters = [NSMutableSet set];
1473- [extraParameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"id", self.playlist.playlistId, nil]];
1474- NSURL *url = [[Subsonic sharedSubsonic] getBaseURL:@"deletePlaylist.view" parameters:extraParameters];
1475- NSURLRequest *request = [[[NSURLRequest alloc] initWithURL:url] autorelease];
1476- NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
1477- [connection start];
1478+ if (self.playlist.playlistId)
1479+ {
1480+ NSMutableArray *extraParameters = [NSMutableArray array];
1481+ [extraParameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"id", self.playlist.playlistId, nil]];
1482+ NSURL *url = [[Subsonic sharedSubsonic] getBaseURL:@"deletePlaylist.view" parameters:extraParameters];
1483+ NSURLRequest *request = [[[NSURLRequest alloc] initWithURL:url] autorelease];
1484+ NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
1485+ [connection start];
1486+ }
1487+ else
1488+ {
1489+ [self deleteLocalPlaylist];
1490+ }
1491 }
1492
1493 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
1494 {
1495- [PerThreadManagedObjectContext() deleteObject:self.playlist];
1496- [self.playlistListViewController performSelector:@selector(reload:) withObject:nil afterDelay:0.25];
1497- [self.navigationController popViewControllerAnimated:YES];
1498+ [self deleteLocalPlaylist];
1499+}
1500+
1501+- (void)deleteLocalPlaylist
1502+{
1503+ [PerThreadManagedObjectContext() deleteObject:self.playlist];
1504+ SaveContext();
1505+ [self.playlistListViewController performSelector:@selector(reload:) withObject:nil afterDelay:0.25];
1506+ [self.navigationController popViewControllerAnimated:YES];
1507 }
1508
1509 - (void)resetTableData:(id)sender
1510
1511=== modified file 'musicstreaming/view_controllers/SongViewController.m'
1512--- musicstreaming/view_controllers/SongViewController.m 2011-06-13 17:22:43 +0000
1513+++ musicstreaming/view_controllers/SongViewController.m 2011-06-21 18:28:35 +0000
1514@@ -38,7 +38,6 @@
1515 #import <MediaPlayer/MediaPlayer.h>
1516 #import <CFNetwork/CFNetwork.h>
1517 #import "NSNumber+Extras.h"
1518-#import "NSMutableSet+Extras.h"
1519
1520 @interface SongViewController (Private)
1521 //KVO-driven stuff
1522
1523=== modified file 'musicstreaming/view_controllers/SubsonicTableViewController.h'
1524--- musicstreaming/view_controllers/SubsonicTableViewController.h 2011-06-16 19:12:54 +0000
1525+++ musicstreaming/view_controllers/SubsonicTableViewController.h 2011-06-21 18:28:35 +0000
1526@@ -21,13 +21,11 @@
1527 #import "PullRefreshTableViewController.h"
1528 #import "Subsonic.h"
1529 #import "Song.h"
1530-#import "MiniHudView.h"
1531
1532 @class Album;
1533
1534 @interface SubsonicTableViewController : PullRefreshTableViewController <UIAlertViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate>
1535 {
1536- MiniHudView *hudView;
1537 BOOL showProgressHUD;
1538 NSTimer *respondToRemoteTimer;
1539 NSMutableArray *tableData;
1540
1541=== modified file 'musicstreaming/view_controllers/SubsonicTableViewController.m'
1542--- musicstreaming/view_controllers/SubsonicTableViewController.m 2011-06-16 19:14:45 +0000
1543+++ musicstreaming/view_controllers/SubsonicTableViewController.m 2011-06-21 18:28:35 +0000
1544@@ -22,7 +22,6 @@
1545 #import "SongViewController.h"
1546 #import "Subsonic.h"
1547 #import "Album.h"
1548-#import "NSMutableSet+Extras.h"
1549 #import "Reachability.h"
1550 #import "UONetworkStatusCoordinator.h"
1551
1552@@ -65,7 +64,7 @@
1553 {
1554 [super viewDidLoad];
1555
1556- showProgressHUD = YES;
1557+ showProgressHUD = YES;
1558 respondToRemoteTimer = NULL;
1559
1560 if (0 == [self.tableData count])
1561@@ -304,6 +303,7 @@
1562 {
1563 [self hideLoadingUI];
1564 NSLog(@"Error loading data: %@", error);
1565+ // TODO: Get better error messages communicated to the user.
1566 // [self showError:NSLocalizedString(@"Unable to load your music. Please check your Internet connection or account credentials and try again.",@"")];
1567 }
1568
1569@@ -377,18 +377,6 @@
1570 [self showMessage:errorMessage withTitle:NSLocalizedString(@"Error",@"")];
1571 }
1572
1573-#pragma mark - MiniHudView
1574-
1575-- (MiniHudView*)hudView
1576-{
1577- if (nil == hudView)
1578- {
1579- hudView = [[MiniHudView alloc] initWithFrame:CGRectMake(270, 386, 30, 30)];
1580- [[UIApplication sharedApplication].keyWindow addSubview:self.hudView];
1581- }
1582- return hudView;
1583-}
1584-
1585 - (void)showLoadingUI
1586 {
1587 if (showProgressHUD)
1588@@ -406,11 +394,7 @@
1589
1590 - (void)hideLoadingUI
1591 {
1592- if (showProgressHUD)
1593- {
1594- [self.hudView hide:YES];
1595- }
1596- else
1597+ if (!showProgressHUD)
1598 {
1599 [self stopLoading];
1600 showProgressHUD = YES;
1601@@ -434,10 +418,8 @@
1602 - (void)dealloc
1603 {
1604 [[NSNotificationCenter defaultCenter] removeObserver:self];
1605- [hudView hide:NO];
1606 RELEASE_SAFELY(parserDelegate);
1607 RELEASE_SAFELY(viewName);
1608- RELEASE_SAFELY(hudView);
1609 RELEASE_SAFELY(tableData);
1610 RELEASE_SAFELY(searchResults);
1611
1612
1613=== modified file 'musicstreaming/view_controllers/SubsonicViewController.m'
1614--- musicstreaming/view_controllers/SubsonicViewController.m 2011-06-16 15:26:22 +0000
1615+++ musicstreaming/view_controllers/SubsonicViewController.m 2011-06-21 18:28:35 +0000
1616@@ -72,19 +72,16 @@
1617 case UIEventSubtypeRemoteControlPause:
1618 case UIEventSubtypeRemoteControlTogglePlayPause:
1619 {
1620- NSLog(@"Got a remote command to play/pause");
1621 [[StreamingPlayer sharedStreamingPlayer] playPauseSong];
1622 break;
1623 }
1624 case UIEventSubtypeRemoteControlNextTrack:
1625 {
1626- NSLog(@"Got a remote command to skip to the next track");
1627 [[StreamingPlayer sharedStreamingPlayer] jumpAhead:self.jumpBy];
1628 break;
1629 }
1630 case UIEventSubtypeRemoteControlPreviousTrack:
1631 {
1632- NSLog(@"Got a remote command to go to previous track");
1633 [[StreamingPlayer sharedStreamingPlayer] prevSong];
1634 break;
1635 }
1636
1637=== removed file 'musicstreaming/xibs/PlaylistEditViewController.xib'
1638--- musicstreaming/xibs/PlaylistEditViewController.xib 2011-05-18 14:10:38 +0000
1639+++ musicstreaming/xibs/PlaylistEditViewController.xib 1970-01-01 00:00:00 +0000
1640@@ -1,314 +0,0 @@
1641-<?xml version="1.0" encoding="UTF-8"?>
1642-<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
1643- <data>
1644- <int key="IBDocument.SystemTarget">1056</int>
1645- <string key="IBDocument.SystemVersion">10J869</string>
1646- <string key="IBDocument.InterfaceBuilderVersion">1306</string>
1647- <string key="IBDocument.AppKitVersion">1038.35</string>
1648- <string key="IBDocument.HIToolboxVersion">461.00</string>
1649- <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
1650- <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
1651- <string key="NS.object.0">301</string>
1652- </object>
1653- <object class="NSArray" key="IBDocument.IntegratedClassDependencies">
1654- <bool key="EncodedWithXMLCoder">YES</bool>
1655- <string>IBUITabBar</string>
1656- <string>IBUITabBarController</string>
1657- <string>IBUIViewController</string>
1658- <string>IBUIView</string>
1659- <string>IBUITabBarItem</string>
1660- <string>IBProxyObject</string>
1661- </object>
1662- <object class="NSArray" key="IBDocument.PluginDependencies">
1663- <bool key="EncodedWithXMLCoder">YES</bool>
1664- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
1665- </object>
1666- <object class="NSMutableDictionary" key="IBDocument.Metadata">
1667- <bool key="EncodedWithXMLCoder">YES</bool>
1668- <object class="NSArray" key="dict.sortedKeys" id="0">
1669- <bool key="EncodedWithXMLCoder">YES</bool>
1670- </object>
1671- <reference key="dict.values" ref="0"/>
1672- </object>
1673- <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
1674- <bool key="EncodedWithXMLCoder">YES</bool>
1675- <object class="IBProxyObject" id="372490531">
1676- <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
1677- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
1678- </object>
1679- <object class="IBProxyObject" id="975951072">
1680- <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
1681- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
1682- </object>
1683- <object class="IBUIView" id="191373211">
1684- <reference key="NSNextResponder"/>
1685- <int key="NSvFlags">274</int>
1686- <string key="NSFrame">{{0, 20}, {320, 460}}</string>
1687- <reference key="NSSuperview"/>
1688- <reference key="NSNextKeyView"/>
1689- <object class="NSColor" key="IBUIBackgroundColor">
1690- <int key="NSColorSpace">3</int>
1691- <bytes key="NSWhite">MQA</bytes>
1692- <object class="NSColorSpace" key="NSCustomColorSpace">
1693- <int key="NSID">2</int>
1694- </object>
1695- </object>
1696- <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
1697- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
1698- </object>
1699- <object class="IBUITabBarController" id="1031713869">
1700- <object class="IBUISimulatedTabBarMetrics" key="IBUISimulatedBottomBarMetrics"/>
1701- <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
1702- <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
1703- <int key="IBUIInterfaceOrientation">1</int>
1704- <int key="interfaceOrientation">1</int>
1705- </object>
1706- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
1707- <bool key="IBUIHorizontal">NO</bool>
1708- <object class="IBUIViewController" key="IBUISelectedViewController" id="232609108">
1709- <object class="IBUITabBarItem" key="IBUITabBarItem" id="647383633">
1710- <string key="IBUITitle">Songs</string>
1711- <object class="NSCustomResource" key="IBUIImage">
1712- <string key="NSClassName">NSImage</string>
1713- <string key="NSResourceName">songs.png</string>
1714- </object>
1715- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
1716- </object>
1717- <reference key="IBUIParentViewController" ref="1031713869"/>
1718- <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
1719- <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
1720- <int key="IBUIInterfaceOrientation">1</int>
1721- <int key="interfaceOrientation">1</int>
1722- </object>
1723- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
1724- <bool key="IBUIHorizontal">NO</bool>
1725- </object>
1726- <object class="NSMutableArray" key="IBUIViewControllers">
1727- <bool key="EncodedWithXMLCoder">YES</bool>
1728- <object class="IBUIViewController" id="264906486">
1729- <object class="IBUITabBarItem" key="IBUITabBarItem" id="798442073">
1730- <string key="IBUITitle">Artists</string>
1731- <object class="NSCustomResource" key="IBUIImage">
1732- <string key="NSClassName">NSImage</string>
1733- <string key="NSResourceName">artists.png</string>
1734- </object>
1735- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
1736- </object>
1737- <reference key="IBUIParentViewController" ref="1031713869"/>
1738- <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
1739- <int key="IBUIInterfaceOrientation">1</int>
1740- <int key="interfaceOrientation">1</int>
1741- </object>
1742- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
1743- <bool key="IBUIHorizontal">NO</bool>
1744- </object>
1745- <object class="IBUIViewController" id="135598923">
1746- <object class="IBUITabBarItem" key="IBUITabBarItem" id="738429249">
1747- <string key="IBUITitle">Albums</string>
1748- <object class="NSCustomResource" key="IBUIImage">
1749- <string key="NSClassName">NSImage</string>
1750- <string key="NSResourceName">albums.png</string>
1751- </object>
1752- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
1753- </object>
1754- <reference key="IBUIParentViewController" ref="1031713869"/>
1755- <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
1756- <int key="IBUIInterfaceOrientation">1</int>
1757- <int key="interfaceOrientation">1</int>
1758- </object>
1759- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
1760- <bool key="IBUIHorizontal">NO</bool>
1761- </object>
1762- <reference ref="232609108"/>
1763- </object>
1764- <object class="IBUITabBar" key="IBUITabBar" id="259355173">
1765- <reference key="NSNextResponder"/>
1766- <int key="NSvFlags">266</int>
1767- <string key="NSFrame">{{0, 431}, {320, 49}}</string>
1768- <reference key="NSSuperview"/>
1769- <reference key="NSNextKeyView"/>
1770- <object class="NSColor" key="IBUIBackgroundColor">
1771- <int key="NSColorSpace">3</int>
1772- <bytes key="NSWhite">MCAwAA</bytes>
1773- </object>
1774- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
1775- </object>
1776- </object>
1777- </object>
1778- <object class="IBObjectContainer" key="IBDocument.Objects">
1779- <object class="NSMutableArray" key="connectionRecords">
1780- <bool key="EncodedWithXMLCoder">YES</bool>
1781- <object class="IBConnectionRecord">
1782- <object class="IBCocoaTouchOutletConnection" key="connection">
1783- <string key="label">view</string>
1784- <reference key="source" ref="372490531"/>
1785- <reference key="destination" ref="191373211"/>
1786- </object>
1787- <int key="connectionID">3</int>
1788- </object>
1789- <object class="IBConnectionRecord">
1790- <object class="IBCocoaTouchOutletConnection" key="connection">
1791- <string key="label">tabBarController</string>
1792- <reference key="source" ref="372490531"/>
1793- <reference key="destination" ref="1031713869"/>
1794- </object>
1795- <int key="connectionID">12</int>
1796- </object>
1797- </object>
1798- <object class="IBMutableOrderedSet" key="objectRecords">
1799- <object class="NSArray" key="orderedObjects">
1800- <bool key="EncodedWithXMLCoder">YES</bool>
1801- <object class="IBObjectRecord">
1802- <int key="objectID">0</int>
1803- <reference key="object" ref="0"/>
1804- <reference key="children" ref="1000"/>
1805- <nil key="parent"/>
1806- </object>
1807- <object class="IBObjectRecord">
1808- <int key="objectID">1</int>
1809- <reference key="object" ref="191373211"/>
1810- <reference key="parent" ref="0"/>
1811- </object>
1812- <object class="IBObjectRecord">
1813- <int key="objectID">-1</int>
1814- <reference key="object" ref="372490531"/>
1815- <reference key="parent" ref="0"/>
1816- <string key="objectName">File's Owner</string>
1817- </object>
1818- <object class="IBObjectRecord">
1819- <int key="objectID">-2</int>
1820- <reference key="object" ref="975951072"/>
1821- <reference key="parent" ref="0"/>
1822- </object>
1823- <object class="IBObjectRecord">
1824- <int key="objectID">4</int>
1825- <reference key="object" ref="1031713869"/>
1826- <object class="NSMutableArray" key="children">
1827- <bool key="EncodedWithXMLCoder">YES</bool>
1828- <reference ref="259355173"/>
1829- <reference ref="264906486"/>
1830- <reference ref="135598923"/>
1831- <reference ref="232609108"/>
1832- </object>
1833- <reference key="parent" ref="0"/>
1834- <string key="objectName">Tab Bar Controller</string>
1835- </object>
1836- <object class="IBObjectRecord">
1837- <int key="objectID">5</int>
1838- <reference key="object" ref="259355173"/>
1839- <reference key="parent" ref="1031713869"/>
1840- </object>
1841- <object class="IBObjectRecord">
1842- <int key="objectID">6</int>
1843- <reference key="object" ref="264906486"/>
1844- <object class="NSMutableArray" key="children">
1845- <bool key="EncodedWithXMLCoder">YES</bool>
1846- <reference ref="798442073"/>
1847- </object>
1848- <reference key="parent" ref="1031713869"/>
1849- </object>
1850- <object class="IBObjectRecord">
1851- <int key="objectID">7</int>
1852- <reference key="object" ref="135598923"/>
1853- <object class="NSMutableArray" key="children">
1854- <bool key="EncodedWithXMLCoder">YES</bool>
1855- <reference ref="738429249"/>
1856- </object>
1857- <reference key="parent" ref="1031713869"/>
1858- </object>
1859- <object class="IBObjectRecord">
1860- <int key="objectID">8</int>
1861- <reference key="object" ref="738429249"/>
1862- <reference key="parent" ref="135598923"/>
1863- </object>
1864- <object class="IBObjectRecord">
1865- <int key="objectID">9</int>
1866- <reference key="object" ref="798442073"/>
1867- <reference key="parent" ref="264906486"/>
1868- </object>
1869- <object class="IBObjectRecord">
1870- <int key="objectID">10</int>
1871- <reference key="object" ref="232609108"/>
1872- <object class="NSMutableArray" key="children">
1873- <bool key="EncodedWithXMLCoder">YES</bool>
1874- <reference ref="647383633"/>
1875- </object>
1876- <reference key="parent" ref="1031713869"/>
1877- </object>
1878- <object class="IBObjectRecord">
1879- <int key="objectID">11</int>
1880- <reference key="object" ref="647383633"/>
1881- <reference key="parent" ref="232609108"/>
1882- </object>
1883- </object>
1884- </object>
1885- <object class="NSMutableDictionary" key="flattenedProperties">
1886- <bool key="EncodedWithXMLCoder">YES</bool>
1887- <object class="NSArray" key="dict.sortedKeys">
1888- <bool key="EncodedWithXMLCoder">YES</bool>
1889- <string>-1.CustomClassName</string>
1890- <string>-2.CustomClassName</string>
1891- <string>1.IBEditorWindowLastContentRect</string>
1892- <string>1.IBPluginDependency</string>
1893- <string>10.IBPluginDependency</string>
1894- <string>11.IBPluginDependency</string>
1895- <string>4.IBPluginDependency</string>
1896- <string>5.IBPluginDependency</string>
1897- <string>6.IBPluginDependency</string>
1898- <string>7.IBPluginDependency</string>
1899- </object>
1900- <object class="NSMutableArray" key="dict.values">
1901- <bool key="EncodedWithXMLCoder">YES</bool>
1902- <string>PlaylistEditViewController</string>
1903- <string>UIResponder</string>
1904- <string>{{354, 412}, {320, 480}}</string>
1905- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
1906- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
1907- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
1908- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
1909- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
1910- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
1911- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
1912- </object>
1913- </object>
1914- <object class="NSMutableDictionary" key="unlocalizedProperties">
1915- <bool key="EncodedWithXMLCoder">YES</bool>
1916- <reference key="dict.sortedKeys" ref="0"/>
1917- <reference key="dict.values" ref="0"/>
1918- </object>
1919- <nil key="activeLocalization"/>
1920- <object class="NSMutableDictionary" key="localizations">
1921- <bool key="EncodedWithXMLCoder">YES</bool>
1922- <reference key="dict.sortedKeys" ref="0"/>
1923- <reference key="dict.values" ref="0"/>
1924- </object>
1925- <nil key="sourceID"/>
1926- <int key="maxID">16</int>
1927- </object>
1928- <object class="IBClassDescriber" key="IBDocument.Classes"/>
1929- <int key="IBDocument.localizationMode">0</int>
1930- <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
1931- <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
1932- <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
1933- <integer value="3100" key="NS.object.0"/>
1934- </object>
1935- <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
1936- <int key="IBDocument.defaultPropertyAccessControl">3</int>
1937- <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
1938- <bool key="EncodedWithXMLCoder">YES</bool>
1939- <object class="NSArray" key="dict.sortedKeys">
1940- <bool key="EncodedWithXMLCoder">YES</bool>
1941- <string>albums.png</string>
1942- <string>artists.png</string>
1943- <string>songs.png</string>
1944- </object>
1945- <object class="NSMutableArray" key="dict.values">
1946- <bool key="EncodedWithXMLCoder">YES</bool>
1947- <string>{30, 30}</string>
1948- <string>{30, 30}</string>
1949- <string>{30, 30}</string>
1950- </object>
1951- </object>
1952- <string key="IBCocoaTouchPluginVersion">301</string>
1953- </data>
1954-</archive>

Subscribers

People subscribed via source and target branches

to all changes: