Merge lp:~urbanape/ubuntuone-ios-client/downloader into lp:ubuntuone-ios-client
- downloader
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 192 |
Proposed branch: | lp:~urbanape/ubuntuone-ios-client/downloader |
Merge into: | lp:ubuntuone-ios-client |
Diff against target: |
7121 lines (+2521/-2219) 88 files modified
musicstreaming/Other Sources/iSubAppDelegate.h (+2/-2) musicstreaming/Other Sources/iSubAppDelegate.m (+1/-6) musicstreaming/about/about.html (+178/-115) musicstreaming/categories/NSString+Extras.h (+26/-0) musicstreaming/categories/NSString+Extras.m (+46/-0) musicstreaming/categories/UIActionSheet+Blocks.h (+16/-0) musicstreaming/categories/UIActionSheet+Blocks.m (+71/-0) musicstreaming/categories/UIAlertView+Blocks.h (+16/-0) musicstreaming/categories/UIAlertView+Blocks.m (+61/-0) musicstreaming/controls/AlbumUITableViewCell.h (+2/-4) musicstreaming/controls/AlbumUITableViewCell.m (+1/-2) musicstreaming/controls/AsynchronousImageView.h (+0/-23) musicstreaming/controls/AsynchronousImageView.m (+0/-78) musicstreaming/controls/AsynchronousImageViewCached.h (+0/-26) musicstreaming/controls/AsynchronousImageViewCached.m (+0/-120) musicstreaming/controls/MBProgressHUD.h (+0/-273) musicstreaming/controls/MBProgressHUD.m (+0/-529) musicstreaming/controls/RIButtonItem.h (+23/-0) musicstreaming/controls/RIButtonItem.m (+28/-0) musicstreaming/controls/SongUITableViewCell.h (+4/-0) musicstreaming/controls/SongUITableViewCell.m (+20/-8) musicstreaming/iSub-Info.plist (+9/-1) musicstreaming/iSub.xcodeproj/project.pbxproj (+162/-58) musicstreaming/iSub_Prefix.pch (+1/-1) musicstreaming/models/Album.h (+3/-1) musicstreaming/models/Album.m (+34/-40) musicstreaming/models/Artist.h (+3/-1) musicstreaming/models/Artist.m (+35/-17) musicstreaming/models/MOC.m (+1/-6) musicstreaming/models/Playlist.h (+17/-17) musicstreaming/models/Playlist.m (+64/-38) musicstreaming/models/Song.h (+14/-3) musicstreaming/models/Song.m (+11/-33) musicstreaming/utilities/AlbumListParser.m (+1/-27) musicstreaming/utilities/AlbumParser.m (+7/-11) musicstreaming/utilities/ArtistListParser.h (+0/-10) musicstreaming/utilities/ArtistListParser.m (+4/-56) musicstreaming/utilities/ArtistParser.m (+4/-7) musicstreaming/utilities/AudioStreamer.h (+6/-1) musicstreaming/utilities/AudioStreamer.m (+97/-62) musicstreaming/utilities/DataCache.h (+0/-29) musicstreaming/utilities/DataCache.m (+0/-56) musicstreaming/utilities/Globals.h (+21/-0) musicstreaming/utilities/Globals.m (+51/-0) musicstreaming/utilities/PlaylistListParser.h (+0/-2) musicstreaming/utilities/PlaylistListParser.m (+9/-27) musicstreaming/utilities/PlaylistParser.h (+7/-8) musicstreaming/utilities/PlaylistParser.m (+52/-24) musicstreaming/utilities/StreamingPlayer.m (+11/-1) musicstreaming/utilities/Subsonic.m (+5/-1) musicstreaming/utilities/operations/AbstractNetworkOperation.h (+35/-0) musicstreaming/utilities/operations/AbstractNetworkOperation.m (+116/-0) musicstreaming/utilities/operations/AlbumArtLoader.h (+10/-7) musicstreaming/utilities/operations/AlbumArtLoader.m (+61/-12) musicstreaming/utilities/operations/AlbumArtLoadingOperation.h (+13/-27) musicstreaming/utilities/operations/AlbumArtLoadingOperation.m (+24/-87) musicstreaming/utilities/operations/DownloadOperation.h (+32/-0) musicstreaming/utilities/operations/DownloadOperation.m (+79/-0) musicstreaming/utilities/operations/Downloader.h (+29/-0) musicstreaming/utilities/operations/Downloader.m (+188/-0) musicstreaming/view_controllers/AlbumListViewController.h (+3/-3) musicstreaming/view_controllers/AlbumListViewController.m (+16/-28) musicstreaming/view_controllers/AlbumViewController.h (+12/-5) musicstreaming/view_controllers/AlbumViewController.m (+114/-25) musicstreaming/view_controllers/ArtistListViewController.m (+3/-2) musicstreaming/view_controllers/ArtistViewController.h (+3/-1) musicstreaming/view_controllers/ArtistViewController.m (+68/-22) musicstreaming/view_controllers/PlaylistEditAlbumListViewController.m (+1/-0) musicstreaming/view_controllers/PlaylistEditAlbumViewController.m (+3/-3) musicstreaming/view_controllers/PlaylistEditArtistListViewController.m (+1/-0) musicstreaming/view_controllers/PlaylistEditArtistViewController.m (+1/-0) musicstreaming/view_controllers/PlaylistEditSongListViewController.m (+4/-3) musicstreaming/view_controllers/PlaylistEditViewController.m (+2/-3) musicstreaming/view_controllers/PlaylistListViewController.m (+36/-42) musicstreaming/view_controllers/PlaylistViewController.h (+2/-0) musicstreaming/view_controllers/PlaylistViewController.m (+50/-55) musicstreaming/view_controllers/SettingsViewController.h (+8/-2) musicstreaming/view_controllers/SettingsViewController.m (+217/-28) musicstreaming/view_controllers/SongListViewController.m (+3/-2) musicstreaming/view_controllers/SongViewController.h (+8/-6) musicstreaming/view_controllers/SongViewController.m (+44/-14) musicstreaming/view_controllers/SubsonicIndexedTableViewController.m (+8/-0) musicstreaming/view_controllers/SubsonicTableViewController.h (+7/-1) musicstreaming/view_controllers/SubsonicTableViewController.m (+30/-17) musicstreaming/view_controllers/SubsonicViewController.m (+13/-8) musicstreaming/xibs/MainWindow.xib (+73/-32) musicstreaming/xibs/PlaylistEditViewController.xib (+58/-31) musicstreaming/xibs/SongViewController.xib (+22/-29) |
To merge this branch: | bzr merge lp:~urbanape/ubuntuone-ios-client/downloader |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu One iOS Client Team | Pending | ||
Review via email: mp+63031@code.launchpad.net |
Commit message
Description of the change
Ridiculously large branch that does a lot:
- Default album art behavior internalized to the AlbumArtLoader
- AlbumArtLoader uses a persistent filesystem cache for album art
- Music cache buttons on Album view allow for downloading tracks for off-line listening
- Cache controls in Settings screen allow for clearing music/album art cache
Known issues (to be resolved in subsequent branches):
- Playlists don't seem to be getting wired up correctly, though they no longer crash the app
- Playlist editing isn't wired up properly at all
- Playlist song ordering isn't wired up properly at all
- 236. By Zachery Bir
-
2.0 (6)
- Fix background streaming progress (or at least make it less broken - Matt Griffin and Aaron Brethorst)
- Album art properly shows on playback screen when first playing (Matt Griffin)
- Cache report values properly update when downloading/deleting tracks
- Tapping button for cached songs deletes cached file
- Tapping button while downloading is a no-op
- Tapping a playing track while in album view goes to Now Playing view instead of restarting the track
- Settings now shows number of Artists, Albums, Songs, and Playlists
- Bumped up the buffering to hopefully hit the sweet spot of reliability/responsiveness.
- Cleaned up a bunch of small bits (Jason Foreman) - 237. By Zachery Bir
-
- little bit of debugging
- turn off idle timer when downloading, turn it back on when download queue is empty
- delete playlists locally as well as remotely
- ditch the annoying error message
Preview Diff
1 | === modified file 'musicstreaming/Default.png' |
2 | Binary files musicstreaming/Default.png 2011-05-02 02:22:54 +0000 and musicstreaming/Default.png 2011-06-13 16:58:33 +0000 differ |
3 | === modified file 'musicstreaming/Default@2x.png' |
4 | Binary files musicstreaming/Default@2x.png 2011-05-02 02:22:54 +0000 and musicstreaming/Default@2x.png 2011-06-13 16:58:33 +0000 differ |
5 | === modified file 'musicstreaming/Other Sources/iSubAppDelegate.h' |
6 | --- musicstreaming/Other Sources/iSubAppDelegate.h 2011-03-28 18:18:01 +0000 |
7 | +++ musicstreaming/Other Sources/iSubAppDelegate.h 2011-06-13 16:58:33 +0000 |
8 | @@ -34,10 +34,10 @@ |
9 | |
10 | UIWindow *window; |
11 | UITabBarController *tabBarController; |
12 | - NSMutableDictionary *coverArtCache; |
13 | } |
14 | @property (nonatomic, retain) IBOutlet UIWindow *window; |
15 | @property (nonatomic, retain) IBOutlet UITabBarController *tabBarController; |
16 | -@property (nonatomic, retain) NSMutableDictionary *coverArtCache; |
17 | + |
18 | +extern NSString * const NOTIF_reloadAccountCredentials; |
19 | @end |
20 | |
21 | |
22 | === modified file 'musicstreaming/Other Sources/iSubAppDelegate.m' |
23 | --- musicstreaming/Other Sources/iSubAppDelegate.m 2011-05-05 08:09:46 +0000 |
24 | +++ musicstreaming/Other Sources/iSubAppDelegate.m 2011-06-13 16:58:33 +0000 |
25 | @@ -49,7 +49,6 @@ |
26 | |
27 | @synthesize window; |
28 | @synthesize tabBarController; |
29 | -@synthesize coverArtCache; |
30 | |
31 | #pragma mark - |
32 | #pragma mark Application lifecycle |
33 | @@ -66,8 +65,6 @@ |
34 | } |
35 | } |
36 | |
37 | - coverArtCache = [[NSMutableDictionary alloc] init]; |
38 | - |
39 | [self configureUsernamePassword]; |
40 | |
41 | [self recoverState]; |
42 | @@ -87,7 +84,7 @@ |
43 | if ([[url scheme] isEqual:@"x-ubuntuone-music"]) |
44 | { |
45 | [self parseQueryCredentials:url]; |
46 | - [[NSNotificationCenter defaultCenter] postNotificationName:@"ReloadAccountCredentials" object:nil]; |
47 | + [[NSNotificationCenter defaultCenter] postNotificationName:NOTIF_reloadAccountCredentials object:nil]; |
48 | |
49 | return YES; |
50 | } |
51 | @@ -164,8 +161,6 @@ |
52 | |
53 | - (void)dealloc |
54 | { |
55 | - [coverArtCache release]; |
56 | - |
57 | [tabBarController release]; |
58 | |
59 | [window release]; |
60 | |
61 | === modified file 'musicstreaming/about/about.html' |
62 | --- musicstreaming/about/about.html 2010-09-30 21:09:34 +0000 |
63 | +++ musicstreaming/about/about.html 2011-06-13 16:58:33 +0000 |
64 | @@ -1,119 +1,182 @@ |
65 | <!DOCTYPE HTML> |
66 | |
67 | <html> |
68 | - <head> |
69 | - <meta name="viewport" content="width=294, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> |
70 | - <link rel="stylesheet" href="about.css" type="text/css" media="screen" title="no title" charset="utf-8"> |
71 | - </head> |
72 | - <body> |
73 | - <div id="container"> |
74 | - |
75 | - <div id="logo"> |
76 | - <img src="music_512.png"> |
77 | - </div> |
78 | - |
79 | - <h1>Ubuntu One Music</h1> |
80 | - |
81 | - <p class="center">Version 1.0</p> |
82 | - <p class="center">©2010 Canonical Limited. All rights reserved.</p> |
83 | - <p class="center">Support: <a href="https://one.ubuntu.com/support/">one.ubuntu.com/support</a> |
84 | - |
85 | - <div id="acknowledgements"> |
86 | - <h2>Acknowledgements</h2> |
87 | - <p> |
88 | - Special thanks to Ben Baron, developer of iSub (<a href="http://einsteinx2.com/projects/isub/">http://einsteinx2.com/projects/isub/</a>) |
89 | - </p> |
90 | - |
91 | - <div id="source"> |
92 | - <div class="item"> |
93 | - <p> |
94 | - iSub Music Streamer<br> |
95 | - Copyright 2010 Ben Baron. All rights reserved. |
96 | - </p> |
97 | - <p> |
98 | - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
99 | - </p> |
100 | - <p> |
101 | - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.<br> |
102 | - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.<br> |
103 | - * Neither the my name nor the names of my contributors may be used to endorse or promote products derived from this software without specific prior written permission. |
104 | - </p> |
105 | - <p> |
106 | - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
107 | - </p> |
108 | - </div> |
109 | - |
110 | - <div class="item"> |
111 | - <p> |
112 | - Icons by Joseph Wain / glyphish.com |
113 | - </p> |
114 | - </div> |
115 | - |
116 | - <div class="item"> |
117 | - <p> |
118 | - SynthesizeSingleton |
119 | - </p> |
120 | - <p> |
121 | - Created by Matt Gallagher on 20/10/08.<br> |
122 | - Copyright 2009 Matt Gallagher. All rights reserved. |
123 | - </p> |
124 | - <p> |
125 | - Permission is given to use this source code file without charge in any project, commercial or otherwise, entirely at your risk, with the condition that any redistribution (in part or whole) of source code must retain this copyright and permission notice. Attribution in compiled projects is appreciated but not required.</p> |
126 | - </div> |
127 | - |
128 | - <div class="item"> |
129 | - <p> |
130 | - UIDevice+Hardware<br> |
131 | - Erica Sadun, http://ericasadun.com<br> |
132 | - iPhone Developer's Cookbook, 3.0 Edition<br> |
133 | - Thanks to Emanuele Vulcano, Kevin Ballard/Eridius, Ryandjohnson, Matt Brown, etc. |
134 | - </p> |
135 | - </div> |
136 | - <div class="item"> |
137 | - <p> |
138 | - MBProgressHUD<br> |
139 | - This code is distributed under the terms and conditions of the MIT license. |
140 | - </p> |
141 | - |
142 | - <p> |
143 | - Copyright (c) 2009 Matej Bukovinski |
144 | - </p> |
145 | - |
146 | - <p> |
147 | - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: |
148 | - </p> |
149 | - |
150 | - <p> |
151 | - The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. |
152 | - </p> |
153 | - |
154 | - <p> |
155 | - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
156 | - </p> |
157 | - </div> |
158 | - |
159 | - <div class="item"> |
160 | - <p> |
161 | - AsynchronousImageView<br> |
162 | - Copyright 2009 Slava Bushtruk. All rights reserved. |
163 | - </p> |
164 | - </div> |
165 | - |
166 | - <div class="item"> |
167 | - <p> |
168 | - Copyright (c) 2010 Leah Culver |
169 | - </p> |
170 | - <p> |
171 | - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: |
172 | - </p> |
173 | - <p> |
174 | - The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. |
175 | - </p> |
176 | - <p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
177 | - </p> |
178 | - </div> |
179 | - </div> <!-- #source --> |
180 | - </div> |
181 | + <head> |
182 | + <meta name="viewport" content="width=294, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> |
183 | + <link rel="stylesheet" href="about.css" type="text/css" media="screen" title="no title" charset="utf-8"> |
184 | + </head> |
185 | + <body> |
186 | + <div id="container"> |
187 | + |
188 | + <div id="logo"> |
189 | + <img src="music_512.png"> |
190 | + </div> |
191 | + |
192 | + <h1>Ubuntu One Music</h1> |
193 | + |
194 | + <p class="center"> |
195 | + Version 2.0 |
196 | + </p> |
197 | + <p class="center"> |
198 | + ©2010-2011 Canonical Limited. All rights reserved. |
199 | + </p> |
200 | + <p class="center"> |
201 | + Support: <a href="https://one.ubuntu.com/support/">one.ubuntu.com/support</a> |
202 | + </p> |
203 | + |
204 | + <div id="acknowledgements"> |
205 | + <h2>Acknowledgements</h2> |
206 | + <p> |
207 | + Special thanks to Ben Baron, developer of iSub |
208 | + (<a href="http://einsteinx2.com/projects/isub/">http://einsteinx2.com/projects/isub/</a>) |
209 | + </p> |
210 | + |
211 | + <div id="source"> |
212 | + <div class="item"> |
213 | + <p> |
214 | + iSub Music Streamer<br> Copyright 2010 Ben Baron. All |
215 | + rights reserved. |
216 | + </p> |
217 | + <p> |
218 | + Redistribution and use in source and binary forms, with |
219 | + or without modification, are permitted provided that the |
220 | + following conditions are met: |
221 | + </p> |
222 | + <p> |
223 | + * Redistributions of source code must retain the above |
224 | + copyright notice, this list of conditions and the |
225 | + following disclaimer.<br> |
226 | + |
227 | + * Redistributions in binary form must reproduce the |
228 | + above copyright notice, this list of conditions and the |
229 | + following disclaimer in the documentation and/or other |
230 | + materials provided with the distribution.<br> |
231 | + |
232 | + * Neither the my name nor the names of my contributors |
233 | + may be used to endorse or promote products derived from |
234 | + this software without specific prior written permission. |
235 | + </p> |
236 | + <p> |
237 | + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
238 | + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED |
239 | + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
240 | + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
241 | + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
242 | + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
243 | + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
244 | + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
245 | + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
246 | + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
247 | + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
248 | + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
249 | + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
250 | + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
251 | + OF SUCH DAMAGE. |
252 | + </p> |
253 | + </div> |
254 | + |
255 | + <div class="item"> |
256 | + <p> |
257 | + Icons by Joseph Wain / glyphish.com |
258 | + </p> |
259 | + </div> |
260 | + |
261 | + <div class="item"> |
262 | + <p> |
263 | + SynthesizeSingleton |
264 | + </p> |
265 | + <p> |
266 | + Created by Matt Gallagher on 20/10/08.<br> Copyright |
267 | + 2009 Matt Gallagher. All rights reserved. |
268 | + </p> |
269 | + <p> |
270 | + Permission is given to use this source code file without |
271 | + charge in any project, commercial or otherwise, entirely |
272 | + at your risk, with the condition that any redistribution |
273 | + (in part or whole) of source code must retain this |
274 | + copyright and permission notice. Attribution in compiled |
275 | + projects is appreciated but not required.</p> |
276 | + </div> |
277 | + |
278 | + <div class="item"> |
279 | + <p> |
280 | + UIDevice+Hardware<br> Erica Sadun, |
281 | + http://ericasadun.com<br> iPhone Developer's Cookbook, |
282 | + 3.0 Edition<br> Thanks to Emanuele Vulcano, Kevin |
283 | + Ballard/Eridius, Ryandjohnson, Matt Brown, etc. |
284 | + </p> |
285 | + </div> |
286 | + |
287 | + <div class="item"> |
288 | + <p> |
289 | + Copyright (c) 2010 Leah Culver |
290 | + </p> |
291 | + <p> |
292 | + Permission is hereby granted, free of charge, to any |
293 | + person obtaining a copy of this software and associated |
294 | + documentation files (the "Software"), to deal in the |
295 | + Software without restriction, including without |
296 | + limitation the rights to use, copy, modify, merge, |
297 | + publish, distribute, sublicense, and/or sell copies of |
298 | + the Software, and to permit persons to whom the Software |
299 | + is furnished to do so, subject to the following |
300 | + conditions: |
301 | + </p> |
302 | + <p> |
303 | + The above copyright notice and this permission notice |
304 | + shall be included in all copies or substantial portions |
305 | + of the Software. |
306 | + </p> |
307 | + <p> |
308 | + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF |
309 | + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
310 | + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A |
311 | + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT |
312 | + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
313 | + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
314 | + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR |
315 | + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
316 | + DEALINGS IN THE SOFTWARE. |
317 | + </p> |
318 | + |
319 | + <div class="item"> |
320 | + <p> |
321 | + Copyright (C) 2011 by Random Ideas, LLC |
322 | + </p> |
323 | + |
324 | + <p> |
325 | + Permission is hereby granted, free of charge, to any |
326 | + person obtaining a copy of this software and |
327 | + associated documentation files (the "Software"), to |
328 | + deal in the Software without restriction, including |
329 | + without limitation the rights to use, copy, modify, |
330 | + merge, publish, distribute, sublicense, and/or sell |
331 | + copies of the Software, and to permit persons to whom |
332 | + the Software is furnished to do so, subject to the |
333 | + following conditions: |
334 | + </p> |
335 | + |
336 | + <p> |
337 | + The above copyright notice and this permission notice |
338 | + shall be included in all copies or substantial |
339 | + portions of the Software. |
340 | + </p> |
341 | + |
342 | + <p> |
343 | + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF |
344 | + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT |
345 | + LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
346 | + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO |
347 | + EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE |
348 | + FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
349 | + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
350 | + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
351 | + USE OR OTHER DEALINGS IN THE SOFTWARE. |
352 | + </p> |
353 | + </div> |
354 | + </div> <!-- #source --> |
355 | </div> |
356 | - </body> |
357 | -</html> |
358 | \ No newline at end of file |
359 | + </div> |
360 | + </div> |
361 | + </body> |
362 | +</html> |
363 | |
364 | === added file 'musicstreaming/albums.png' |
365 | Binary files musicstreaming/albums.png 1970-01-01 00:00:00 +0000 and musicstreaming/albums.png 2011-06-13 16:58:33 +0000 differ |
366 | === added file 'musicstreaming/albums@2x.png' |
367 | Binary files musicstreaming/albums@2x.png 1970-01-01 00:00:00 +0000 and musicstreaming/albums@2x.png 2011-06-13 16:58:33 +0000 differ |
368 | === added file 'musicstreaming/artists.png' |
369 | Binary files musicstreaming/artists.png 1970-01-01 00:00:00 +0000 and musicstreaming/artists.png 2011-06-13 16:58:33 +0000 differ |
370 | === added file 'musicstreaming/artists@2x.png' |
371 | Binary files musicstreaming/artists@2x.png 1970-01-01 00:00:00 +0000 and musicstreaming/artists@2x.png 2011-06-13 16:58:33 +0000 differ |
372 | === added file 'musicstreaming/cached.png' |
373 | Binary files musicstreaming/cached.png 1970-01-01 00:00:00 +0000 and musicstreaming/cached.png 2011-06-13 16:58:33 +0000 differ |
374 | === added file 'musicstreaming/cached@2x.png' |
375 | Binary files musicstreaming/cached@2x.png 1970-01-01 00:00:00 +0000 and musicstreaming/cached@2x.png 2011-06-13 16:58:33 +0000 differ |
376 | === added file 'musicstreaming/categories/NSString+Extras.h' |
377 | --- musicstreaming/categories/NSString+Extras.h 1970-01-01 00:00:00 +0000 |
378 | +++ musicstreaming/categories/NSString+Extras.h 2011-06-13 16:58:33 +0000 |
379 | @@ -0,0 +1,26 @@ |
380 | +// |
381 | +// NSString+Extras.h |
382 | +// iSub |
383 | +// |
384 | +// Created by Zachery Bir on 5/23/11. |
385 | +// Copyright 2011 Canonical Ltd. |
386 | +// |
387 | +// This program is free software: you can redistribute it and/or modify it |
388 | +// under the terms of the GNU Affero General Public License version 3, |
389 | +// as published by the Free Software Foundation. |
390 | +// |
391 | +// This program is distributed in the hope that it will be useful, but |
392 | +// WITHOUT ANY WARRANTY; without even the implied warranties of |
393 | +// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
394 | +// PURPOSE. See the GNU Affero General Public License for more details. |
395 | +// |
396 | +// You should have received a copy of the GNU Affero General Public License |
397 | +// along with this program. If not, see <http://www.gnu.org/licenses/>. |
398 | + |
399 | +#import <Foundation/Foundation.h> |
400 | + |
401 | + |
402 | +@interface NSString (NSString_Extras) |
403 | +- (NSString *)dearticlizedString; |
404 | +- (NSString *)dearticlizedIndex; |
405 | +@end |
406 | |
407 | === added file 'musicstreaming/categories/NSString+Extras.m' |
408 | --- musicstreaming/categories/NSString+Extras.m 1970-01-01 00:00:00 +0000 |
409 | +++ musicstreaming/categories/NSString+Extras.m 2011-06-13 16:58:33 +0000 |
410 | @@ -0,0 +1,46 @@ |
411 | +// |
412 | +// NSString+Extras.m |
413 | +// iSub |
414 | +// |
415 | +// Created by Zachery Bir on 5/23/11. |
416 | +// Copyright 2011 Canonical Ltd. |
417 | +// |
418 | +// This program is free software: you can redistribute it and/or modify it |
419 | +// under the terms of the GNU Affero General Public License version 3, |
420 | +// as published by the Free Software Foundation. |
421 | +// |
422 | +// This program is distributed in the hope that it will be useful, but |
423 | +// WITHOUT ANY WARRANTY; without even the implied warranties of |
424 | +// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
425 | +// PURPOSE. See the GNU Affero General Public License for more details. |
426 | +// |
427 | +// You should have received a copy of the GNU Affero General Public License |
428 | +// along with this program. If not, see <http://www.gnu.org/licenses/>. |
429 | + |
430 | +#import "NSString+Extras.h" |
431 | + |
432 | + |
433 | +@implementation NSString (NSString_Extras) |
434 | + |
435 | +- (NSString *)dearticlizedString |
436 | +{ |
437 | + NSError *error = NULL; |
438 | + NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:@"^(the|a|an|le|les|la|el|las|los)\\s(.*)$" |
439 | + options:NSRegularExpressionCaseInsensitive |
440 | + error:&error]; |
441 | + |
442 | + NSString *dearticlized = [expression stringByReplacingMatchesInString:self |
443 | + options:NSMatchingWithoutAnchoringBounds |
444 | + range:NSMakeRange(0, [self length]) |
445 | + withTemplate:@"$2, $1"]; |
446 | + |
447 | + return dearticlized; |
448 | +} |
449 | + |
450 | +- (NSString *)dearticlizedIndex |
451 | +{ |
452 | + NSString *index = [[self dearticlizedString] substringToIndex:1]; |
453 | + |
454 | + return index; |
455 | +} |
456 | +@end |
457 | |
458 | === added file 'musicstreaming/categories/UIActionSheet+Blocks.h' |
459 | --- musicstreaming/categories/UIActionSheet+Blocks.h 1970-01-01 00:00:00 +0000 |
460 | +++ musicstreaming/categories/UIActionSheet+Blocks.h 2011-06-13 16:58:33 +0000 |
461 | @@ -0,0 +1,16 @@ |
462 | +// |
463 | +// UIActionSheet+Blocks.h |
464 | +// Shibui |
465 | +// |
466 | +// Created by Jiva DeVoe on 1/5/11. |
467 | +// Copyright 2011 Random Ideas, LLC. All rights reserved. |
468 | +// |
469 | + |
470 | +#import <Foundation/Foundation.h> |
471 | +#import "RIButtonItem.h" |
472 | + |
473 | +@interface UIActionSheet (Blocks) <UIActionSheetDelegate> |
474 | + |
475 | +-(id)initWithTitle:(NSString *)inTitle cancelButtonItem:(RIButtonItem *)inCancelButtonItem destructiveButtonItem:(RIButtonItem *)inDestructiveItem otherButtonItems:(RIButtonItem *)inOtherButtonItems, ... NS_REQUIRES_NIL_TERMINATION; |
476 | + |
477 | +@end |
478 | |
479 | === added file 'musicstreaming/categories/UIActionSheet+Blocks.m' |
480 | --- musicstreaming/categories/UIActionSheet+Blocks.m 1970-01-01 00:00:00 +0000 |
481 | +++ musicstreaming/categories/UIActionSheet+Blocks.m 2011-06-13 16:58:33 +0000 |
482 | @@ -0,0 +1,71 @@ |
483 | +// |
484 | +// UIActionSheet+Blocks.m |
485 | +// Shibui |
486 | +// |
487 | +// Created by Jiva DeVoe on 1/5/11. |
488 | +// Copyright 2011 Random Ideas, LLC. All rights reserved. |
489 | +// |
490 | + |
491 | +#import "UIActionSheet+Blocks.h" |
492 | +#import <objc/runtime.h> |
493 | + |
494 | +static NSString *RI_BUTTON_ASS_KEY = @"com.random-ideas.BUTTONS"; |
495 | + |
496 | +@implementation UIActionSheet (Blocks) |
497 | + |
498 | +-(id)initWithTitle:(NSString *)inTitle cancelButtonItem:(RIButtonItem *)inCancelButtonItem destructiveButtonItem:(RIButtonItem *)inDestructiveItem otherButtonItems:(RIButtonItem *)inOtherButtonItems, ... |
499 | +{ |
500 | + if((self = [self initWithTitle:inTitle delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil])) |
501 | + { |
502 | + NSMutableArray *buttonsArray = [NSMutableArray array]; |
503 | + |
504 | + RIButtonItem *eachItem; |
505 | + va_list argumentList; |
506 | + if (inOtherButtonItems) |
507 | + { |
508 | + [buttonsArray addObject: inOtherButtonItems]; |
509 | + va_start(argumentList, inOtherButtonItems); |
510 | + while((eachItem = va_arg(argumentList, RIButtonItem *))) |
511 | + { |
512 | + [buttonsArray addObject: eachItem]; |
513 | + } |
514 | + va_end(argumentList); |
515 | + } |
516 | + |
517 | + for(RIButtonItem *item in buttonsArray) |
518 | + { |
519 | + [self addButtonWithTitle:item.label]; |
520 | + } |
521 | + |
522 | + if(inDestructiveItem) |
523 | + { |
524 | + [buttonsArray addObject:inDestructiveItem]; |
525 | + NSInteger destIndex = [self addButtonWithTitle:inDestructiveItem.label]; |
526 | + [self setDestructiveButtonIndex:destIndex]; |
527 | + } |
528 | + if(inCancelButtonItem) |
529 | + { |
530 | + [buttonsArray addObject:inCancelButtonItem]; |
531 | + NSInteger cancelIndex = [self addButtonWithTitle:inCancelButtonItem.label]; |
532 | + [self setCancelButtonIndex:cancelIndex]; |
533 | + } |
534 | + |
535 | + objc_setAssociatedObject(self, RI_BUTTON_ASS_KEY, buttonsArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC); |
536 | + |
537 | + [self retain]; // keep yourself around! |
538 | + } |
539 | + return self; |
540 | +} |
541 | + |
542 | +- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex |
543 | +{ |
544 | + NSArray *buttonsArray = objc_getAssociatedObject(self, RI_BUTTON_ASS_KEY); |
545 | + RIButtonItem *item = [buttonsArray objectAtIndex:buttonIndex]; |
546 | + if(item.action) |
547 | + item.action(); |
548 | + objc_setAssociatedObject(self, RI_BUTTON_ASS_KEY, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); |
549 | + [self release]; // and release yourself! |
550 | +} |
551 | + |
552 | + |
553 | +@end |
554 | |
555 | === added file 'musicstreaming/categories/UIAlertView+Blocks.h' |
556 | --- musicstreaming/categories/UIAlertView+Blocks.h 1970-01-01 00:00:00 +0000 |
557 | +++ musicstreaming/categories/UIAlertView+Blocks.h 2011-06-13 16:58:33 +0000 |
558 | @@ -0,0 +1,16 @@ |
559 | +// |
560 | +// UIAlertView+Blocks.h |
561 | +// Shibui |
562 | +// |
563 | +// Created by Jiva DeVoe on 12/28/10. |
564 | +// Copyright 2010 Random Ideas, LLC. All rights reserved. |
565 | +// |
566 | + |
567 | +#import <Foundation/Foundation.h> |
568 | +#import "RIButtonItem.h" |
569 | + |
570 | +@interface UIAlertView (Blocks) |
571 | + |
572 | +-(id)initWithTitle:(NSString *)inTitle message:(NSString *)inMessage cancelButtonItem:(RIButtonItem *)inCancelButtonItem otherButtonItems:(RIButtonItem *)inOtherButtonItems, ... NS_REQUIRES_NIL_TERMINATION; |
573 | + |
574 | +@end |
575 | |
576 | === added file 'musicstreaming/categories/UIAlertView+Blocks.m' |
577 | --- musicstreaming/categories/UIAlertView+Blocks.m 1970-01-01 00:00:00 +0000 |
578 | +++ musicstreaming/categories/UIAlertView+Blocks.m 2011-06-13 16:58:33 +0000 |
579 | @@ -0,0 +1,61 @@ |
580 | +// |
581 | +// UIAlertView+Blocks.m |
582 | +// Shibui |
583 | +// |
584 | +// Created by Jiva DeVoe on 12/28/10. |
585 | +// Copyright 2010 Random Ideas, LLC. All rights reserved. |
586 | +// |
587 | + |
588 | +#import "UIAlertView+Blocks.h" |
589 | +#import <objc/runtime.h> |
590 | + |
591 | +static NSString *RI_BUTTON_ASS_KEY = @"com.random-ideas.BUTTONS"; |
592 | + |
593 | +@implementation UIAlertView (Blocks) |
594 | + |
595 | +-(id)initWithTitle:(NSString *)inTitle message:(NSString *)inMessage cancelButtonItem:(RIButtonItem *)inCancelButtonItem otherButtonItems:(RIButtonItem *)inOtherButtonItems, ... |
596 | +{ |
597 | + if((self = [self initWithTitle:inTitle message:inMessage delegate:self cancelButtonTitle:inCancelButtonItem.label otherButtonTitles:nil])) |
598 | + { |
599 | + NSMutableArray *buttonsArray = [NSMutableArray array]; |
600 | + |
601 | + RIButtonItem *eachItem; |
602 | + va_list argumentList; |
603 | + if (inOtherButtonItems) |
604 | + { |
605 | + [buttonsArray addObject: inOtherButtonItems]; |
606 | + va_start(argumentList, inOtherButtonItems); |
607 | + while((eachItem = va_arg(argumentList, RIButtonItem *))) |
608 | + { |
609 | + [buttonsArray addObject: eachItem]; |
610 | + } |
611 | + va_end(argumentList); |
612 | + } |
613 | + |
614 | + for(RIButtonItem *item in buttonsArray) |
615 | + { |
616 | + [self addButtonWithTitle:item.label]; |
617 | + } |
618 | + |
619 | + if(inCancelButtonItem) |
620 | + [buttonsArray insertObject:inCancelButtonItem atIndex:0]; |
621 | + |
622 | + objc_setAssociatedObject(self, RI_BUTTON_ASS_KEY, buttonsArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC); |
623 | + |
624 | + [self setDelegate:self]; |
625 | + [self retain]; // keep yourself around! |
626 | + } |
627 | + return self; |
628 | +} |
629 | + |
630 | +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex |
631 | +{ |
632 | + NSArray *buttonsArray = objc_getAssociatedObject(self, RI_BUTTON_ASS_KEY); |
633 | + RIButtonItem *item = [buttonsArray objectAtIndex:buttonIndex]; |
634 | + if(item.action) |
635 | + item.action(); |
636 | + objc_setAssociatedObject(self, RI_BUTTON_ASS_KEY, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); |
637 | + [self release]; // and release yourself! |
638 | +} |
639 | + |
640 | +@end |
641 | |
642 | === modified file 'musicstreaming/controls/AlbumUITableViewCell.h' |
643 | --- musicstreaming/controls/AlbumUITableViewCell.h 2010-09-20 20:32:15 +0000 |
644 | +++ musicstreaming/controls/AlbumUITableViewCell.h 2011-06-13 16:58:33 +0000 |
645 | @@ -30,14 +30,12 @@ |
646 | |
647 | #import <UIKit/UIKit.h> |
648 | |
649 | -@class AsynchronousImageViewCached; |
650 | - |
651 | @interface AlbumUITableViewCell : UITableViewCell { |
652 | - AsynchronousImageViewCached *coverArtView; |
653 | + UIImageView *coverArtView; |
654 | UILabel *albumNameLabel; |
655 | } |
656 | |
657 | -@property (nonatomic, retain) AsynchronousImageViewCached *coverArtView; |
658 | +@property (nonatomic, retain) UIImageView *coverArtView; |
659 | @property (nonatomic, retain) UILabel *albumNameLabel; |
660 | |
661 | @end |
662 | |
663 | === modified file 'musicstreaming/controls/AlbumUITableViewCell.m' |
664 | --- musicstreaming/controls/AlbumUITableViewCell.m 2011-04-14 04:24:43 +0000 |
665 | +++ musicstreaming/controls/AlbumUITableViewCell.m 2011-06-13 16:58:33 +0000 |
666 | @@ -29,7 +29,6 @@ |
667 | // DAMAGE. |
668 | |
669 | #import "AlbumUITableViewCell.h" |
670 | -#import "AsynchronousImageViewCached.h" |
671 | |
672 | @implementation AlbumUITableViewCell |
673 | |
674 | @@ -37,7 +36,7 @@ |
675 | |
676 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { |
677 | if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { |
678 | - self.coverArtView = [[[AsynchronousImageViewCached alloc] init] autorelease]; |
679 | + self.coverArtView = [[[UIImageView alloc] init] autorelease]; |
680 | [self.contentView addSubview:self.coverArtView]; |
681 | |
682 | self.albumNameLabel = [[[UILabel alloc] init] autorelease]; |
683 | |
684 | === removed file 'musicstreaming/controls/AsynchronousImageView.h' |
685 | --- musicstreaming/controls/AsynchronousImageView.h 2010-09-20 20:32:15 +0000 |
686 | +++ musicstreaming/controls/AsynchronousImageView.h 1970-01-01 00:00:00 +0000 |
687 | @@ -1,23 +0,0 @@ |
688 | -// |
689 | -// AsynchronousImageView.h |
690 | -// GLOSS |
691 | -// |
692 | -// Created by Слава on 22.10.09. |
693 | -// Copyright 2009 Slava Bushtruk. All rights reserved. |
694 | -// --------------------------------------------------- |
695 | -// |
696 | -// Modified by Ben Baron for the iSub project. |
697 | -// |
698 | - |
699 | -#import <UIKit/UIKit.h> |
700 | - |
701 | - |
702 | -@interface AsynchronousImageView : UIImageView |
703 | -{ |
704 | - NSURLConnection *connection; |
705 | - NSMutableData *data; |
706 | -} |
707 | - |
708 | -- (void)loadImageFromURLString:(NSString *)theUrlString; |
709 | - |
710 | -@end |
711 | |
712 | === removed file 'musicstreaming/controls/AsynchronousImageView.m' |
713 | --- musicstreaming/controls/AsynchronousImageView.m 2011-04-15 20:03:25 +0000 |
714 | +++ musicstreaming/controls/AsynchronousImageView.m 1970-01-01 00:00:00 +0000 |
715 | @@ -1,78 +0,0 @@ |
716 | -// |
717 | -// AsynchronousImageView.m |
718 | -// GLOSS |
719 | -// |
720 | -// Created by Слава on 22.10.09. |
721 | -// Copyright 2009 Slava Bushtruk. All rights reserved. |
722 | -// --------------------------------------------------- |
723 | -// |
724 | -// Modified by Ben Baron for the iSub project. |
725 | -// |
726 | - |
727 | -#import "AsynchronousImageView.h" |
728 | -#import "iSubAppDelegate.h" |
729 | -#import "StreamingPlayer.h" |
730 | - |
731 | -@implementation AsynchronousImageView |
732 | - |
733 | -- (void)loadImageFromURLString:(NSString *)theUrlString |
734 | -{ |
735 | - [self.image release], self.image = nil; |
736 | - NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:theUrlString] |
737 | - cachePolicy:NSURLRequestReturnCacheDataElseLoad |
738 | - timeoutInterval:30.0]; |
739 | - |
740 | - connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; |
741 | -} |
742 | - |
743 | - |
744 | -- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData |
745 | -{ |
746 | - if (data == nil) |
747 | - data = [[NSMutableData alloc] initWithCapacity:2048]; |
748 | - |
749 | - [data appendData:incrementalData]; |
750 | -} |
751 | - |
752 | - |
753 | -- (void)connection:(NSURLConnection *)theConnection didFailWithError:(NSError *)error |
754 | -{ |
755 | - NSLog(@"Connection to album art failed"); |
756 | - |
757 | - [[StreamingPlayer sharedStreamingPlayer] setCurrentCoverArt:[UIImage imageNamed:@"default-album-art.png"]]; |
758 | - self.image = [StreamingPlayer sharedStreamingPlayer].currentCoverArt; |
759 | - |
760 | - RELEASE_SAFELY(data); |
761 | - RELEASE_SAFELY(connection); |
762 | -} |
763 | - |
764 | - |
765 | -- (void)connectionDidFinishLoading:(NSURLConnection *)theConnection |
766 | -{ |
767 | - UIImage *image = [UIImage imageWithData:data]; |
768 | - |
769 | - if (image) |
770 | - { |
771 | - [StreamingPlayer sharedStreamingPlayer].currentCoverArt = image; |
772 | - } |
773 | - else |
774 | - { |
775 | - [StreamingPlayer sharedStreamingPlayer].currentCoverArt = [UIImage imageNamed:@"default-album-art.png"]; |
776 | - } |
777 | - |
778 | - self.image = [StreamingPlayer sharedStreamingPlayer].currentCoverArt; |
779 | - |
780 | - RELEASE_SAFELY(data); |
781 | - RELEASE_SAFELY(connection); |
782 | -} |
783 | - |
784 | - |
785 | -- (void)dealloc |
786 | -{ |
787 | - RELEASE_SAFELY(data); |
788 | - RELEASE_SAFELY(connection); |
789 | - |
790 | - [super dealloc]; |
791 | -} |
792 | - |
793 | -@end |
794 | |
795 | === removed file 'musicstreaming/controls/AsynchronousImageViewCached.h' |
796 | --- musicstreaming/controls/AsynchronousImageViewCached.h 2011-04-14 19:06:11 +0000 |
797 | +++ musicstreaming/controls/AsynchronousImageViewCached.h 1970-01-01 00:00:00 +0000 |
798 | @@ -1,26 +0,0 @@ |
799 | -// |
800 | -// AsynchronousImageView.h |
801 | -// GLOSS |
802 | -// |
803 | -// Created by Слава on 22.10.09. |
804 | -// Copyright 2009 Slava Bushtruk. All rights reserved. |
805 | -// --------------------------------------------------- |
806 | -// |
807 | -// Modified by Ben Baron for the iSub project. |
808 | -// |
809 | - |
810 | -#import <UIKit/UIKit.h> |
811 | - |
812 | - |
813 | -@interface AsynchronousImageViewCached : UIImageView |
814 | -{ |
815 | - NSURLConnection *connection; |
816 | - NSMutableData *data; |
817 | - NSString *coverArtId; |
818 | - int displaySize; |
819 | -} |
820 | -- (void)loadImageId:(NSString *)artId forSize:(int)aSize; |
821 | -- (void)loadImageFromURLString:(NSString *)theUrlString; |
822 | -- (void)loadCachedImageId:(NSString *)artId; |
823 | -- (void)loadDefaultImage; |
824 | -@end |
825 | |
826 | === removed file 'musicstreaming/controls/AsynchronousImageViewCached.m' |
827 | --- musicstreaming/controls/AsynchronousImageViewCached.m 2011-04-15 20:03:25 +0000 |
828 | +++ musicstreaming/controls/AsynchronousImageViewCached.m 1970-01-01 00:00:00 +0000 |
829 | @@ -1,120 +0,0 @@ |
830 | -// |
831 | -// AsynchronousImageView.m |
832 | -// GLOSS |
833 | -// |
834 | -// Created by Слава on 22.10.09. |
835 | -// Copyright 2009 Slava Bushtruk. All rights reserved. |
836 | -// --------------------------------------------------- |
837 | -// |
838 | -// Modified by Ben Baron for the iSub project. |
839 | -// |
840 | - |
841 | -#import "AsynchronousImageViewCached.h" |
842 | -#import "iSubAppDelegate.h" |
843 | -#import "UIImage+Resize.h" |
844 | -#import "NSMutableSet+Extras.h" |
845 | -#import "Subsonic.h" |
846 | - |
847 | -@implementation AsynchronousImageViewCached |
848 | - |
849 | -- (void)loadImageId:(NSString *)artId forSize:(int)aSize |
850 | -{ |
851 | - coverArtId = [artId retain]; |
852 | - displaySize = aSize; |
853 | - if (nil != artId) |
854 | - { |
855 | - [self loadCachedImageId:artId]; |
856 | - } |
857 | - else |
858 | - { |
859 | - [self loadDefaultImage]; |
860 | - } |
861 | -} |
862 | - |
863 | -- (void)loadImageFromURLString:(NSString *)theUrlString |
864 | -{ |
865 | - self.image = nil; |
866 | - NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:theUrlString] |
867 | - cachePolicy:NSURLRequestReturnCacheDataElseLoad |
868 | - timeoutInterval:30.0]; |
869 | - connection = [[NSURLConnection alloc] initWithRequest:request |
870 | - delegate:self |
871 | - startImmediately:YES]; |
872 | -} |
873 | - |
874 | -- (void)loadCachedImageId:(NSString *)artId |
875 | -{ |
876 | - iSubAppDelegate *appDelegate = (iSubAppDelegate *)[[UIApplication sharedApplication] delegate]; |
877 | - |
878 | - if ([appDelegate.coverArtCache objectForKey:artId]) |
879 | - { |
880 | - // If the image is already in the cache dictionary, load it |
881 | - self.image = [[appDelegate.coverArtCache objectForKey:artId] resizedImage:CGSizeMake(displaySize, displaySize) |
882 | - interpolationQuality:kCGInterpolationHigh]; |
883 | - } |
884 | - else |
885 | - { |
886 | - // If not, grab it from the url and cache it |
887 | - NSMutableSet *parameters = [NSMutableSet set]; |
888 | - [parameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"id", artId, nil]]; |
889 | - // Always get the largest we can handle |
890 | - [parameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"size", [NSString stringWithFormat:@"%d", 640], nil]]; |
891 | - NSURL *url = [[Subsonic sharedSubsonic] getBaseURL:@"getCoverArt.view" parameters:parameters]; |
892 | - [self loadImageFromURLString:[url absoluteString]]; |
893 | - } |
894 | -} |
895 | - |
896 | -- (void)loadDefaultImage |
897 | -{ |
898 | - self.image = [[UIImage imageNamed:@"default-album-art.png"] resizedImage:CGSizeMake(displaySize, displaySize) |
899 | - interpolationQuality:kCGInterpolationHigh]; |
900 | -} |
901 | - |
902 | -- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData |
903 | -{ |
904 | - if (data == nil) |
905 | - data = [[NSMutableData alloc] initWithCapacity:2048]; |
906 | - |
907 | - [data appendData:incrementalData]; |
908 | -} |
909 | - |
910 | - |
911 | -- (void)connection:(NSURLConnection *)theConnection didFailWithError:(NSError *)error |
912 | -{ |
913 | - NSLog(@"Connection to album art failed"); |
914 | - [data release], data = nil; |
915 | - [connection release], connection = nil; |
916 | -} |
917 | - |
918 | - |
919 | -- (void)connectionDidFinishLoading:(NSURLConnection *)theConnection |
920 | -{ |
921 | - iSubAppDelegate *appDelegate = (iSubAppDelegate *)[[UIApplication sharedApplication] delegate]; |
922 | - |
923 | - // Check to see if the data is a valid image. If so, use it; if not, use the default image. |
924 | - if([UIImage imageWithData:data]) |
925 | - { |
926 | - [appDelegate.coverArtCache setObject:[UIImage imageWithData:data] forKey:coverArtId]; |
927 | - self.image = [[UIImage imageWithData:data] resizedImage:CGSizeMake(displaySize, displaySize) |
928 | - interpolationQuality:kCGInterpolationHigh]; |
929 | - } |
930 | - else |
931 | - { |
932 | - [self loadDefaultImage]; |
933 | - } |
934 | - |
935 | - [coverArtId release]; |
936 | - [data release], data = nil; |
937 | - [connection release], connection = nil; |
938 | -} |
939 | - |
940 | - |
941 | -- (void)dealloc { |
942 | - [data release]; |
943 | - [connection cancel]; |
944 | - [connection release]; |
945 | - connection = nil; |
946 | - [super dealloc]; |
947 | -} |
948 | - |
949 | -@end |
950 | |
951 | === removed file 'musicstreaming/controls/MBProgressHUD.h' |
952 | --- musicstreaming/controls/MBProgressHUD.h 2010-08-26 22:06:31 +0000 |
953 | +++ musicstreaming/controls/MBProgressHUD.h 1970-01-01 00:00:00 +0000 |
954 | @@ -1,273 +0,0 @@ |
955 | -// |
956 | -// MBProgressHUD.h |
957 | -// Version 0.33 |
958 | -// Created by Matej Bukovinski on 2.4.09. |
959 | -// |
960 | - |
961 | -// This code is distributed under the terms and conditions of the MIT license. |
962 | - |
963 | -// Copyright (c) 2009 Matej Bukovinski |
964 | -// |
965 | -// Permission is hereby granted, free of charge, to any person obtaining a copy |
966 | -// of this software and associated documentation files (the "Software"), to deal |
967 | -// in the Software without restriction, including without limitation the rights |
968 | -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
969 | -// copies of the Software, and to permit persons to whom the Software is |
970 | -// furnished to do so, subject to the following conditions: |
971 | -// |
972 | -// The above copyright notice and this permission notice shall be included in |
973 | -// all copies or substantial portions of the Software. |
974 | -// |
975 | -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
976 | -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
977 | -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
978 | -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
979 | -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
980 | -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
981 | -// THE SOFTWARE. |
982 | - |
983 | -#import <UIKit/UIKit.h> |
984 | - |
985 | -/** |
986 | - * MBProgressHUD operation modes. |
987 | - */ |
988 | -typedef enum { |
989 | - /** Progress is shown using an UIActivityIndicatorView. This is the default. */ |
990 | - MBProgressHUDModeIndeterminate, |
991 | - /** Progress is shown using a MBRoundProgressView. */ |
992 | - MBProgressHUDModeDeterminate, |
993 | - /** Shows a custom view */ |
994 | - MBProgressHUDModeCustomView |
995 | -} MBProgressHUDMode; |
996 | - |
997 | - |
998 | -/** |
999 | - * Defines callback methods for MBProgressHUD delegates. |
1000 | - */ |
1001 | -@protocol MBProgressHUDDelegate <NSObject> |
1002 | - |
1003 | -@required |
1004 | -/** |
1005 | - * A callback function that is called after the HUD was fully hidden from the screen. |
1006 | - */ |
1007 | -- (void)hudWasHidden; |
1008 | - |
1009 | -@end |
1010 | - |
1011 | - |
1012 | -/** |
1013 | - * A progress view for showing definite progress by filling up a circle (similar to the indicator for building in xcode). |
1014 | - */ |
1015 | -@interface MBRoundProgressView : UIProgressView { |
1016 | - |
1017 | -} |
1018 | - |
1019 | -/** |
1020 | - * Create a 37 by 37 pixel indicator. |
1021 | - * This is the same size as used by the larger UIActivityIndicatorView. |
1022 | - */ |
1023 | -- (id)initWithDefaultSize; |
1024 | - |
1025 | -@end |
1026 | - |
1027 | -/** |
1028 | - * Displays a simple HUD window containing a progress indicator and two optional labels for short messages. |
1029 | - * |
1030 | - * This is a simple drop-in class for displaying a progress HUD view similar to Apples private UIProgressHUD class. |
1031 | - * The MBProgressHUD window spans over the entire space given to it by the initWithFrame constructor and catches all |
1032 | - * user input on this region, thereby preventing the user operations on components below the view. The HUD itself is |
1033 | - * drawn centered as a rounded semi-transparent view witch resizes depending on the user specified content. |
1034 | - * |
1035 | - * This view supports three modes of operation: |
1036 | - * - MBProgressHUDModeIndeterminate - shows a UIActivityIndicatorView |
1037 | - * - MBProgressHUDModeDeterminate - shows a custom round progress indicator (MBRoundProgressView) |
1038 | - * - MBProgressHUDModeCustomView - shows an arbitrary, user specified view (@see customView) |
1039 | - * |
1040 | - * All three modes can have optional labels assigned: |
1041 | - * - If the labelText property is set and non-empty then a label containing the provided content is placed below the |
1042 | - * indicator view. |
1043 | - * - If also the detailsLabelText property is set then another label is placed below the first label. |
1044 | - */ |
1045 | -@interface MBProgressHUD : UIView { |
1046 | - |
1047 | - MBProgressHUDMode mode; |
1048 | - |
1049 | - SEL methodForExecution; |
1050 | - id targetForExecution; |
1051 | - id objectForExecution; |
1052 | - BOOL useAnimation; |
1053 | - |
1054 | - float yOffset; |
1055 | - float xOffset; |
1056 | - |
1057 | - float width; |
1058 | - float height; |
1059 | - |
1060 | - BOOL taskInProgress; |
1061 | - float graceTime; |
1062 | - float minShowTime; |
1063 | - NSTimer *graceTimer; |
1064 | - NSTimer *minShowTimer; |
1065 | - NSDate *showStarted; |
1066 | - |
1067 | - UIView *indicator; |
1068 | - UILabel *label; |
1069 | - UILabel *detailsLabel; |
1070 | - |
1071 | - float progress; |
1072 | - |
1073 | - id<MBProgressHUDDelegate> delegate; |
1074 | - NSString *labelText; |
1075 | - NSString *detailsLabelText; |
1076 | - float opacity; |
1077 | - UIFont *labelFont; |
1078 | - UIFont *detailsLabelFont; |
1079 | - |
1080 | - BOOL isFinished; |
1081 | - |
1082 | - UIView *customView; |
1083 | -} |
1084 | - |
1085 | -/** |
1086 | - * A convenience constructor that initializes the HUD with the window's bounds. Calls the designated constructor with |
1087 | - * window.bounds as the parameter. |
1088 | - * |
1089 | - * @param window The window instance that will provide the bounds for the HUD. Should probably be the same instance as |
1090 | - * the HUD's superview (i.e., the window that the HUD will be added to). |
1091 | - */ |
1092 | -- (id)initWithWindow:(UIWindow *)window; |
1093 | - |
1094 | -/** |
1095 | - * A convenience constructor that initializes the HUD with the view's bounds. Calls the designated constructor with |
1096 | - * view.bounds as the parameter |
1097 | - * |
1098 | - * @param view The view instance that will provide the bounds for the HUD. Should probably be the same instance as |
1099 | - * the HUD's superview (i.e., the view that the HUD will be added to). |
1100 | - */ |
1101 | -- (id)initWithView:(UIView *)view; |
1102 | - |
1103 | -/** |
1104 | - * The UIView (i.g., a UIIMageView) to be shown when the HUD is in MBProgressHUDModeCustomView. |
1105 | - * For best results use a 37 by 37 pixel view (so the bounds match the build in indicator bounds). |
1106 | - */ |
1107 | -@property (retain) UIView *customView; |
1108 | - |
1109 | -/** |
1110 | - * MBProgressHUD operation mode. Switches between indeterminate (MBProgressHUDModeIndeterminate) and determinate |
1111 | - * progress (MBProgressHUDModeDeterminate). The default is MBProgressHUDModeIndeterminate. |
1112 | - */ |
1113 | -@property (assign) MBProgressHUDMode mode; |
1114 | - |
1115 | -/** |
1116 | - * The HUD delegate object. If set the delegate will receive hudWasHidden callbacks when the HUD was hidden. The |
1117 | - * delegate should conform to the MBProgressHUDDelegate protocol and implement the hudWasHidden method. The delegate |
1118 | - * object will not be retained. |
1119 | - */ |
1120 | -@property (assign) id<MBProgressHUDDelegate> delegate; |
1121 | - |
1122 | -/** |
1123 | - * An optional short message to be displayed below the activity indicator. The HUD is automatically resized to fit |
1124 | - * the entire text. If the text is too long it will get clipped by displaying "..." at the end. If left unchanged or |
1125 | - * set to @"", then no message is displayed. |
1126 | - */ |
1127 | -@property (copy) NSString *labelText; |
1128 | - |
1129 | -/** |
1130 | - * An optional details message displayed below the labelText message. This message is displayed only if the labelText |
1131 | - * property is also set and is different from an empty string (@""). |
1132 | - */ |
1133 | -@property (copy) NSString *detailsLabelText; |
1134 | - |
1135 | -/** |
1136 | - * The opacity of the HUD window. Defaults to 0.9 (90% opacity). |
1137 | - */ |
1138 | -@property (assign) float opacity; |
1139 | - |
1140 | -/** |
1141 | - * The x-axis offset of the HUD relative to the centre of the superview. |
1142 | - */ |
1143 | -@property (assign) float xOffset; |
1144 | - |
1145 | -/** |
1146 | - *The y-ayis offset of the HUD relative to the centre of the superview. |
1147 | - */ |
1148 | -@property (assign) float yOffset; |
1149 | - |
1150 | -/* |
1151 | - * Grace period is the time (in seconds) that the invoked method may be run without |
1152 | - * showing the HUD. If the task finishes befor the grace time runs out, the HUD will |
1153 | - * not be shown at all. |
1154 | - * This may be used to prevent HUD display for very short tasks. |
1155 | - * Defaults to 0 (no grace time). |
1156 | - * Grace time functionality is only supported when the task status is known! |
1157 | - * @see taskInProgress |
1158 | - */ |
1159 | -@property (assign) float graceTime; |
1160 | - |
1161 | - |
1162 | -/** |
1163 | - * The minimum time (in seconds) that the HUD is shown. |
1164 | - * This avoids the problem of the HUD being shown and than instantly hidden. |
1165 | - * Defaults to 0 (no minimum show time). |
1166 | - */ |
1167 | -@property (assign) float minShowTime; |
1168 | - |
1169 | -/** |
1170 | - * Indicates that the executed operation is in progress. Needed for correct graceTime operation. |
1171 | - * If you don't set a graceTime (different than 0.0) this does nothing. |
1172 | - * This property is automatically set when using showWhileExecuting:onTarget:withObject:animated:. |
1173 | - * When threading is done outside of the HUD (i.e., when the show: and hide: methods are used directly), |
1174 | - * you need to set this property when your task starts and completes in order to have normal graceTime |
1175 | - * functunality. |
1176 | - */ |
1177 | -@property (assign) BOOL taskInProgress; |
1178 | - |
1179 | -/** |
1180 | - * Font to be used for the main label. Set this property if the default is not adequate. |
1181 | - */ |
1182 | -@property (retain) UIFont* labelFont; |
1183 | - |
1184 | -/** |
1185 | - * Font to be used for the details label. Set this property if the default is not adequate. |
1186 | - */ |
1187 | -@property (retain) UIFont* detailsLabelFont; |
1188 | - |
1189 | -/** |
1190 | - * The progress of the progress indicator, from 0.0 to 1.0. Defaults to 0.0. |
1191 | - */ |
1192 | -@property (assign) float progress; |
1193 | - |
1194 | -/** |
1195 | - * Display the HUD. You need to make sure that the main thread completes its run loop soon after this method call so |
1196 | - * the user interface can be updated. Call this method when your task is already set-up to be executed in a new thread |
1197 | - * (e.g., when using something like NSOperation or calling an asynchronous call like NSUrlRequest). |
1198 | - * |
1199 | - * @param animated If set to YES the HUD will appear using a fade animation. If set to NO the HUD will not use |
1200 | - * animations while appearing. |
1201 | - */ |
1202 | -- (void)show:(BOOL)animated; |
1203 | - |
1204 | -/** |
1205 | - * Hide the HUD, this still calls the hudWasHidden delegate. This is the counterpart of the hide: method. Use it to |
1206 | - * hide the HUD when your task completes. |
1207 | - * |
1208 | - * @param animated If set to YES the HUD will disappear using a fade animation. If set to NO the HUD will not use |
1209 | - * animations while disappearing. |
1210 | - */ |
1211 | -- (void)hide:(BOOL)animated; |
1212 | - |
1213 | -/** |
1214 | - * Shows the HUD while a background task is executing in a new thread, then hides the HUD. |
1215 | - * |
1216 | - * This method also takes care of NSAutoreleasePools so your method does not have to be concerned with setting up a |
1217 | - * pool. |
1218 | - * |
1219 | - * @param method The method to be executed while the HUD is shown. This method will be executed in a new thread. |
1220 | - * @param target The object that the target method belongs to. |
1221 | - * @param object An optional object to be passed to the method. |
1222 | - * @param animated If set to YES the HUD will appear and disappear using a fade animation. If set to NO the HUD will |
1223 | - * not use animations while appearing and disappearing. |
1224 | - */ |
1225 | -- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated; |
1226 | - |
1227 | -@end |
1228 | |
1229 | === removed file 'musicstreaming/controls/MBProgressHUD.m' |
1230 | --- musicstreaming/controls/MBProgressHUD.m 2010-08-26 22:06:31 +0000 |
1231 | +++ musicstreaming/controls/MBProgressHUD.m 1970-01-01 00:00:00 +0000 |
1232 | @@ -1,529 +0,0 @@ |
1233 | -// |
1234 | -// MBProgressHUD.m |
1235 | -// Version 0.33 |
1236 | -// Created by Matej Bukovinski on 2.4.09. |
1237 | -// |
1238 | - |
1239 | -#import "MBProgressHUD.h" |
1240 | - |
1241 | -@interface MBProgressHUD () |
1242 | - |
1243 | -- (void)hideUsingAnimation:(BOOL)animated; |
1244 | -- (void)showUsingAnimation:(BOOL)animated; |
1245 | - |
1246 | -- (void)fillRoundedRect:(CGRect)rect inContext:(CGContextRef)context; |
1247 | - |
1248 | -- (void)done; |
1249 | - |
1250 | -- (void)updateLabelText:(NSString *)newText; |
1251 | -- (void)updateDetailsLabelText:(NSString *)newText; |
1252 | -- (void)updateProgress; |
1253 | -- (void)updateIndicators; |
1254 | - |
1255 | -- (void)handleGraceTimer:(NSTimer *)theTimer; |
1256 | -- (void)handleMinShowTimer:(NSTimer *)theTimer; |
1257 | - |
1258 | -@property (retain) UIView *indicator; |
1259 | - |
1260 | -@property (assign) float width; |
1261 | -@property (assign) float height; |
1262 | - |
1263 | -@property (retain) NSTimer *graceTimer; |
1264 | -@property (retain) NSTimer *minShowTimer; |
1265 | - |
1266 | -@property (retain) NSDate *showStarted; |
1267 | - |
1268 | -@end |
1269 | - |
1270 | - |
1271 | -@implementation MBProgressHUD |
1272 | - |
1273 | -#pragma mark - |
1274 | -#pragma mark Accessors |
1275 | - |
1276 | -@synthesize mode; |
1277 | - |
1278 | -@synthesize delegate; |
1279 | -@synthesize labelText; |
1280 | -@synthesize detailsLabelText; |
1281 | -@synthesize opacity; |
1282 | -@synthesize labelFont; |
1283 | -@synthesize detailsLabelFont; |
1284 | -@synthesize progress; |
1285 | - |
1286 | -@synthesize indicator; |
1287 | - |
1288 | -@synthesize width; |
1289 | -@synthesize height; |
1290 | -@synthesize xOffset; |
1291 | -@synthesize yOffset; |
1292 | - |
1293 | -@synthesize graceTime; |
1294 | -@synthesize minShowTime; |
1295 | -@synthesize graceTimer; |
1296 | -@synthesize minShowTimer; |
1297 | -@synthesize taskInProgress; |
1298 | - |
1299 | -@synthesize customView; |
1300 | - |
1301 | -@synthesize showStarted; |
1302 | - |
1303 | -- (void)setMode:(MBProgressHUDMode)newMode { |
1304 | - // Dont change mode if it wasn't actually changed to prevent flickering |
1305 | - if (mode && (mode == newMode)) { |
1306 | - return; |
1307 | - } |
1308 | - |
1309 | - mode = newMode; |
1310 | - |
1311 | - [self performSelectorOnMainThread:@selector(updateIndicators) withObject:nil waitUntilDone:NO]; |
1312 | - [self performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO]; |
1313 | - [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; |
1314 | -} |
1315 | - |
1316 | -- (void)setLabelText:(NSString *)newText { |
1317 | - [self performSelectorOnMainThread:@selector(updateLabelText:) withObject:newText waitUntilDone:NO]; |
1318 | - [self performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO]; |
1319 | - [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; |
1320 | -} |
1321 | - |
1322 | -- (void)setDetailsLabelText:(NSString *)newText { |
1323 | - [self performSelectorOnMainThread:@selector(updateDetailsLabelText:) withObject:newText waitUntilDone:NO]; |
1324 | - [self performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO]; |
1325 | - [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; |
1326 | -} |
1327 | - |
1328 | -- (void)setProgress:(float)newProgress { |
1329 | - progress = newProgress; |
1330 | - |
1331 | - // Update display ony if showing the determinate progress view |
1332 | - if (mode == MBProgressHUDModeDeterminate) { |
1333 | - [self performSelectorOnMainThread:@selector(updateProgress) withObject:nil waitUntilDone:NO]; |
1334 | - [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; |
1335 | - } |
1336 | -} |
1337 | - |
1338 | -#pragma mark - |
1339 | -#pragma mark Accessor helpers |
1340 | - |
1341 | -- (void)updateLabelText:(NSString *)newText { |
1342 | - if (labelText != newText) { |
1343 | - [labelText release]; |
1344 | - labelText = [newText copy]; |
1345 | - } |
1346 | -} |
1347 | - |
1348 | -- (void)updateDetailsLabelText:(NSString *)newText { |
1349 | - if (detailsLabelText != newText) { |
1350 | - [detailsLabelText release]; |
1351 | - detailsLabelText = [newText copy]; |
1352 | - } |
1353 | -} |
1354 | - |
1355 | -- (void)updateProgress { |
1356 | - [(MBRoundProgressView *)indicator setProgress:progress]; |
1357 | -} |
1358 | - |
1359 | -- (void)updateIndicators { |
1360 | - if (indicator) { |
1361 | - [indicator removeFromSuperview]; |
1362 | - } |
1363 | - |
1364 | - if (mode == MBProgressHUDModeDeterminate) { |
1365 | - self.indicator = [[[MBRoundProgressView alloc] initWithDefaultSize] autorelease]; |
1366 | - } |
1367 | - else if (mode == MBProgressHUDModeCustomView && self.customView != nil){ |
1368 | - self.indicator = self.customView; |
1369 | - } else { |
1370 | - self.indicator = [[[UIActivityIndicatorView alloc] |
1371 | - initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease]; |
1372 | - [(UIActivityIndicatorView *)indicator startAnimating]; |
1373 | - } |
1374 | - |
1375 | - |
1376 | - [self addSubview:indicator]; |
1377 | -} |
1378 | - |
1379 | -#pragma mark - |
1380 | -#pragma mark Constants |
1381 | - |
1382 | -#define MARGIN 20.0 |
1383 | -#define PADDING 4.0 |
1384 | - |
1385 | -#define LABELFONTSIZE 22.0 |
1386 | -#define LABELDETAILSFONTSIZE 16.0 |
1387 | - |
1388 | -#define PI 3.14159265358979323846 |
1389 | - |
1390 | -#pragma mark - |
1391 | -#pragma mark Lifecycle methods |
1392 | - |
1393 | -- (id)initWithWindow:(UIWindow *)window { |
1394 | - return [self initWithView:window]; |
1395 | -} |
1396 | - |
1397 | -- (id)initWithView:(UIView *)view { |
1398 | - // Let's check if the view is nil (this is a common error when using the windw initializer above) |
1399 | - if (!view) { |
1400 | - [NSException raise:@"MBProgressHUDViewIsNillException" |
1401 | - format:@"The view used in the MBProgressHUD initializer is nil."]; |
1402 | - } |
1403 | - return [self initWithFrame:view.bounds]; |
1404 | -} |
1405 | - |
1406 | -- (id)initWithFrame:(CGRect)frame { |
1407 | - if (self = [super initWithFrame:frame]) { |
1408 | - // Set default values for properties |
1409 | - self.mode = MBProgressHUDModeIndeterminate; |
1410 | - self.labelText = nil; |
1411 | - self.detailsLabelText = nil; |
1412 | - self.opacity = 0.9; |
1413 | - self.labelFont = [UIFont boldSystemFontOfSize:LABELFONTSIZE]; |
1414 | - self.detailsLabelFont = [UIFont boldSystemFontOfSize:LABELDETAILSFONTSIZE]; |
1415 | - self.xOffset = 0.0; |
1416 | - self.yOffset = 0.0; |
1417 | - self.graceTime = 0.0; |
1418 | - self.minShowTime = 0.0; |
1419 | - |
1420 | - self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; |
1421 | - |
1422 | - // Transparent background |
1423 | - self.opaque = NO; |
1424 | - self.backgroundColor = [UIColor clearColor]; |
1425 | - |
1426 | - // Make invisible for now |
1427 | - self.alpha = 0.0; |
1428 | - |
1429 | - // Add label |
1430 | - label = [[UILabel alloc] initWithFrame:self.bounds]; |
1431 | - |
1432 | - // Add details label |
1433 | - detailsLabel = [[UILabel alloc] initWithFrame:self.bounds]; |
1434 | - |
1435 | - taskInProgress = NO; |
1436 | - } |
1437 | - return self; |
1438 | -} |
1439 | - |
1440 | -- (void)dealloc { |
1441 | - [indicator release]; |
1442 | - [label release]; |
1443 | - [detailsLabel release]; |
1444 | - [labelText release]; |
1445 | - [detailsLabelText release]; |
1446 | - [graceTimer release]; |
1447 | - [minShowTimer release]; |
1448 | - [showStarted release]; |
1449 | - [customView release]; |
1450 | - [super dealloc]; |
1451 | -} |
1452 | - |
1453 | -#pragma mark - |
1454 | -#pragma mark Layout |
1455 | - |
1456 | -- (void)layoutSubviews { |
1457 | - CGRect frame = self.bounds; |
1458 | - |
1459 | - // Compute HUD dimensions based on indicator size (add margin to HUD border) |
1460 | - CGRect indFrame = indicator.bounds; |
1461 | - self.width = indFrame.size.width + 2 * MARGIN; |
1462 | - self.height = indFrame.size.height + 2 * MARGIN; |
1463 | - |
1464 | - // Position the indicator |
1465 | - indFrame.origin.x = floor((frame.size.width - indFrame.size.width) / 2) + self.xOffset; |
1466 | - indFrame.origin.y = floor((frame.size.height - indFrame.size.height) / 2) + self.yOffset; |
1467 | - indicator.frame = indFrame; |
1468 | - |
1469 | - // Add label if label text was set |
1470 | - if (nil != self.labelText) { |
1471 | - // Get size of label text |
1472 | - CGSize dims = [self.labelText sizeWithFont:self.labelFont]; |
1473 | - |
1474 | - // Compute label dimensions based on font metrics if size is larger than max then clip the label width |
1475 | - float lHeight = dims.height; |
1476 | - float lWidth; |
1477 | - if (dims.width <= (frame.size.width - 2 * MARGIN)) { |
1478 | - lWidth = dims.width; |
1479 | - } |
1480 | - else { |
1481 | - lWidth = frame.size.width - 4 * MARGIN; |
1482 | - } |
1483 | - |
1484 | - // Set label properties |
1485 | - label.font = self.labelFont; |
1486 | - label.adjustsFontSizeToFitWidth = NO; |
1487 | - label.textAlignment = UITextAlignmentCenter; |
1488 | - label.opaque = NO; |
1489 | - label.backgroundColor = [UIColor clearColor]; |
1490 | - label.textColor = [UIColor whiteColor]; |
1491 | - label.text = self.labelText; |
1492 | - |
1493 | - // Update HUD size |
1494 | - if (self.width < (lWidth + 2 * MARGIN)) { |
1495 | - self.width = lWidth + 2 * MARGIN; |
1496 | - } |
1497 | - self.height = self.height + lHeight + PADDING; |
1498 | - |
1499 | - // Move indicator to make room for the label |
1500 | - indFrame.origin.y -= (floor(lHeight / 2 + PADDING / 2)); |
1501 | - indicator.frame = indFrame; |
1502 | - |
1503 | - // Set the label position and dimensions |
1504 | - CGRect lFrame = CGRectMake(floor((frame.size.width - lWidth) / 2) + xOffset, |
1505 | - floor(indFrame.origin.y + indFrame.size.height + PADDING), |
1506 | - lWidth, lHeight); |
1507 | - label.frame = lFrame; |
1508 | - |
1509 | - [self addSubview:label]; |
1510 | - |
1511 | - // Add details label delatils text was set |
1512 | - if (nil != self.detailsLabelText) { |
1513 | - // Get size of label text |
1514 | - dims = [self.detailsLabelText sizeWithFont:self.detailsLabelFont]; |
1515 | - |
1516 | - // Compute label dimensions based on font metrics if size is larger than max then clip the label width |
1517 | - lHeight = dims.height; |
1518 | - if (dims.width <= (frame.size.width - 2 * MARGIN)) { |
1519 | - lWidth = dims.width; |
1520 | - } |
1521 | - else { |
1522 | - lWidth = frame.size.width - 4 * MARGIN; |
1523 | - } |
1524 | - |
1525 | - // Set label properties |
1526 | - detailsLabel.font = self.detailsLabelFont; |
1527 | - detailsLabel.adjustsFontSizeToFitWidth = NO; |
1528 | - detailsLabel.textAlignment = UITextAlignmentCenter; |
1529 | - detailsLabel.opaque = NO; |
1530 | - detailsLabel.backgroundColor = [UIColor clearColor]; |
1531 | - detailsLabel.textColor = [UIColor whiteColor]; |
1532 | - detailsLabel.text = self.detailsLabelText; |
1533 | - |
1534 | - // Update HUD size |
1535 | - if (self.width < lWidth) { |
1536 | - self.width = lWidth + 2 * MARGIN; |
1537 | - } |
1538 | - self.height = self.height + lHeight + PADDING; |
1539 | - |
1540 | - // Move indicator to make room for the new label |
1541 | - indFrame.origin.y -= (floor(lHeight / 2 + PADDING / 2)); |
1542 | - indicator.frame = indFrame; |
1543 | - |
1544 | - // Move first label to make room for the new label |
1545 | - lFrame.origin.y -= (floor(lHeight / 2 + PADDING / 2)); |
1546 | - label.frame = lFrame; |
1547 | - |
1548 | - // Set label position and dimensions |
1549 | - CGRect lFrameD = CGRectMake(floor((frame.size.width - lWidth) / 2) + xOffset, |
1550 | - lFrame.origin.y + lFrame.size.height + PADDING, lWidth, lHeight); |
1551 | - detailsLabel.frame = lFrameD; |
1552 | - |
1553 | - [self addSubview:detailsLabel]; |
1554 | - } |
1555 | - } |
1556 | -} |
1557 | - |
1558 | -#pragma mark - |
1559 | -#pragma mark Showing and execution |
1560 | - |
1561 | -- (void)show:(BOOL)animated { |
1562 | - useAnimation = animated; |
1563 | - |
1564 | - // If the grace time is set postpone the HUD display |
1565 | - if (self.graceTime > 0.0) { |
1566 | - self.graceTimer = [NSTimer scheduledTimerWithTimeInterval:self.graceTime |
1567 | - target:self |
1568 | - selector:@selector(handleGraceTimer:) |
1569 | - userInfo:nil |
1570 | - repeats:NO]; |
1571 | - } |
1572 | - // ... otherwise show the HUD imediately |
1573 | - else { |
1574 | - [self setNeedsDisplay]; |
1575 | - [self showUsingAnimation:useAnimation]; |
1576 | - } |
1577 | -} |
1578 | - |
1579 | -- (void)hide:(BOOL)animated { |
1580 | - useAnimation = animated; |
1581 | - |
1582 | - // If the minShow time is set, calculate how long the hud was shown, |
1583 | - // and pospone the hiding operation if necessary |
1584 | - if (self.minShowTime > 0.0 && showStarted) { |
1585 | - NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:showStarted]; |
1586 | - if (interv < self.minShowTime) { |
1587 | - self.minShowTimer = [NSTimer scheduledTimerWithTimeInterval:(self.minShowTime - interv) |
1588 | - target:self |
1589 | - selector:@selector(handleMinShowTimer:) |
1590 | - userInfo:nil |
1591 | - repeats:NO]; |
1592 | - return; |
1593 | - } |
1594 | - } |
1595 | - |
1596 | - // ... otherwise hide the HUD immediately |
1597 | - [self hideUsingAnimation:useAnimation]; |
1598 | -} |
1599 | - |
1600 | -- (void)handleGraceTimer:(NSTimer *)theTimer { |
1601 | - // Show the HUD only if the task is still running |
1602 | - if (taskInProgress) { |
1603 | - [self setNeedsDisplay]; |
1604 | - [self showUsingAnimation:useAnimation]; |
1605 | - } |
1606 | -} |
1607 | - |
1608 | -- (void)handleMinShowTimer:(NSTimer *)theTimer { |
1609 | - [self hideUsingAnimation:useAnimation]; |
1610 | -} |
1611 | - |
1612 | -- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated { |
1613 | - |
1614 | - methodForExecution = method; |
1615 | - targetForExecution = [target retain]; |
1616 | - objectForExecution = [object retain]; |
1617 | - |
1618 | - // Launch execution in new thread |
1619 | - taskInProgress = YES; |
1620 | - [NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil]; |
1621 | - |
1622 | - // Show HUD view |
1623 | - [self show:animated]; |
1624 | -} |
1625 | - |
1626 | -- (void)launchExecution { |
1627 | - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
1628 | - |
1629 | - // Start executing the requested task |
1630 | - [targetForExecution performSelector:methodForExecution withObject:objectForExecution]; |
1631 | - |
1632 | - // Task completed, update view in main thread (note: view operations should |
1633 | - // be done only in the main thread) |
1634 | - [self performSelectorOnMainThread:@selector(cleanUp) withObject:nil waitUntilDone:NO]; |
1635 | - |
1636 | - [pool release]; |
1637 | -} |
1638 | - |
1639 | -- (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void*)context { |
1640 | - [self done]; |
1641 | -} |
1642 | - |
1643 | -- (void)done { |
1644 | - isFinished = YES; |
1645 | - |
1646 | - // If delegate was set make the callback |
1647 | - self.alpha = 0.0; |
1648 | - |
1649 | - if(delegate != nil && [delegate conformsToProtocol:@protocol(MBProgressHUDDelegate)]) { |
1650 | - if([delegate respondsToSelector:@selector(hudWasHidden)]) { |
1651 | - [delegate performSelector:@selector(hudWasHidden)]; |
1652 | - } |
1653 | - } |
1654 | -} |
1655 | - |
1656 | -- (void)cleanUp { |
1657 | - taskInProgress = NO; |
1658 | - |
1659 | - self.indicator = nil; |
1660 | - |
1661 | - [targetForExecution release]; |
1662 | - [objectForExecution release]; |
1663 | - |
1664 | - [self hide:useAnimation]; |
1665 | -} |
1666 | - |
1667 | -#pragma mark - |
1668 | -#pragma mark Fade in and Fade out |
1669 | - |
1670 | -- (void)showUsingAnimation:(BOOL)animated { |
1671 | - self.showStarted = [NSDate date]; |
1672 | - // Fade in |
1673 | - if (animated) { |
1674 | - [UIView beginAnimations:nil context:NULL]; |
1675 | - [UIView setAnimationDuration:0.40]; |
1676 | - self.alpha = 1.0; |
1677 | - [UIView commitAnimations]; |
1678 | - } |
1679 | - else { |
1680 | - self.alpha = 1.0; |
1681 | - } |
1682 | -} |
1683 | - |
1684 | -- (void)hideUsingAnimation:(BOOL)animated { |
1685 | - // Fade out |
1686 | - if (animated) { |
1687 | - [UIView beginAnimations:nil context:NULL]; |
1688 | - [UIView setAnimationDuration:0.40]; |
1689 | - [UIView setAnimationDelegate:self]; |
1690 | - [UIView setAnimationDidStopSelector:@selector(animationFinished: finished: context:)]; |
1691 | - // 0.02 prevents the hud from passing through touches during the animation the hud will get completely hidden |
1692 | - // in the done method |
1693 | - self.alpha = 0.02; |
1694 | - [UIView commitAnimations]; |
1695 | - } |
1696 | - else { |
1697 | - self.alpha = 0.0; |
1698 | - [self done]; |
1699 | - } |
1700 | -} |
1701 | - |
1702 | -#pragma mark BG Drawing |
1703 | - |
1704 | -- (void)drawRect:(CGRect)rect { |
1705 | - // Center HUD |
1706 | - CGRect allRect = self.bounds; |
1707 | - // Draw rounded HUD bacgroud rect |
1708 | - CGRect boxRect = CGRectMake(((allRect.size.width - self.width) / 2) + self.xOffset, |
1709 | - ((allRect.size.height - self.height) / 2) + self.yOffset, self.width, self.height); |
1710 | - CGContextRef ctxt = UIGraphicsGetCurrentContext(); |
1711 | - [self fillRoundedRect:boxRect inContext:ctxt]; |
1712 | -} |
1713 | - |
1714 | -- (void)fillRoundedRect:(CGRect)rect inContext:(CGContextRef)context { |
1715 | - float radius = 10.0f; |
1716 | - |
1717 | - CGContextBeginPath(context); |
1718 | - CGContextSetGrayFillColor(context, 0.0, self.opacity); |
1719 | - CGContextMoveToPoint(context, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect)); |
1720 | - CGContextAddArc(context, CGRectGetMaxX(rect) - radius, CGRectGetMinY(rect) + radius, radius, 3 * M_PI / 2, 0, 0); |
1721 | - CGContextAddArc(context, CGRectGetMaxX(rect) - radius, CGRectGetMaxY(rect) - radius, radius, 0, M_PI / 2, 0); |
1722 | - CGContextAddArc(context, CGRectGetMinX(rect) + radius, CGRectGetMaxY(rect) - radius, radius, M_PI / 2, M_PI, 0); |
1723 | - CGContextAddArc(context, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect) + radius, radius, M_PI, 3 * M_PI / 2, 0); |
1724 | - CGContextClosePath(context); |
1725 | - CGContextFillPath(context); |
1726 | -} |
1727 | - |
1728 | -@end |
1729 | - |
1730 | - |
1731 | -@implementation MBRoundProgressView |
1732 | - |
1733 | -- (id)initWithDefaultSize { |
1734 | - return [super initWithFrame:CGRectMake(0.0f, 0.0f, 37.0f, 37.0f)]; |
1735 | -} |
1736 | - |
1737 | -- (void)drawRect:(CGRect)rect { |
1738 | - CGRect allRect = self.bounds; |
1739 | - CGRect circleRect = CGRectMake(allRect.origin.x + 2, allRect.origin.y + 2, allRect.size.width - 4, |
1740 | - allRect.size.height - 4); |
1741 | - |
1742 | - CGContextRef context = UIGraphicsGetCurrentContext(); |
1743 | - |
1744 | - // Draw background |
1745 | - CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); // white |
1746 | - CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.1); // translucent white |
1747 | - CGContextSetLineWidth(context, 2.0); |
1748 | - CGContextFillEllipseInRect(context, circleRect); |
1749 | - CGContextStrokeEllipseInRect(context, circleRect); |
1750 | - |
1751 | - // Draw progress |
1752 | - float x = (allRect.size.width / 2); |
1753 | - float y = (allRect.size.height / 2); |
1754 | - CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); // white |
1755 | - CGContextMoveToPoint(context, x, y); |
1756 | - CGContextAddArc(context, x, y, (allRect.size.width - 4) / 2, -(PI / 2), (self.progress * 2 * PI) - PI / 2, 0); |
1757 | - CGContextClosePath(context); |
1758 | - CGContextFillPath(context); |
1759 | -} |
1760 | - |
1761 | -@end |
1762 | |
1763 | === added file 'musicstreaming/controls/RIButtonItem.h' |
1764 | --- musicstreaming/controls/RIButtonItem.h 1970-01-01 00:00:00 +0000 |
1765 | +++ musicstreaming/controls/RIButtonItem.h 2011-06-13 16:58:33 +0000 |
1766 | @@ -0,0 +1,23 @@ |
1767 | +// |
1768 | +// RIButtonItem.h |
1769 | +// Shibui |
1770 | +// |
1771 | +// Created by Jiva DeVoe on 1/12/11. |
1772 | +// Copyright 2011 Random Ideas, LLC. All rights reserved. |
1773 | +// |
1774 | + |
1775 | +#import <Foundation/Foundation.h> |
1776 | + |
1777 | +typedef void (^RISimpleAction)(); |
1778 | + |
1779 | +@interface RIButtonItem : NSObject |
1780 | +{ |
1781 | + NSString *label; |
1782 | + RISimpleAction action; |
1783 | +} |
1784 | +@property (retain, nonatomic) NSString *label; |
1785 | +@property (copy, nonatomic) RISimpleAction action; |
1786 | ++(id)item; |
1787 | ++(id)itemWithLabel:(NSString *)inLabel; |
1788 | +@end |
1789 | + |
1790 | |
1791 | === added file 'musicstreaming/controls/RIButtonItem.m' |
1792 | --- musicstreaming/controls/RIButtonItem.m 1970-01-01 00:00:00 +0000 |
1793 | +++ musicstreaming/controls/RIButtonItem.m 2011-06-13 16:58:33 +0000 |
1794 | @@ -0,0 +1,28 @@ |
1795 | +// |
1796 | +// RIButtonItem.m |
1797 | +// Shibui |
1798 | +// |
1799 | +// Created by Jiva DeVoe on 1/12/11. |
1800 | +// Copyright 2011 Random Ideas, LLC. All rights reserved. |
1801 | +// |
1802 | + |
1803 | +#import "RIButtonItem.h" |
1804 | + |
1805 | +@implementation RIButtonItem |
1806 | +@synthesize label; |
1807 | +@synthesize action; |
1808 | + |
1809 | ++(id)item |
1810 | +{ |
1811 | + return [[self new] autorelease]; |
1812 | +} |
1813 | + |
1814 | ++(id)itemWithLabel:(NSString *)inLabel |
1815 | +{ |
1816 | + id newItem = [self item]; |
1817 | + [newItem setLabel:inLabel]; |
1818 | + return newItem; |
1819 | +} |
1820 | + |
1821 | +@end |
1822 | + |
1823 | |
1824 | === modified file 'musicstreaming/controls/SongUITableViewCell.h' |
1825 | --- musicstreaming/controls/SongUITableViewCell.h 2010-09-30 00:08:28 +0000 |
1826 | +++ musicstreaming/controls/SongUITableViewCell.h 2011-06-13 16:58:33 +0000 |
1827 | @@ -31,6 +31,8 @@ |
1828 | #import <UIKit/UIKit.h> |
1829 | |
1830 | @interface SongUITableViewCell : UITableViewCell { |
1831 | + UIButton *cacheButton; |
1832 | + UIActivityIndicatorView *spinner; |
1833 | UILabel *songNameLabel; |
1834 | BOOL evenRow; |
1835 | UIView *coloredView; |
1836 | @@ -38,6 +40,8 @@ |
1837 | UILabel *durationLabel; |
1838 | UIImageView *nowPlaying; |
1839 | } |
1840 | +@property(nonatomic,retain) UIButton *cacheButton; |
1841 | +@property(nonatomic,retain) UIActivityIndicatorView *spinner; |
1842 | @property(nonatomic,assign) BOOL evenRow; |
1843 | @property(nonatomic,retain) UIImageView *nowPlaying; |
1844 | @property(nonatomic,retain) UILabel *songNameLabel; |
1845 | |
1846 | === modified file 'musicstreaming/controls/SongUITableViewCell.m' |
1847 | --- musicstreaming/controls/SongUITableViewCell.m 2011-04-14 04:24:43 +0000 |
1848 | +++ musicstreaming/controls/SongUITableViewCell.m 2011-06-13 16:58:33 +0000 |
1849 | @@ -34,7 +34,7 @@ |
1850 | |
1851 | @implementation SongUITableViewCell |
1852 | |
1853 | -@synthesize songNameLabel, positionLabel, durationLabel, nowPlaying, evenRow; |
1854 | +@synthesize cacheButton, spinner, songNameLabel, positionLabel, durationLabel, nowPlaying, evenRow; |
1855 | |
1856 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier |
1857 | { |
1858 | @@ -44,10 +44,18 @@ |
1859 | |
1860 | coloredView = [[UIView alloc] initWithFrame:self.frame]; |
1861 | coloredView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; |
1862 | - |
1863 | [self.contentView addSubview:coloredView]; |
1864 | + |
1865 | + // XXX: This is added first so that it sits behind the cacheButton. This isn't optimal. Something better would be to delegate taps on the spinner to the cacheButton, regardless of its front-to-back ordering in the subviews. |
1866 | + spinner = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] retain]; |
1867 | + spinner.hidesWhenStopped = YES; |
1868 | + [coloredView addSubview:spinner]; |
1869 | |
1870 | - songNameLabel = [[UILabel alloc] init]; |
1871 | + cacheButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; |
1872 | + [cacheButton setImage:[UIImage imageNamed:@"uncached"] forState:UIControlStateNormal]; |
1873 | + [coloredView addSubview:self.cacheButton]; |
1874 | + |
1875 | + songNameLabel = [[UILabel alloc] init]; |
1876 | songNameLabel.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]]; |
1877 | [coloredView addSubview:self.songNameLabel]; |
1878 | |
1879 | @@ -64,7 +72,7 @@ |
1880 | [coloredView addSubview:durationLabel]; |
1881 | |
1882 | nowPlaying = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 13, 12)]; |
1883 | - nowPlaying.image = [UIImage imageNamed:@"speaker.png"]; |
1884 | + nowPlaying.image = [UIImage imageNamed:@"speaker"]; |
1885 | nowPlaying.backgroundColor = [UIColor clearColor]; |
1886 | nowPlaying.contentMode = UIViewContentModeCenter; |
1887 | [coloredView addSubview:nowPlaying]; |
1888 | @@ -79,10 +87,12 @@ |
1889 | { |
1890 | [super layoutSubviews]; |
1891 | self.positionLabel.frame = CGRectMake(0, 0, 35, self.frame.size.height); |
1892 | - self.songNameLabel.frame = CGRectMake(47, 0, 197, self.frame.size.height); |
1893 | - self.nowPlaying.frame = CGRectMake(252, 0, 13, self.frame.size.height); |
1894 | - self.durationLabel.frame = CGRectMake(272, 0, 48, self.frame.size.height); |
1895 | - |
1896 | + self.songNameLabel.frame = CGRectMake(37, 0, 164, self.frame.size.height); |
1897 | + self.nowPlaying.frame = CGRectMake(203, 0, 13, self.frame.size.height); |
1898 | + self.durationLabel.frame = CGRectMake(218, 0, 48, self.frame.size.height); |
1899 | + self.cacheButton.frame = CGRectMake(268, 0, 44, self.frame.size.height); |
1900 | + self.spinner.frame = CGRectMake(282, 14, 16, 16); |
1901 | + |
1902 | if (self.evenRow) |
1903 | { |
1904 | coloredView.backgroundColor = [UIColor whiteColor]; |
1905 | @@ -103,6 +113,8 @@ |
1906 | |
1907 | - (void)dealloc |
1908 | { |
1909 | + [cacheButton release]; |
1910 | + [spinner release]; |
1911 | [durationLabel release]; |
1912 | [songNameLabel release]; |
1913 | [positionLabel release]; |
1914 | |
1915 | === modified file 'musicstreaming/iSub-Info.plist' |
1916 | --- musicstreaming/iSub-Info.plist 2010-10-01 04:00:55 +0000 |
1917 | +++ musicstreaming/iSub-Info.plist 2011-06-13 16:58:33 +0000 |
1918 | @@ -6,6 +6,8 @@ |
1919 | <string>English</string> |
1920 | <key>CFBundleDisplayName</key> |
1921 | <string>${PRODUCT_NAME}</string> |
1922 | + <key>CFBundleDocumentTypes</key> |
1923 | + <array/> |
1924 | <key>CFBundleExecutable</key> |
1925 | <string>${EXECUTABLE_NAME}</string> |
1926 | <key>CFBundleIconFile</key> |
1927 | @@ -23,6 +25,8 @@ |
1928 | <string>${PRODUCT_NAME}</string> |
1929 | <key>CFBundlePackageType</key> |
1930 | <string>APPL</string> |
1931 | + <key>CFBundleShortVersionString</key> |
1932 | + <string>2.0</string> |
1933 | <key>CFBundleSignature</key> |
1934 | <string>UOMS</string> |
1935 | <key>CFBundleURLTypes</key> |
1936 | @@ -37,7 +41,7 @@ |
1937 | </dict> |
1938 | </array> |
1939 | <key>CFBundleVersion</key> |
1940 | - <string>1.0</string> |
1941 | + <string>6</string> |
1942 | <key>LSRequiresIPhoneOS</key> |
1943 | <false/> |
1944 | <key>NSMainNibFile</key> |
1945 | @@ -50,5 +54,9 @@ |
1946 | <false/> |
1947 | <key>UIStatusBarStyle</key> |
1948 | <string>UIStatusBarStyleBlackOpaque</string> |
1949 | + <key>UTExportedTypeDeclarations</key> |
1950 | + <array/> |
1951 | + <key>UTImportedTypeDeclarations</key> |
1952 | + <array/> |
1953 | </dict> |
1954 | </plist> |
1955 | |
1956 | === modified file 'musicstreaming/iSub.xcodeproj/project.pbxproj' (properties changed: +x to -x) |
1957 | --- musicstreaming/iSub.xcodeproj/project.pbxproj 2011-05-05 06:54:40 +0000 |
1958 | +++ musicstreaming/iSub.xcodeproj/project.pbxproj 2011-06-13 16:58:33 +0000 |
1959 | @@ -31,6 +31,16 @@ |
1960 | 9110DC41134E4EEF0046B8E4 /* NSMutableSet+Extras.m in Sources */ = {isa = PBXBuildFile; fileRef = 9110DC40134E4EEF0046B8E4 /* NSMutableSet+Extras.m */; }; |
1961 | 9110DC44134EAC740046B8E4 /* AlbumListParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 9110DC43134EAC730046B8E4 /* AlbumListParser.m */; }; |
1962 | 9110DC571354A7490046B8E4 /* AlbumArtistUITableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9110DC561354A7470046B8E4 /* AlbumArtistUITableViewCell.m */; }; |
1963 | + 9112B0241383FF27003C1D93 /* albums.png in Resources */ = {isa = PBXBuildFile; fileRef = 9112B01E1383FF27003C1D93 /* albums.png */; }; |
1964 | + 9112B0251383FF27003C1D93 /* artists.png in Resources */ = {isa = PBXBuildFile; fileRef = 9112B01F1383FF27003C1D93 /* artists.png */; }; |
1965 | + 9112B0261383FF27003C1D93 /* playlists.png in Resources */ = {isa = PBXBuildFile; fileRef = 9112B0201383FF27003C1D93 /* playlists.png */; }; |
1966 | + 9112B0281383FF27003C1D93 /* settings.png in Resources */ = {isa = PBXBuildFile; fileRef = 9112B0221383FF27003C1D93 /* settings.png */; }; |
1967 | + 9112B0291383FF27003C1D93 /* songs.png in Resources */ = {isa = PBXBuildFile; fileRef = 9112B0231383FF27003C1D93 /* songs.png */; }; |
1968 | + 9112B02F1383FF37003C1D93 /* albums@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9112B02A1383FF37003C1D93 /* albums@2x.png */; }; |
1969 | + 9112B0301383FF37003C1D93 /* artists@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9112B02B1383FF37003C1D93 /* artists@2x.png */; }; |
1970 | + 9112B0311383FF37003C1D93 /* playlists@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9112B02C1383FF37003C1D93 /* playlists@2x.png */; }; |
1971 | + 9112B0321383FF37003C1D93 /* settings@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9112B02D1383FF37003C1D93 /* settings@2x.png */; }; |
1972 | + 9112B0331383FF37003C1D93 /* songs@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9112B02E1383FF37003C1D93 /* songs@2x.png */; }; |
1973 | 9123D1A113257ADF00B40210 /* PlaylistListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9123D1A013257ADF00B40210 /* PlaylistListViewController.m */; }; |
1974 | 9123D1BB13280B3400B40210 /* PlaylistViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9123D1BA13280B3400B40210 /* PlaylistViewController.m */; }; |
1975 | 9123D1C3132816D200B40210 /* PlaylistListParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 9123D1C2132816D200B40210 /* PlaylistListParser.m */; }; |
1976 | @@ -39,8 +49,18 @@ |
1977 | 912D1267134B609700721EE4 /* PlaylistEditViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 912D1266134B609600721EE4 /* PlaylistEditViewController.m */; }; |
1978 | 912D392213311F2700A443B2 /* AlbumListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 912D392113311F2500A443B2 /* AlbumListViewController.m */; }; |
1979 | 912D392613311FC600A443B2 /* SongListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 912D392513311FC400A443B2 /* SongListViewController.m */; }; |
1980 | + 91406E9413849F2400A7DA67 /* cached.png in Resources */ = {isa = PBXBuildFile; fileRef = 91406E8E13849F2400A7DA67 /* cached.png */; }; |
1981 | + 91406E9513849F2400A7DA67 /* cached@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 91406E8F13849F2400A7DA67 /* cached@2x.png */; }; |
1982 | + 91406E9613849F2400A7DA67 /* partiallycached.png in Resources */ = {isa = PBXBuildFile; fileRef = 91406E9013849F2400A7DA67 /* partiallycached.png */; }; |
1983 | + 91406E9713849F2400A7DA67 /* partiallycached@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 91406E9113849F2400A7DA67 /* partiallycached@2x.png */; }; |
1984 | + 91406E9813849F2400A7DA67 /* uncached.png in Resources */ = {isa = PBXBuildFile; fileRef = 91406E9213849F2400A7DA67 /* uncached.png */; }; |
1985 | + 91406E9913849F2400A7DA67 /* uncached@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 91406E9313849F2400A7DA67 /* uncached@2x.png */; }; |
1986 | + 91406EEA138AEEE000A7DA67 /* NSString+Extras.m in Sources */ = {isa = PBXBuildFile; fileRef = 91406EE9138AEEE000A7DA67 /* NSString+Extras.m */; }; |
1987 | 919376F3135CC1CF0030B7BD /* PlaylistEditSongUITableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 919376F2135CC1CF0030B7BD /* PlaylistEditSongUITableViewCell.m */; }; |
1988 | 91B3A4441344CF92006C8193 /* SubsonicIndexedTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91B3A4431344CF91006C8193 /* SubsonicIndexedTableViewController.m */; }; |
1989 | + 91BE4018138E8D2300D44D68 /* UIActionSheet+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = 91BE4015138E8D2300D44D68 /* UIActionSheet+Blocks.m */; }; |
1990 | + 91BE4019138E8D2300D44D68 /* UIAlertView+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = 91BE4017138E8D2300D44D68 /* UIAlertView+Blocks.m */; }; |
1991 | + 91BE401C138E8D3A00D44D68 /* RIButtonItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 91BE401B138E8D3A00D44D68 /* RIButtonItem.m */; }; |
1992 | 91E88609132DA82000618994 /* PlaylistParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 91E88608132DA82000618994 /* PlaylistParser.m */; }; |
1993 | 9316628812264A74003B0EB7 /* NSDate+Extras.m in Sources */ = {isa = PBXBuildFile; fileRef = 9316628712264A74003B0EB7 /* NSDate+Extras.m */; }; |
1994 | 932E7A6E1254747E00E7C8FF /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 932E7A6D1254747E00E7C8FF /* Default@2x.png */; }; |
1995 | @@ -49,14 +69,18 @@ |
1996 | 932E7B0912552CB400E7C8FF /* PullRefreshTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 932E7B0812552CB400E7C8FF /* PullRefreshTableViewController.m */; }; |
1997 | 932E7B0B12552CD500E7C8FF /* arrow.png in Resources */ = {isa = PBXBuildFile; fileRef = 932E7B0A12552CD500E7C8FF /* arrow.png */; }; |
1998 | 9354D0AB1248267B00733067 /* NSDictionary+Extras.m in Sources */ = {isa = PBXBuildFile; fileRef = 9354D0AA1248267B00733067 /* NSDictionary+Extras.m */; }; |
1999 | - 936F1F3112271B6500070F43 /* MBProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 936F1F3012271B6500070F43 /* MBProgressHUD.m */; }; |
2000 | 936F20681227364200070F43 /* Playlist.m in Sources */ = {isa = PBXBuildFile; fileRef = 936F20671227364200070F43 /* Playlist.m */; }; |
2001 | 936F209012273D9000070F43 /* Song.m in Sources */ = {isa = PBXBuildFile; fileRef = 936F208F12273D9000070F43 /* Song.m */; }; |
2002 | 936F230A12284D1900070F43 /* NamedTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 936F230912284D1900070F43 /* NamedTextFieldCell.m */; }; |
2003 | + 937FAA11137CFC1B00507E51 /* AlbumArtLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 937FAA0E137CFC1B00507E51 /* AlbumArtLoader.m */; }; |
2004 | + 937FAA12137CFC1B00507E51 /* AlbumArtLoadingOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 937FAA10137CFC1B00507E51 /* AlbumArtLoadingOperation.m */; }; |
2005 | + 937FAA15137CFC5000507E51 /* Downloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 937FAA14137CFC5000507E51 /* Downloader.m */; }; |
2006 | + 937FAA18137CFC7200507E51 /* DownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 937FAA17137CFC7200507E51 /* DownloadOperation.m */; }; |
2007 | + 937FAA1B137CFCA600507E51 /* AbstractNetworkOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 937FAA1A137CFCA600507E51 /* AbstractNetworkOperation.m */; }; |
2008 | + 937FAAEF137D15E800507E51 /* Globals.m in Sources */ = {isa = PBXBuildFile; fileRef = 937FAAEE137D15E800507E51 /* Globals.m */; }; |
2009 | 93A54024123188880048BC3D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93A54023123188880048BC3D /* Security.framework */; }; |
2010 | 93BC5209124C181600B7587C /* Subsonic.m in Sources */ = {isa = PBXBuildFile; fileRef = 93BC5208124C181600B7587C /* Subsonic.m */; }; |
2011 | 93BC52A7124C1E6900B7587C /* StreamingPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 93BC52A6124C1E6900B7587C /* StreamingPlayer.m */; }; |
2012 | - 93BC53FB124C7C8D00B7587C /* DataCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 93BC53FA124C7C8D00B7587C /* DataCache.m */; }; |
2013 | 93CCBD4F1254039900AFFC22 /* speaker.png in Resources */ = {isa = PBXBuildFile; fileRef = 93CCBD4D1254039900AFFC22 /* speaker.png */; }; |
2014 | 93CCBD501254039900AFFC22 /* speaker@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93CCBD4E1254039900AFFC22 /* speaker@2x.png */; }; |
2015 | 93CCBD7D12540CB700AFFC22 /* AboutViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93CCBD7B12540CB700AFFC22 /* AboutViewController.m */; }; |
2016 | @@ -81,16 +105,12 @@ |
2017 | 93DFFE45135D71030061F29F /* MOC.m in Sources */ = {isa = PBXBuildFile; fileRef = 93DFFE44135D71030061F29F /* MOC.m */; }; |
2018 | 93DFFE4D135D71760061F29F /* music.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 93DFFE4C135D71760061F29F /* music.xcdatamodeld */; }; |
2019 | 93DFFE54135D72420061F29F /* NSManagedObjectContext+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 93DFFE53135D72420061F29F /* NSManagedObjectContext+Additions.m */; }; |
2020 | - 93ED1AD8137276810058FC98 /* ImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 93ED1AD7137276810058FC98 /* ImageLoader.m */; }; |
2021 | - 93ED1ADF137279A30058FC98 /* ImageLoadingOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 93ED1ADE137279A30058FC98 /* ImageLoadingOperation.m */; }; |
2022 | 93EE2AF0124993F100E7E060 /* ArtistListParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 93EE2AEF124993F100E7E060 /* ArtistListParser.m */; }; |
2023 | 93EE2BA31249F33D00E7E060 /* ArtistParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 93EE2BA21249F33D00E7E060 /* ArtistParser.m */; }; |
2024 | 93F334471247F9DE006C6707 /* SFHFKeychainUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F334461247F9DE006C6707 /* SFHFKeychainUtils.m */; }; |
2025 | 93F3344D1247FA0B006C6707 /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F3344C1247FA0B006C6707 /* Reachability.m */; }; |
2026 | 93F334521247FA2C006C6707 /* Album.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F3344F1247FA2C006C6707 /* Album.m */; }; |
2027 | 93F334531247FA2C006C6707 /* Artist.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F334511247FA2C006C6707 /* Artist.m */; }; |
2028 | - 93F334561247FA52006C6707 /* AsynchronousImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F334551247FA52006C6707 /* AsynchronousImageView.m */; }; |
2029 | - 93F334591247FA68006C6707 /* AsynchronousImageViewCached.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F334581247FA68006C6707 /* AsynchronousImageViewCached.m */; }; |
2030 | 93F3345C1247FA85006C6707 /* AlbumUITableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F3345B1247FA85006C6707 /* AlbumUITableViewCell.m */; }; |
2031 | 93F3345F1247FA97006C6707 /* SongUITableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93F3345E1247FA97006C6707 /* SongUITableViewCell.m */; }; |
2032 | 93F334681247FB02006C6707 /* SongViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93F334641247FB02006C6707 /* SongViewController.xib */; }; |
2033 | @@ -110,7 +130,6 @@ |
2034 | 93FA42B0124DC1350080DF62 /* 05-shuffle.png in Resources */ = {isa = PBXBuildFile; fileRef = 93FA42A9124DC1350080DF62 /* 05-shuffle.png */; }; |
2035 | 93FA42B1124DC1350080DF62 /* 05-shuffle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93FA42AA124DC1350080DF62 /* 05-shuffle@2x.png */; }; |
2036 | 93FA42B2124DC1350080DF62 /* background.png in Resources */ = {isa = PBXBuildFile; fileRef = 93FA42AB124DC1350080DF62 /* background.png */; }; |
2037 | - 93FA42B3124DC1350080DF62 /* default-album-art-small.png in Resources */ = {isa = PBXBuildFile; fileRef = 93FA42AC124DC1350080DF62 /* default-album-art-small.png */; }; |
2038 | 93FA42B4124DC1350080DF62 /* default-album-art.png in Resources */ = {isa = PBXBuildFile; fileRef = 93FA42AD124DC1350080DF62 /* default-album-art.png */; }; |
2039 | 93FA4336124DE0D80080DF62 /* player_back.png in Resources */ = {isa = PBXBuildFile; fileRef = 93FA4334124DE0D80080DF62 /* player_back.png */; }; |
2040 | 93FA4337124DE0D80080DF62 /* player_back@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93FA4335124DE0D80080DF62 /* player_back@2x.png */; }; |
2041 | @@ -160,6 +179,16 @@ |
2042 | 9110DC43134EAC730046B8E4 /* AlbumListParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlbumListParser.m; sourceTree = "<group>"; }; |
2043 | 9110DC551354A7460046B8E4 /* AlbumArtistUITableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = AlbumArtistUITableViewCell.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; |
2044 | 9110DC561354A7470046B8E4 /* AlbumArtistUITableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AlbumArtistUITableViewCell.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; |
2045 | + 9112B01E1383FF27003C1D93 /* albums.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = albums.png; sourceTree = "<group>"; }; |
2046 | + 9112B01F1383FF27003C1D93 /* artists.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = artists.png; sourceTree = "<group>"; }; |
2047 | + 9112B0201383FF27003C1D93 /* playlists.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = playlists.png; sourceTree = "<group>"; }; |
2048 | + 9112B0221383FF27003C1D93 /* settings.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = settings.png; sourceTree = "<group>"; }; |
2049 | + 9112B0231383FF27003C1D93 /* songs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = songs.png; sourceTree = "<group>"; }; |
2050 | + 9112B02A1383FF37003C1D93 /* albums@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "albums@2x.png"; sourceTree = "<group>"; }; |
2051 | + 9112B02B1383FF37003C1D93 /* artists@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "artists@2x.png"; sourceTree = "<group>"; }; |
2052 | + 9112B02C1383FF37003C1D93 /* playlists@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "playlists@2x.png"; sourceTree = "<group>"; }; |
2053 | + 9112B02D1383FF37003C1D93 /* settings@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "settings@2x.png"; sourceTree = "<group>"; }; |
2054 | + 9112B02E1383FF37003C1D93 /* songs@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "songs@2x.png"; sourceTree = "<group>"; }; |
2055 | 9123D19F13257ADF00B40210 /* PlaylistListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaylistListViewController.h; sourceTree = "<group>"; }; |
2056 | 9123D1A013257ADF00B40210 /* PlaylistListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = PlaylistListViewController.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; |
2057 | 9123D1B913280B3400B40210 /* PlaylistViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistViewController.h; path = view_controllers/PlaylistViewController.h; sourceTree = "<group>"; }; |
2058 | @@ -176,10 +205,24 @@ |
2059 | 912D392113311F2500A443B2 /* AlbumListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AlbumListViewController.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; |
2060 | 912D392413311FC400A443B2 /* SongListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SongListViewController.h; sourceTree = "<group>"; }; |
2061 | 912D392513311FC400A443B2 /* SongListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SongListViewController.m; sourceTree = "<group>"; }; |
2062 | + 91406E8E13849F2400A7DA67 /* cached.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cached.png; sourceTree = "<group>"; }; |
2063 | + 91406E8F13849F2400A7DA67 /* cached@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "cached@2x.png"; sourceTree = "<group>"; }; |
2064 | + 91406E9013849F2400A7DA67 /* partiallycached.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = partiallycached.png; sourceTree = "<group>"; }; |
2065 | + 91406E9113849F2400A7DA67 /* partiallycached@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "partiallycached@2x.png"; sourceTree = "<group>"; }; |
2066 | + 91406E9213849F2400A7DA67 /* uncached.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = uncached.png; sourceTree = "<group>"; }; |
2067 | + 91406E9313849F2400A7DA67 /* uncached@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "uncached@2x.png"; sourceTree = "<group>"; }; |
2068 | + 91406EE8138AEEE000A7DA67 /* NSString+Extras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Extras.h"; sourceTree = "<group>"; }; |
2069 | + 91406EE9138AEEE000A7DA67 /* NSString+Extras.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Extras.m"; sourceTree = "<group>"; }; |
2070 | 919376F1135CC1CF0030B7BD /* PlaylistEditSongUITableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaylistEditSongUITableViewCell.h; sourceTree = "<group>"; }; |
2071 | 919376F2135CC1CF0030B7BD /* PlaylistEditSongUITableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlaylistEditSongUITableViewCell.m; sourceTree = "<group>"; }; |
2072 | 91B3A4421344CF90006C8193 /* SubsonicIndexedTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubsonicIndexedTableViewController.h; sourceTree = "<group>"; }; |
2073 | 91B3A4431344CF91006C8193 /* SubsonicIndexedTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SubsonicIndexedTableViewController.m; sourceTree = "<group>"; }; |
2074 | + 91BE4014138E8D2300D44D68 /* UIActionSheet+Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIActionSheet+Blocks.h"; sourceTree = "<group>"; }; |
2075 | + 91BE4015138E8D2300D44D68 /* UIActionSheet+Blocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIActionSheet+Blocks.m"; sourceTree = "<group>"; }; |
2076 | + 91BE4016138E8D2300D44D68 /* UIAlertView+Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertView+Blocks.h"; sourceTree = "<group>"; }; |
2077 | + 91BE4017138E8D2300D44D68 /* UIAlertView+Blocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertView+Blocks.m"; sourceTree = "<group>"; }; |
2078 | + 91BE401A138E8D3A00D44D68 /* RIButtonItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RIButtonItem.h; sourceTree = "<group>"; }; |
2079 | + 91BE401B138E8D3A00D44D68 /* RIButtonItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RIButtonItem.m; sourceTree = "<group>"; }; |
2080 | 91E88607132DA82000618994 /* PlaylistParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaylistParser.h; sourceTree = "<group>"; }; |
2081 | 91E88608132DA82000618994 /* PlaylistParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlaylistParser.m; sourceTree = "<group>"; }; |
2082 | 9316628612264A74003B0EB7 /* NSDate+Extras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+Extras.h"; sourceTree = "<group>"; }; |
2083 | @@ -193,22 +236,30 @@ |
2084 | 9354D0A91248267B00733067 /* NSDictionary+Extras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Extras.h"; sourceTree = "<group>"; }; |
2085 | 9354D0AA1248267B00733067 /* NSDictionary+Extras.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Extras.m"; sourceTree = "<group>"; }; |
2086 | 935FCC42123766E600B5DF9B /* Entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Entitlements.plist; sourceTree = "<group>"; }; |
2087 | - 936F1F2F12271B6500070F43 /* MBProgressHUD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBProgressHUD.h; sourceTree = "<group>"; }; |
2088 | - 936F1F3012271B6500070F43 /* MBProgressHUD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBProgressHUD.m; sourceTree = "<group>"; }; |
2089 | 936F20661227364200070F43 /* Playlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Playlist.h; sourceTree = "<group>"; }; |
2090 | 936F20671227364200070F43 /* Playlist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Playlist.m; sourceTree = "<group>"; }; |
2091 | 936F208E12273D9000070F43 /* Song.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Song.h; sourceTree = "<group>"; }; |
2092 | 936F208F12273D9000070F43 /* Song.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Song.m; sourceTree = "<group>"; }; |
2093 | 936F230812284D1900070F43 /* NamedTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NamedTextFieldCell.h; sourceTree = "<group>"; }; |
2094 | 936F230912284D1900070F43 /* NamedTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NamedTextFieldCell.m; sourceTree = "<group>"; }; |
2095 | + 937FAA0D137CFC1B00507E51 /* AlbumArtLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlbumArtLoader.h; sourceTree = "<group>"; }; |
2096 | + 937FAA0E137CFC1B00507E51 /* AlbumArtLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlbumArtLoader.m; sourceTree = "<group>"; }; |
2097 | + 937FAA0F137CFC1B00507E51 /* AlbumArtLoadingOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlbumArtLoadingOperation.h; sourceTree = "<group>"; }; |
2098 | + 937FAA10137CFC1B00507E51 /* AlbumArtLoadingOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlbumArtLoadingOperation.m; sourceTree = "<group>"; }; |
2099 | + 937FAA13137CFC5000507E51 /* Downloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Downloader.h; sourceTree = "<group>"; }; |
2100 | + 937FAA14137CFC5000507E51 /* Downloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Downloader.m; sourceTree = "<group>"; }; |
2101 | + 937FAA16137CFC7200507E51 /* DownloadOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DownloadOperation.h; sourceTree = "<group>"; }; |
2102 | + 937FAA17137CFC7200507E51 /* DownloadOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DownloadOperation.m; sourceTree = "<group>"; }; |
2103 | + 937FAA19137CFCA600507E51 /* AbstractNetworkOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractNetworkOperation.h; sourceTree = "<group>"; }; |
2104 | + 937FAA1A137CFCA600507E51 /* AbstractNetworkOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AbstractNetworkOperation.m; sourceTree = "<group>"; }; |
2105 | + 937FAAED137D15E800507E51 /* Globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Globals.h; sourceTree = "<group>"; }; |
2106 | + 937FAAEE137D15E800507E51 /* Globals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Globals.m; sourceTree = "<group>"; }; |
2107 | 93A54023123188880048BC3D /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; |
2108 | 93BC5207124C181600B7587C /* Subsonic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Subsonic.h; sourceTree = "<group>"; }; |
2109 | 93BC5208124C181600B7587C /* Subsonic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Subsonic.m; sourceTree = "<group>"; }; |
2110 | 93BC520A124C187700B7587C /* SynthesizeSingleton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SynthesizeSingleton.h; sourceTree = SOURCE_ROOT; }; |
2111 | 93BC52A5124C1E6900B7587C /* StreamingPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamingPlayer.h; sourceTree = "<group>"; }; |
2112 | 93BC52A6124C1E6900B7587C /* StreamingPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StreamingPlayer.m; sourceTree = "<group>"; }; |
2113 | - 93BC53F9124C7C8D00B7587C /* DataCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataCache.h; sourceTree = "<group>"; }; |
2114 | - 93BC53FA124C7C8D00B7587C /* DataCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataCache.m; sourceTree = "<group>"; }; |
2115 | 93CCBD4D1254039900AFFC22 /* speaker.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = speaker.png; sourceTree = "<group>"; }; |
2116 | 93CCBD4E1254039900AFFC22 /* speaker@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "speaker@2x.png"; sourceTree = "<group>"; }; |
2117 | 93CCBD7A12540CB700AFFC22 /* AboutViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AboutViewController.h; path = view_controllers/AboutViewController.h; sourceTree = "<group>"; }; |
2118 | @@ -242,10 +293,6 @@ |
2119 | 93DFFE48135D71550061F29F /* music.xcdatamodel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.xcdatamodel; path = music.xcdatamodel; sourceTree = "<group>"; }; |
2120 | 93DFFE52135D72420061F29F /* NSManagedObjectContext+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+Additions.h"; sourceTree = "<group>"; }; |
2121 | 93DFFE53135D72420061F29F /* NSManagedObjectContext+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+Additions.m"; sourceTree = "<group>"; }; |
2122 | - 93ED1AD6137276810058FC98 /* ImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageLoader.h; sourceTree = "<group>"; }; |
2123 | - 93ED1AD7137276810058FC98 /* ImageLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageLoader.m; sourceTree = "<group>"; }; |
2124 | - 93ED1ADD137279A30058FC98 /* ImageLoadingOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageLoadingOperation.h; sourceTree = "<group>"; }; |
2125 | - 93ED1ADE137279A30058FC98 /* ImageLoadingOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageLoadingOperation.m; sourceTree = "<group>"; }; |
2126 | 93EE2AEE124993F100E7E060 /* ArtistListParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArtistListParser.h; sourceTree = "<group>"; }; |
2127 | 93EE2AEF124993F100E7E060 /* ArtistListParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArtistListParser.m; sourceTree = "<group>"; }; |
2128 | 93EE2BA11249F33D00E7E060 /* ArtistParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArtistParser.h; sourceTree = "<group>"; }; |
2129 | @@ -258,10 +305,6 @@ |
2130 | 93F3344F1247FA2C006C6707 /* Album.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Album.m; sourceTree = "<group>"; }; |
2131 | 93F334501247FA2C006C6707 /* Artist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Artist.h; sourceTree = "<group>"; }; |
2132 | 93F334511247FA2C006C6707 /* Artist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Artist.m; sourceTree = "<group>"; }; |
2133 | - 93F334541247FA52006C6707 /* AsynchronousImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsynchronousImageView.h; sourceTree = "<group>"; }; |
2134 | - 93F334551247FA52006C6707 /* AsynchronousImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AsynchronousImageView.m; sourceTree = "<group>"; }; |
2135 | - 93F334571247FA68006C6707 /* AsynchronousImageViewCached.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = AsynchronousImageViewCached.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; |
2136 | - 93F334581247FA68006C6707 /* AsynchronousImageViewCached.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AsynchronousImageViewCached.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; |
2137 | 93F3345A1247FA85006C6707 /* AlbumUITableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = AlbumUITableViewCell.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; |
2138 | 93F3345B1247FA85006C6707 /* AlbumUITableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AlbumUITableViewCell.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; |
2139 | 93F3345D1247FA97006C6707 /* SongUITableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SongUITableViewCell.h; sourceTree = "<group>"; }; |
2140 | @@ -292,7 +335,6 @@ |
2141 | 93FA42A9124DC1350080DF62 /* 05-shuffle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "05-shuffle.png"; sourceTree = "<group>"; }; |
2142 | 93FA42AA124DC1350080DF62 /* 05-shuffle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "05-shuffle@2x.png"; sourceTree = "<group>"; }; |
2143 | 93FA42AB124DC1350080DF62 /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background.png; sourceTree = "<group>"; }; |
2144 | - 93FA42AC124DC1350080DF62 /* default-album-art-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "default-album-art-small.png"; sourceTree = "<group>"; }; |
2145 | 93FA42AD124DC1350080DF62 /* default-album-art.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "default-album-art.png"; sourceTree = "<group>"; }; |
2146 | 93FA4334124DE0D80080DF62 /* player_back.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = player_back.png; sourceTree = "<group>"; }; |
2147 | 93FA4335124DE0D80080DF62 /* player_back@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "player_back@2x.png"; sourceTree = "<group>"; }; |
2148 | @@ -358,12 +400,28 @@ |
2149 | 29B97317FDCFA39411CA2CEA /* Resources */ = { |
2150 | isa = PBXGroup; |
2151 | children = ( |
2152 | + 9112B01F1383FF27003C1D93 /* artists.png */, |
2153 | + 9112B02B1383FF37003C1D93 /* artists@2x.png */, |
2154 | + 9112B01E1383FF27003C1D93 /* albums.png */, |
2155 | + 9112B02A1383FF37003C1D93 /* albums@2x.png */, |
2156 | + 9112B0231383FF27003C1D93 /* songs.png */, |
2157 | + 9112B02E1383FF37003C1D93 /* songs@2x.png */, |
2158 | + 9112B0201383FF27003C1D93 /* playlists.png */, |
2159 | + 9112B02C1383FF37003C1D93 /* playlists@2x.png */, |
2160 | + 9112B0221383FF27003C1D93 /* settings.png */, |
2161 | + 9112B02D1383FF37003C1D93 /* settings@2x.png */, |
2162 | + 91406E8E13849F2400A7DA67 /* cached.png */, |
2163 | + 91406E8F13849F2400A7DA67 /* cached@2x.png */, |
2164 | + 91406E9013849F2400A7DA67 /* partiallycached.png */, |
2165 | + 91406E9113849F2400A7DA67 /* partiallycached@2x.png */, |
2166 | + 91406E9213849F2400A7DA67 /* uncached.png */, |
2167 | + 91406E9313849F2400A7DA67 /* uncached@2x.png */, |
2168 | + 5305C2051157F4F800BC78F0 /* Default.png */, |
2169 | 932E7A6D1254747E00E7C8FF /* Default@2x.png */, |
2170 | + 93D6B50B1252CA71007880B0 /* music_57.png */, |
2171 | 93D6B5141252CB34007880B0 /* music_57@2x.png */, |
2172 | 93D6B50A1252CA71007880B0 /* music_29.png */, |
2173 | - 93D6B50B1252CA71007880B0 /* music_57.png */, |
2174 | 93D6B50D1252CA71007880B0 /* music_512.png */, |
2175 | - 5305C2051157F4F800BC78F0 /* Default.png */, |
2176 | 53F0CD8111589F0A00A665CD /* progress-label-background.png */, |
2177 | 8D1107310486CEB800E47090 /* iSub-Info.plist */, |
2178 | 935FCC42123766E600B5DF9B /* Entitlements.plist */, |
2179 | @@ -466,6 +524,10 @@ |
2180 | 9316628512264A74003B0EB7 /* Categories */ = { |
2181 | isa = PBXGroup; |
2182 | children = ( |
2183 | + 91BE4014138E8D2300D44D68 /* UIActionSheet+Blocks.h */, |
2184 | + 91BE4015138E8D2300D44D68 /* UIActionSheet+Blocks.m */, |
2185 | + 91BE4016138E8D2300D44D68 /* UIAlertView+Blocks.h */, |
2186 | + 91BE4017138E8D2300D44D68 /* UIAlertView+Blocks.m */, |
2187 | 93DFFE52135D72420061F29F /* NSManagedObjectContext+Additions.h */, |
2188 | 93DFFE53135D72420061F29F /* NSManagedObjectContext+Additions.m */, |
2189 | 93D6B119124ED3B3007880B0 /* UIDevice+Hardware.h */, |
2190 | @@ -486,6 +548,8 @@ |
2191 | 91018B0D13573D150051EFDC /* UIImage+Alpha.m */, |
2192 | 91018B0F13573D350051EFDC /* UIImage+RoundedCorner.h */, |
2193 | 91018B1013573D350051EFDC /* UIImage+RoundedCorner.m */, |
2194 | + 91406EE8138AEEE000A7DA67 /* NSString+Extras.h */, |
2195 | + 91406EE9138AEEE000A7DA67 /* NSString+Extras.m */, |
2196 | ); |
2197 | name = Categories; |
2198 | path = categories; |
2199 | @@ -504,6 +568,8 @@ |
2200 | 936F1F2E12271B6500070F43 /* Controls */ = { |
2201 | isa = PBXGroup; |
2202 | children = ( |
2203 | + 91BE401A138E8D3A00D44D68 /* RIButtonItem.h */, |
2204 | + 91BE401B138E8D3A00D44D68 /* RIButtonItem.m */, |
2205 | 93F3345D1247FA97006C6707 /* SongUITableViewCell.h */, |
2206 | 93F3345E1247FA97006C6707 /* SongUITableViewCell.m */, |
2207 | 919376F1135CC1CF0030B7BD /* PlaylistEditSongUITableViewCell.h */, |
2208 | @@ -512,14 +578,8 @@ |
2209 | 93F3345B1247FA85006C6707 /* AlbumUITableViewCell.m */, |
2210 | 9110DC551354A7460046B8E4 /* AlbumArtistUITableViewCell.h */, |
2211 | 9110DC561354A7470046B8E4 /* AlbumArtistUITableViewCell.m */, |
2212 | - 93F334571247FA68006C6707 /* AsynchronousImageViewCached.h */, |
2213 | - 93F334581247FA68006C6707 /* AsynchronousImageViewCached.m */, |
2214 | - 93F334541247FA52006C6707 /* AsynchronousImageView.h */, |
2215 | - 93F334551247FA52006C6707 /* AsynchronousImageView.m */, |
2216 | 936F230812284D1900070F43 /* NamedTextFieldCell.h */, |
2217 | 936F230912284D1900070F43 /* NamedTextFieldCell.m */, |
2218 | - 936F1F2F12271B6500070F43 /* MBProgressHUD.h */, |
2219 | - 936F1F3012271B6500070F43 /* MBProgressHUD.m */, |
2220 | 912D1262134A162000721EE4 /* AlertPrompt.h */, |
2221 | 912D1263134A162000721EE4 /* AlertPrompt.m */, |
2222 | 93DF12D7136E968E00D6C085 /* MiniHudView.h */, |
2223 | @@ -547,9 +607,27 @@ |
2224 | path = models; |
2225 | sourceTree = "<group>"; |
2226 | }; |
2227 | + 937FAA0C137CFC1B00507E51 /* operations */ = { |
2228 | + isa = PBXGroup; |
2229 | + children = ( |
2230 | + 937FAA16137CFC7200507E51 /* DownloadOperation.h */, |
2231 | + 937FAA17137CFC7200507E51 /* DownloadOperation.m */, |
2232 | + 937FAA13137CFC5000507E51 /* Downloader.h */, |
2233 | + 937FAA14137CFC5000507E51 /* Downloader.m */, |
2234 | + 937FAA0D137CFC1B00507E51 /* AlbumArtLoader.h */, |
2235 | + 937FAA0E137CFC1B00507E51 /* AlbumArtLoader.m */, |
2236 | + 937FAA0F137CFC1B00507E51 /* AlbumArtLoadingOperation.h */, |
2237 | + 937FAA10137CFC1B00507E51 /* AlbumArtLoadingOperation.m */, |
2238 | + 937FAA19137CFCA600507E51 /* AbstractNetworkOperation.h */, |
2239 | + 937FAA1A137CFCA600507E51 /* AbstractNetworkOperation.m */, |
2240 | + ); |
2241 | + path = operations; |
2242 | + sourceTree = "<group>"; |
2243 | + }; |
2244 | 93F334441247F9B9006C6707 /* Utilities */ = { |
2245 | isa = PBXGroup; |
2246 | children = ( |
2247 | + 937FAA0C137CFC1B00507E51 /* operations */, |
2248 | 93BC5207124C181600B7587C /* Subsonic.h */, |
2249 | 93BC5208124C181600B7587C /* Subsonic.m */, |
2250 | 91018B29135924730051EFDC /* Parsers */, |
2251 | @@ -561,14 +639,10 @@ |
2252 | 93F334461247F9DE006C6707 /* SFHFKeychainUtils.m */, |
2253 | 93BC52A5124C1E6900B7587C /* StreamingPlayer.h */, |
2254 | 93BC52A6124C1E6900B7587C /* StreamingPlayer.m */, |
2255 | - 93BC53F9124C7C8D00B7587C /* DataCache.h */, |
2256 | - 93BC53FA124C7C8D00B7587C /* DataCache.m */, |
2257 | 93D6B5491252CE57007880B0 /* URLQueryStringParser.h */, |
2258 | 93D6B54A1252CE57007880B0 /* URLQueryStringParser.m */, |
2259 | - 93ED1AD6137276810058FC98 /* ImageLoader.h */, |
2260 | - 93ED1AD7137276810058FC98 /* ImageLoader.m */, |
2261 | - 93ED1ADD137279A30058FC98 /* ImageLoadingOperation.h */, |
2262 | - 93ED1ADE137279A30058FC98 /* ImageLoadingOperation.m */, |
2263 | + 937FAAED137D15E800507E51 /* Globals.h */, |
2264 | + 937FAAEE137D15E800507E51 /* Globals.m */, |
2265 | ); |
2266 | name = Utilities; |
2267 | path = utilities; |
2268 | @@ -642,7 +716,6 @@ |
2269 | 93FA42A9124DC1350080DF62 /* 05-shuffle.png */, |
2270 | 93FA42AA124DC1350080DF62 /* 05-shuffle@2x.png */, |
2271 | 93FA42AB124DC1350080DF62 /* background.png */, |
2272 | - 93FA42AC124DC1350080DF62 /* default-album-art-small.png */, |
2273 | 93FA42AD124DC1350080DF62 /* default-album-art.png */, |
2274 | ); |
2275 | name = Images; |
2276 | @@ -712,7 +785,6 @@ |
2277 | 93FA42B0124DC1350080DF62 /* 05-shuffle.png in Resources */, |
2278 | 93FA42B1124DC1350080DF62 /* 05-shuffle@2x.png in Resources */, |
2279 | 93FA42B2124DC1350080DF62 /* background.png in Resources */, |
2280 | - 93FA42B3124DC1350080DF62 /* default-album-art-small.png in Resources */, |
2281 | 93FA42B4124DC1350080DF62 /* default-album-art.png in Resources */, |
2282 | 93FA4336124DE0D80080DF62 /* player_back.png in Resources */, |
2283 | 93FA4337124DE0D80080DF62 /* player_back@2x.png in Resources */, |
2284 | @@ -739,6 +811,22 @@ |
2285 | 932E7AA11255265A00E7C8FF /* about.html in Resources */, |
2286 | 932E7B0B12552CD500E7C8FF /* arrow.png in Resources */, |
2287 | 91018B25135922BF0051EFDC /* PlaylistEditViewController.xib in Resources */, |
2288 | + 9112B0241383FF27003C1D93 /* albums.png in Resources */, |
2289 | + 9112B0251383FF27003C1D93 /* artists.png in Resources */, |
2290 | + 9112B0261383FF27003C1D93 /* playlists.png in Resources */, |
2291 | + 9112B0281383FF27003C1D93 /* settings.png in Resources */, |
2292 | + 9112B0291383FF27003C1D93 /* songs.png in Resources */, |
2293 | + 9112B02F1383FF37003C1D93 /* albums@2x.png in Resources */, |
2294 | + 9112B0301383FF37003C1D93 /* artists@2x.png in Resources */, |
2295 | + 9112B0311383FF37003C1D93 /* playlists@2x.png in Resources */, |
2296 | + 9112B0321383FF37003C1D93 /* settings@2x.png in Resources */, |
2297 | + 9112B0331383FF37003C1D93 /* songs@2x.png in Resources */, |
2298 | + 91406E9413849F2400A7DA67 /* cached.png in Resources */, |
2299 | + 91406E9513849F2400A7DA67 /* cached@2x.png in Resources */, |
2300 | + 91406E9613849F2400A7DA67 /* partiallycached.png in Resources */, |
2301 | + 91406E9713849F2400A7DA67 /* partiallycached@2x.png in Resources */, |
2302 | + 91406E9813849F2400A7DA67 /* uncached.png in Resources */, |
2303 | + 91406E9913849F2400A7DA67 /* uncached@2x.png in Resources */, |
2304 | ); |
2305 | runOnlyForDeploymentPostprocessing = 0; |
2306 | }; |
2307 | @@ -750,7 +838,6 @@ |
2308 | buildActionMask = 2147483647; |
2309 | files = ( |
2310 | 9316628812264A74003B0EB7 /* NSDate+Extras.m in Sources */, |
2311 | - 936F1F3112271B6500070F43 /* MBProgressHUD.m in Sources */, |
2312 | 936F20681227364200070F43 /* Playlist.m in Sources */, |
2313 | 936F209012273D9000070F43 /* Song.m in Sources */, |
2314 | 936F230A12284D1900070F43 /* NamedTextFieldCell.m in Sources */, |
2315 | @@ -758,8 +845,6 @@ |
2316 | 93F3344D1247FA0B006C6707 /* Reachability.m in Sources */, |
2317 | 93F334521247FA2C006C6707 /* Album.m in Sources */, |
2318 | 93F334531247FA2C006C6707 /* Artist.m in Sources */, |
2319 | - 93F334561247FA52006C6707 /* AsynchronousImageView.m in Sources */, |
2320 | - 93F334591247FA68006C6707 /* AsynchronousImageViewCached.m in Sources */, |
2321 | 93F3345C1247FA85006C6707 /* AlbumUITableViewCell.m in Sources */, |
2322 | 93F3345F1247FA97006C6707 /* SongUITableViewCell.m in Sources */, |
2323 | 93F334711247FB78006C6707 /* iSubAppDelegate.m in Sources */, |
2324 | @@ -776,7 +861,6 @@ |
2325 | 93EE2BA31249F33D00E7E060 /* ArtistParser.m in Sources */, |
2326 | 93BC5209124C181600B7587C /* Subsonic.m in Sources */, |
2327 | 93BC52A7124C1E6900B7587C /* StreamingPlayer.m in Sources */, |
2328 | - 93BC53FB124C7C8D00B7587C /* DataCache.m in Sources */, |
2329 | 93D6B0FF124ED061007880B0 /* SubsonicViewController.m in Sources */, |
2330 | 93D6B11B124ED3B3007880B0 /* UIDevice+Hardware.m in Sources */, |
2331 | 93D6B214124F0F62007880B0 /* NSNumber+Extras.m in Sources */, |
2332 | @@ -811,8 +895,16 @@ |
2333 | 93DFFE4D135D71760061F29F /* music.xcdatamodeld in Sources */, |
2334 | 93DFFE54135D72420061F29F /* NSManagedObjectContext+Additions.m in Sources */, |
2335 | 93DF12D9136E968E00D6C085 /* MiniHudView.m in Sources */, |
2336 | - 93ED1AD8137276810058FC98 /* ImageLoader.m in Sources */, |
2337 | - 93ED1ADF137279A30058FC98 /* ImageLoadingOperation.m in Sources */, |
2338 | + 937FAA11137CFC1B00507E51 /* AlbumArtLoader.m in Sources */, |
2339 | + 937FAA12137CFC1B00507E51 /* AlbumArtLoadingOperation.m in Sources */, |
2340 | + 937FAA15137CFC5000507E51 /* Downloader.m in Sources */, |
2341 | + 937FAA18137CFC7200507E51 /* DownloadOperation.m in Sources */, |
2342 | + 937FAA1B137CFCA600507E51 /* AbstractNetworkOperation.m in Sources */, |
2343 | + 937FAAEF137D15E800507E51 /* Globals.m in Sources */, |
2344 | + 91406EEA138AEEE000A7DA67 /* NSString+Extras.m in Sources */, |
2345 | + 91BE4018138E8D2300D44D68 /* UIActionSheet+Blocks.m in Sources */, |
2346 | + 91BE4019138E8D2300D44D68 /* UIAlertView+Blocks.m in Sources */, |
2347 | + 91BE401C138E8D3A00D44D68 /* RIButtonItem.m in Sources */, |
2348 | ); |
2349 | runOnlyForDeploymentPostprocessing = 0; |
2350 | }; |
2351 | @@ -823,20 +915,23 @@ |
2352 | isa = XCBuildConfiguration; |
2353 | buildSettings = { |
2354 | ALWAYS_SEARCH_USER_PATHS = NO; |
2355 | - CODE_SIGN_ENTITLEMENTS = Entitlements.plist; |
2356 | - CODE_SIGN_IDENTITY = "iPhone Developer: Zachery Bir (P7WDPDEFHU)"; |
2357 | - "CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer: Zachery Bir (P7WDPDEFHU)"; |
2358 | - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Zachery Bir (P7WDPDEFHU)"; |
2359 | + CODE_SIGN_ENTITLEMENTS = ""; |
2360 | + CODE_SIGN_IDENTITY = "iPhone Developer"; |
2361 | + "CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer"; |
2362 | + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; |
2363 | COPY_PHASE_STRIP = NO; |
2364 | + CURRENT_PROJECT_VERSION = 6; |
2365 | GCC_DYNAMIC_NO_PIC = NO; |
2366 | GCC_OPTIMIZATION_LEVEL = 0; |
2367 | GCC_PRECOMPILE_PREFIX_HEADER = YES; |
2368 | GCC_PREFIX_HEADER = iSub_Prefix.pch; |
2369 | + GCC_VERSION = ""; |
2370 | INFOPLIST_FILE = "iSub-Info.plist"; |
2371 | PRODUCT_NAME = "U1 Music"; |
2372 | - PROVISIONING_PROFILE = "6CD9666E-9AEA-40F3-8973-7914D90DB031"; |
2373 | - "PROVISIONING_PROFILE[sdk=*]" = "FE49C826-C565-422D-A0D7-2F02D179FC58"; |
2374 | - "PROVISIONING_PROFILE[sdk=iphoneos*]" = "FE49C826-C565-422D-A0D7-2F02D179FC58"; |
2375 | + PROVISIONING_PROFILE = ""; |
2376 | + "PROVISIONING_PROFILE[sdk=*]" = ""; |
2377 | + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; |
2378 | + RUN_CLANG_STATIC_ANALYZER = NO; |
2379 | SDKROOT = iphoneos; |
2380 | }; |
2381 | name = Debug; |
2382 | @@ -846,16 +941,19 @@ |
2383 | buildSettings = { |
2384 | ALWAYS_SEARCH_USER_PATHS = NO; |
2385 | CODE_SIGN_ENTITLEMENTS = Entitlements.plist; |
2386 | - CODE_SIGN_IDENTITY = "iPhone Developer: Zachery Bir (P7WDPDEFHU)"; |
2387 | - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Canonical Group Limited"; |
2388 | - COPY_PHASE_STRIP = YES; |
2389 | + CODE_SIGN_IDENTITY = "iPhone Distribution"; |
2390 | + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; |
2391 | + COPY_PHASE_STRIP = NO; |
2392 | + CURRENT_PROJECT_VERSION = 6; |
2393 | GCC_PRECOMPILE_PREFIX_HEADER = YES; |
2394 | GCC_PREFIX_HEADER = iSub_Prefix.pch; |
2395 | + GCC_VERSION = ""; |
2396 | INFOPLIST_FILE = "iSub-Info.plist"; |
2397 | IPHONEOS_DEPLOYMENT_TARGET = 4.0; |
2398 | PRODUCT_NAME = "U1 Music"; |
2399 | - PROVISIONING_PROFILE = "6CD9666E-9AEA-40F3-8973-7914D90DB031"; |
2400 | - "PROVISIONING_PROFILE[sdk=iphoneos*]" = "C363FA5F-63C0-4EEA-8F4A-99821B6B3DDF"; |
2401 | + PROVISIONING_PROFILE = ""; |
2402 | + "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; |
2403 | + RUN_CLANG_STATIC_ANALYZER = NO; |
2404 | SDKROOT = iphoneos; |
2405 | }; |
2406 | name = Release; |
2407 | @@ -864,16 +962,19 @@ |
2408 | isa = XCBuildConfiguration; |
2409 | buildSettings = { |
2410 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; |
2411 | - CODE_SIGN_ENTITLEMENTS = ""; |
2412 | + CODE_SIGN_ENTITLEMENTS = Entitlements.plist; |
2413 | + CODE_SIGN_IDENTITY = "iPhone Developer"; |
2414 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; |
2415 | + COPY_PHASE_STRIP = NO; |
2416 | GCC_C_LANGUAGE_STANDARD = c99; |
2417 | GCC_WARN_ABOUT_RETURN_TYPE = YES; |
2418 | GCC_WARN_UNUSED_VARIABLE = YES; |
2419 | IPHONEOS_DEPLOYMENT_TARGET = 4.0; |
2420 | OTHER_CFLAGS = ""; |
2421 | PREBINDING = NO; |
2422 | + PROVISIONING_PROFILE = ""; |
2423 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; |
2424 | - SDKROOT = iphoneos4.1; |
2425 | + SDKROOT = iphoneos; |
2426 | }; |
2427 | name = Debug; |
2428 | }; |
2429 | @@ -881,15 +982,18 @@ |
2430 | isa = XCBuildConfiguration; |
2431 | buildSettings = { |
2432 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; |
2433 | - CODE_SIGN_ENTITLEMENTS = ""; |
2434 | + CODE_SIGN_ENTITLEMENTS = Entitlements.plist; |
2435 | + CODE_SIGN_IDENTITY = "iPhone Distribution"; |
2436 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; |
2437 | + COPY_PHASE_STRIP = NO; |
2438 | GCC_C_LANGUAGE_STANDARD = c99; |
2439 | GCC_WARN_ABOUT_RETURN_TYPE = YES; |
2440 | GCC_WARN_UNUSED_VARIABLE = YES; |
2441 | IPHONEOS_DEPLOYMENT_TARGET = 4.0; |
2442 | PREBINDING = NO; |
2443 | + PROVISIONING_PROFILE = ""; |
2444 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; |
2445 | - SDKROOT = iphoneos4.1; |
2446 | + SDKROOT = iphoneos; |
2447 | }; |
2448 | name = Release; |
2449 | }; |
2450 | |
2451 | === modified file 'musicstreaming/iSub_Prefix.pch' |
2452 | --- musicstreaming/iSub_Prefix.pch 2011-04-19 08:04:45 +0000 |
2453 | +++ musicstreaming/iSub_Prefix.pch 2011-06-13 16:58:33 +0000 |
2454 | @@ -12,12 +12,12 @@ |
2455 | #import <Foundation/Foundation.h> |
2456 | #import <UIKit/UIKit.h> |
2457 | #import <CoreData/CoreData.h> |
2458 | + #import "Globals.h" |
2459 | #import "MOC.h" |
2460 | #import "NSManagedObjectContext+Additions.h" |
2461 | #import "SFHFKeychainUtils.h" |
2462 | #define RELEASE_SAFELY(__obj) [__obj release], __obj = nil; |
2463 | |
2464 | - //xxx todo - I believe serviceName needs to have the bundle identifier (ABC12345DEF.) prepended to it. |
2465 | #define UBUNTU_ONE_SERVICE_NAME @"com.ubuntu.one" |
2466 | #define UBUNTU_ONE_DUMMY_USER_NAME @"_UBUNTU_ONE_USER_NAME" |
2467 | #endif |
2468 | |
2469 | === removed file 'musicstreaming/images/default-album-art-small.png' |
2470 | Binary files musicstreaming/images/default-album-art-small.png 2010-09-25 05:48:41 +0000 and musicstreaming/images/default-album-art-small.png 1970-01-01 00:00:00 +0000 differ |
2471 | === modified file 'musicstreaming/images/default-album-art.png' |
2472 | Binary files musicstreaming/images/default-album-art.png 2010-09-25 05:48:41 +0000 and musicstreaming/images/default-album-art.png 2011-06-13 16:58:33 +0000 differ |
2473 | === modified file 'musicstreaming/models/Album.h' |
2474 | --- musicstreaming/models/Album.h 2011-05-02 07:15:23 +0000 |
2475 | +++ musicstreaming/models/Album.h 2011-06-13 16:58:33 +0000 |
2476 | @@ -30,7 +30,7 @@ |
2477 | |
2478 | @class Artist, Song; |
2479 | |
2480 | -@interface Album : NSManagedObject <NSCoding, NSCopying> |
2481 | +@interface Album : NSManagedObject |
2482 | { |
2483 | } |
2484 | @property (nonatomic, retain) NSString *title; |
2485 | @@ -43,6 +43,8 @@ |
2486 | + (BOOL)albumWithIdExists:(NSString*)anAlbumId; |
2487 | + (Album*)albumWithId:(NSString*)anAlbumId; |
2488 | - (BOOL)matchesSearchQuery:(NSString *)query; |
2489 | +- (NSError*)loadSongs; |
2490 | +- (NSString*)dearticlizedTitle; |
2491 | @end |
2492 | |
2493 | // coalesce these into one @interface Album (CoreDataGeneratedAccessors) section |
2494 | |
2495 | === modified file 'musicstreaming/models/Album.m' |
2496 | --- musicstreaming/models/Album.m 2011-05-02 07:15:23 +0000 |
2497 | +++ musicstreaming/models/Album.m 2011-06-13 16:58:33 +0000 |
2498 | @@ -30,6 +30,10 @@ |
2499 | |
2500 | #import "Album.h" |
2501 | #import "Artist.h" |
2502 | +#import "NSMutableSet+Extras.h" |
2503 | +#import "NSString+Extras.h" |
2504 | +#import "AlbumParser.h" |
2505 | +#import "Subsonic.h" |
2506 | |
2507 | @implementation Album |
2508 | @dynamic title, artist, albumId, coverArtId; |
2509 | @@ -63,46 +67,36 @@ |
2510 | } |
2511 | } |
2512 | |
2513 | -- (id)copyWithZone:(NSZone *)zone |
2514 | -{ |
2515 | - Album *copy = [[Album allocWithZone:zone] init]; |
2516 | - |
2517 | - NSString *t = [self.title copyWithZone:zone]; |
2518 | - copy.title = t; |
2519 | - |
2520 | - NSString *a = [self.artist copyWithZone:zone]; |
2521 | - copy.artist = a; |
2522 | - |
2523 | - NSString *i = [self.albumId copyWithZone:zone]; |
2524 | - copy.albumId = i; |
2525 | - |
2526 | - NSString *c = [self.coverArtId copyWithZone:zone]; |
2527 | - copy.coverArtId = c; |
2528 | - |
2529 | - [t release]; |
2530 | - [a release]; |
2531 | - [i release]; |
2532 | - [c release]; |
2533 | - |
2534 | - return copy; |
2535 | -} |
2536 | - |
2537 | -- (void)encodeWithCoder:(NSCoder*)encoder |
2538 | -{ |
2539 | - [encoder encodeObject:self.title forKey:@"title"]; |
2540 | - [encoder encodeObject:self.artist forKey:@"artist"]; |
2541 | - [encoder encodeObject:self.albumId forKey:@"albumId"]; |
2542 | - [encoder encodeObject:self.coverArtId forKey:@"coverArtId"]; |
2543 | -} |
2544 | - |
2545 | -- (id)initWithCoder:(NSCoder*)decoder |
2546 | -{ |
2547 | - self.title = [[decoder decodeObjectForKey:@"title"] retain]; |
2548 | - self.artist = [[decoder decodeObjectForKey:@"artist"] retain]; |
2549 | - self.albumId = [[decoder decodeObjectForKey:@"albumId"] retain]; |
2550 | - self.coverArtId = [[decoder decodeObjectForKey:@"coverArtId"] retain]; |
2551 | - |
2552 | - return self; |
2553 | +- (NSString *)dearticlizedTitle |
2554 | +{ |
2555 | + return [self.title dearticlizedString]; |
2556 | +} |
2557 | + |
2558 | +- (NSError*)loadSongs |
2559 | +{ |
2560 | + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
2561 | + NSError *error = nil; |
2562 | + |
2563 | + NSMutableSet *parameters = [NSMutableSet set]; |
2564 | + [parameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"id", self.albumId, nil]]; |
2565 | + NSURL *url = [[Subsonic sharedSubsonic] getBaseURL:@"getAlbum.view" parameters:parameters]; |
2566 | + NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url]; |
2567 | + |
2568 | + AlbumParser *parser = [[AlbumParser alloc] init]; |
2569 | + parser.albumObjectId = [self objectID]; |
2570 | + |
2571 | + [xmlParser setDelegate:parser]; |
2572 | + |
2573 | + if (![xmlParser parse]) |
2574 | + { |
2575 | + error = [[xmlParser parserError] copy]; |
2576 | + } |
2577 | + |
2578 | + [xmlParser release]; |
2579 | + [parser release]; |
2580 | + [pool release]; |
2581 | + |
2582 | + return [error autorelease]; |
2583 | } |
2584 | |
2585 | - (NSString*)description |
2586 | |
2587 | === modified file 'musicstreaming/models/Artist.h' |
2588 | --- musicstreaming/models/Artist.h 2011-05-02 03:10:39 +0000 |
2589 | +++ musicstreaming/models/Artist.h 2011-06-13 16:58:33 +0000 |
2590 | @@ -30,7 +30,7 @@ |
2591 | |
2592 | @class Album, Song; |
2593 | |
2594 | -@interface Artist : NSManagedObject <NSCoding> |
2595 | +@interface Artist : NSManagedObject |
2596 | { |
2597 | } |
2598 | @property (nonatomic, retain) NSString *name; |
2599 | @@ -39,6 +39,8 @@ |
2600 | @property (nonatomic, retain) NSSet* songs; |
2601 | + (BOOL)artistWithIdExists:(NSString*)anArtistId; |
2602 | - (BOOL)matchesSearchQuery:(NSString *)query; |
2603 | +- (NSString *)dearticlizedName; |
2604 | +- (NSError*)loadAlbums; |
2605 | @end |
2606 | |
2607 | @interface Artist (CoreDataGeneratedAccessors) |
2608 | |
2609 | === modified file 'musicstreaming/models/Artist.m' |
2610 | --- musicstreaming/models/Artist.m 2011-05-02 03:10:39 +0000 |
2611 | +++ musicstreaming/models/Artist.m 2011-06-13 16:58:33 +0000 |
2612 | @@ -30,6 +30,10 @@ |
2613 | |
2614 | #import "Artist.h" |
2615 | #import "Album.h" |
2616 | +#import "Subsonic.h" |
2617 | +#import "NSMutableSet+Extras.h" |
2618 | +#import "NSString+Extras.h" |
2619 | +#import "ArtistParser.h" |
2620 | |
2621 | @implementation Artist |
2622 | |
2623 | @@ -54,23 +58,6 @@ |
2624 | return (0 != [matches count]); |
2625 | } |
2626 | |
2627 | -- (id)initWithCoder:(NSCoder*)decoder |
2628 | -{ |
2629 | - if ((self = [super init])) |
2630 | - { |
2631 | - self.name = [decoder decodeObjectForKey:@"name"]; |
2632 | - self.artistId = [decoder decodeObjectForKey:@"artistId"]; |
2633 | - } |
2634 | - |
2635 | - return self; |
2636 | -} |
2637 | - |
2638 | -- (void)encodeWithCoder:(NSCoder*)encoder |
2639 | -{ |
2640 | - [encoder encodeObject:self.name forKey:@"name"]; |
2641 | - [encoder encodeObject:self.artistId forKey:@"artistId"]; |
2642 | -} |
2643 | - |
2644 | - (NSString*)description |
2645 | { |
2646 | return [NSString stringWithFormat:@"%@ (%@) MOC %@",self.name, self.artistId, [self managedObjectContext]]; |
2647 | @@ -82,4 +69,35 @@ |
2648 | return titleResultsRange.length > 0; |
2649 | } |
2650 | |
2651 | +- (NSString *)dearticlizedName |
2652 | +{ |
2653 | + return [self.name dearticlizedString]; |
2654 | +} |
2655 | + |
2656 | +// Note: executes synchronously! |
2657 | +- (NSError*)loadAlbums |
2658 | +{ |
2659 | + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
2660 | + NSError *error = nil; |
2661 | + |
2662 | + NSMutableSet *parameters = [NSMutableSet set]; |
2663 | + [parameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"id", self.artistId, nil]]; |
2664 | + NSURL *url = [[Subsonic sharedSubsonic] getBaseURL:@"getMusicDirectory.view" parameters:parameters]; |
2665 | + NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url]; |
2666 | + ArtistParser *parser = [[ArtistParser alloc] init]; |
2667 | + parser.artistManagedObjectID = [self objectID]; |
2668 | + [xmlParser setDelegate:parser]; |
2669 | + |
2670 | + if (![xmlParser parse]) |
2671 | + { |
2672 | + error = [[xmlParser parserError] copy]; |
2673 | + } |
2674 | + |
2675 | + [xmlParser release]; |
2676 | + [parser release]; |
2677 | + [pool release]; |
2678 | + |
2679 | + return [error autorelease]; |
2680 | +} |
2681 | + |
2682 | @end |
2683 | |
2684 | === modified file 'musicstreaming/models/MOC.m' |
2685 | --- musicstreaming/models/MOC.m 2011-04-19 08:05:04 +0000 |
2686 | +++ musicstreaming/models/MOC.m 2011-06-13 16:58:33 +0000 |
2687 | @@ -52,11 +52,6 @@ |
2688 | } |
2689 | } |
2690 | |
2691 | -NSURL* ApplicationDocumentsDirectory( void ) |
2692 | -{ |
2693 | - return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; |
2694 | -} |
2695 | - |
2696 | NSPersistentStoreCoordinator * GetPersistentStoreCoordinator( void ) |
2697 | { |
2698 | if (persistentStoreCoordinator_ != nil) |
2699 | @@ -64,7 +59,7 @@ |
2700 | return persistentStoreCoordinator_; |
2701 | } |
2702 | |
2703 | - NSURL *storeURL = [ApplicationDocumentsDirectory() URLByAppendingPathComponent:@"music.sqlite"]; |
2704 | + NSURL *storeURL = DatabaseFile(); |
2705 | |
2706 | NSError *error = nil; |
2707 | persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:GetManagedObjectModel()]; |
2708 | |
2709 | === modified file 'musicstreaming/models/Playlist.h' |
2710 | --- musicstreaming/models/Playlist.h 2011-04-07 20:50:30 +0000 |
2711 | +++ musicstreaming/models/Playlist.h 2011-06-13 16:58:33 +0000 |
2712 | @@ -19,25 +19,25 @@ |
2713 | |
2714 | #import <Foundation/Foundation.h> |
2715 | |
2716 | +@class Song; |
2717 | |
2718 | -@interface Playlist : NSObject <NSCoding> |
2719 | +@interface Playlist : NSManagedObject |
2720 | { |
2721 | - NSString *playlistId; |
2722 | - NSString *name; |
2723 | - NSMutableArray *contents; |
2724 | } |
2725 | @property(nonatomic,retain) NSString *playlistId; |
2726 | @property(nonatomic,retain) NSString *name; |
2727 | -@property(nonatomic,retain) NSMutableArray *contents; |
2728 | -- (id)initWithCoder:(NSCoder *)aDecoder; |
2729 | -- (BOOL)matchesSearchQuery:(NSString*)query; |
2730 | -@end |
2731 | - |
2732 | -//Subordinate Data: |
2733 | -//<?xml version="1.0" encoding="UTF-8"?> |
2734 | -//<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.2.0"> |
2735 | -// <playlist> |
2736 | -// <entry id="2f55736572732f6161726f6e2f4d757369632f6954756e65732f6954756e6573204d757369632f4d757369632f41726361646520466972652f54686520537562757262732f30312054686520537562757262732e6d7033" title="The Suburbs" isDir="false" album="The Suburbs" artist="Arcade Fire" duration="315" bitRate="320" track="1" year="2010" genre="Rock" size="12797916" suffix="mp3" contentType="audio/mpeg" coverArt="2f55736572732f6161726f6e2f4d757369632f6954756e65732f6954756e6573204d757369632f4d757369632f41726361646520466972652f54686520537562757262732f30312054686520537562757262732e6d7033" path="Arcade Fire/The Suburbs/01 The Suburbs.mp3"/> |
2737 | -// <entry id="2f55736572732f6161726f6e2f4d757369632f6954756e65732f6954756e6573204d757369632f4d757369632f41726361646520466972652f54686520537562757262732f303220526561647920546f2053746172742e6d7033" title="Ready To Start" isDir="false" album="The Suburbs" artist="Arcade Fire" duration="255" bitRate="320" track="2" year="2010" genre="Rock" size="10413098" suffix="mp3" contentType="audio/mpeg" coverArt="2f55736572732f6161726f6e2f4d757369632f6954756e65732f6954756e6573204d757369632f4d757369632f41726361646520466972652f54686520537562757262732f30312054686520537562757262732e6d7033" path="Arcade Fire/The Suburbs/02 Ready To Start.mp3"/> |
2738 | -// </playlist> |
2739 | -//</subsonic-response> |
2740 | \ No newline at end of file |
2741 | +@property(nonatomic,retain) NSSet *songs; |
2742 | + |
2743 | ++ (BOOL)playlistWithIdExists:(NSString*)aPlaylistId; |
2744 | ++ (Playlist*)playlistWithId:(NSString*)aPlaylistId; |
2745 | +- (BOOL)matchesSearchQuery:(NSString *)query; |
2746 | +- (NSError*)loadSongs; |
2747 | +@end |
2748 | + |
2749 | +// coalesce these into one @interface Album (CoreDataGeneratedAccessors) section |
2750 | +@interface Playlist (CoreDataGeneratedAccessors) |
2751 | +- (void)addSongsObject:(Song *)value; |
2752 | +- (void)removeSongsObject:(Song *)value; |
2753 | +- (void)addSongs:(NSSet *)value; |
2754 | +- (void)removeSongs:(NSSet *)value; |
2755 | +@end |
2756 | |
2757 | === modified file 'musicstreaming/models/Playlist.m' |
2758 | --- musicstreaming/models/Playlist.m 2011-04-07 23:59:24 +0000 |
2759 | +++ musicstreaming/models/Playlist.m 2011-06-13 16:58:33 +0000 |
2760 | @@ -18,51 +18,77 @@ |
2761 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
2762 | |
2763 | #import "Playlist.h" |
2764 | +#import "Subsonic.h" |
2765 | +#import "NSMutableSet+Extras.h" |
2766 | +#import "PlaylistParser.h" |
2767 | |
2768 | @implementation Playlist |
2769 | |
2770 | -@synthesize playlistId, name, contents; |
2771 | - |
2772 | -- (id)init |
2773 | -{ |
2774 | - if ((self = [super init])) |
2775 | - { |
2776 | - self.playlistId = nil; |
2777 | - self.name = nil; |
2778 | - self.contents = [NSMutableArray array]; |
2779 | - } |
2780 | - return self; |
2781 | -} |
2782 | - |
2783 | -- (void)encodeWithCoder:(NSCoder*)encoder |
2784 | -{ |
2785 | - [encoder encodeObject:playlistId forKey:@"playlistId"]; |
2786 | - [encoder encodeObject:name forKey:@"name"]; |
2787 | - [encoder encodeObject:contents forKey:@"contents"]; |
2788 | -} |
2789 | - |
2790 | - |
2791 | -- (id)initWithCoder:(NSCoder*)decoder |
2792 | -{ |
2793 | - playlistId = [[decoder decodeObjectForKey:@"playlistId"] retain]; |
2794 | - name = [[decoder decodeObjectForKey:@"name"] retain]; |
2795 | - contents = [[decoder decodeObjectForKey:@"contents"] retain]; |
2796 | - |
2797 | - return self; |
2798 | -} |
2799 | - |
2800 | -- (void)dealloc |
2801 | -{ |
2802 | - self.playlistId = NULL; |
2803 | - self.name = NULL; |
2804 | - self.contents = NULL; |
2805 | - |
2806 | - [super dealloc]; |
2807 | +@dynamic playlistId, name, songs; |
2808 | + |
2809 | ++ (BOOL)playlistWithIdExists:(NSString *)aPlaylistId |
2810 | +{ |
2811 | + return (nil != [Playlist playlistWithId:aPlaylistId]); |
2812 | +} |
2813 | + |
2814 | ++ (Playlist *)playlistWithId:(NSString *)aPlaylistId |
2815 | +{ |
2816 | + NSFetchRequest * fetch = [[NSFetchRequest alloc] init]; |
2817 | + NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Playlist" inManagedObjectContext:PerThreadManagedObjectContext()]; |
2818 | + [fetch setEntity:entityDescription]; |
2819 | + |
2820 | + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"playlistId == %@", aPlaylistId]; |
2821 | + [fetch setPredicate:predicate]; |
2822 | + |
2823 | + NSError * error = nil; |
2824 | + NSArray * matches = [PerThreadManagedObjectContext() executeFetchRequest:fetch error:&error]; |
2825 | + [fetch release]; |
2826 | + |
2827 | + if ([matches count] > 0) |
2828 | + { |
2829 | + return [matches objectAtIndex:0]; |
2830 | + } |
2831 | + else |
2832 | + { |
2833 | + return nil; |
2834 | + } |
2835 | +} |
2836 | + |
2837 | +- (NSError*)loadSongs |
2838 | +{ |
2839 | + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
2840 | + NSError *error = nil; |
2841 | + |
2842 | + NSMutableSet *parameters = [NSMutableSet set]; |
2843 | + [parameters addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"id", self.playlistId, nil]]; |
2844 | + NSURL *url = [[Subsonic sharedSubsonic] getBaseURL:@"getPlaylist.view" parameters:parameters]; |
2845 | + NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url]; |
2846 | + |
2847 | + PlaylistParser *parser = [[PlaylistParser alloc] init]; |
2848 | + parser.playlistObjectId = [self objectID]; |
2849 | + |
2850 | + [xmlParser setDelegate:parser]; |
2851 | + |
2852 | + if (![xmlParser parse]) |
2853 | + { |
2854 | + error = [[xmlParser parserError] copy]; |
2855 | + } |
2856 | + |
2857 | + [xmlParser release]; |
2858 | + [parser release]; |
2859 | + [pool release]; |
2860 | + |
2861 | + return [error autorelease]; |
2862 | +} |
2863 | + |
2864 | +- (NSString*)description |
2865 | +{ |
2866 | + return [NSString stringWithFormat:@"%@ (%@) MOC %@", self.name, self.playlistId, [self managedObjectContext]]; |
2867 | } |
2868 | |
2869 | - (BOOL)matchesSearchQuery:(NSString *)query |
2870 | { |
2871 | - NSRange titleResultsRange = [name rangeOfString:query options:NSCaseInsensitiveSearch]; |
2872 | + NSRange titleResultsRange = [self.name rangeOfString:query options:NSCaseInsensitiveSearch]; |
2873 | return titleResultsRange.length > 0; |
2874 | } |
2875 | |
2876 | |
2877 | === modified file 'musicstreaming/models/Song.h' |
2878 | --- musicstreaming/models/Song.h 2011-05-05 18:12:15 +0000 |
2879 | +++ musicstreaming/models/Song.h 2011-06-13 16:58:33 +0000 |
2880 | @@ -28,9 +28,9 @@ |
2881 | // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
2882 | // DAMAGE. |
2883 | |
2884 | -@class Artist, Album; |
2885 | +@class Artist, Album, Playlist; |
2886 | |
2887 | -@interface Song : NSManagedObject <NSCoding> |
2888 | +@interface Song : NSManagedObject |
2889 | { |
2890 | } |
2891 | @property (nonatomic, retain) NSString *title; |
2892 | @@ -47,8 +47,19 @@ |
2893 | @property (nonatomic, retain) NSNumber *size; |
2894 | @property (nonatomic, retain) Artist *artistEntity; |
2895 | @property (nonatomic, retain) Album *albumEntity; |
2896 | +@property (nonatomic, retain) NSSet *playlistEntities; |
2897 | |
2898 | + (BOOL)songWithIdExists:(NSString*)aSongId; |
2899 | + (Song*)songWithId:(NSString*)aSongId; |
2900 | - (BOOL)matchesSearchQuery:(NSString *)query; |
2901 | -@end |
2902 | \ No newline at end of file |
2903 | +- (NSString *)dearticlizedTitle; |
2904 | +- (BOOL)cachedSongExists; |
2905 | +- (NSURL*)cachedSongURL; |
2906 | +@end |
2907 | + |
2908 | +@interface Song (CoreDataGeneratedAccessors) |
2909 | +- (void)addPlaylistEntitiesObject:(Playlist *)value; |
2910 | +- (void)removePlaylistEntitiesObject:(Playlist *)value; |
2911 | +- (void)addPlaylistEntities:(NSSet *)value; |
2912 | +- (void)removePlaylistEntities:(NSSet *)value; |
2913 | +@end |
2914 | |
2915 | === modified file 'musicstreaming/models/Song.m' |
2916 | --- musicstreaming/models/Song.m 2011-05-05 18:12:15 +0000 |
2917 | +++ musicstreaming/models/Song.m 2011-06-13 16:58:33 +0000 |
2918 | @@ -31,10 +31,11 @@ |
2919 | #import "Song.h" |
2920 | #import "Artist.h" |
2921 | #import "Album.h" |
2922 | +#import "NSString+Extras.h" |
2923 | |
2924 | @implementation Song |
2925 | @dynamic title, songId, artist, album, genre, coverArtId, path, duration, bitRate, track, year, size; |
2926 | -@dynamic artistEntity, albumEntity; |
2927 | +@dynamic artistEntity, albumEntity, playlistEntities; |
2928 | |
2929 | + (BOOL)songWithIdExists:(NSString*)aSongId |
2930 | { |
2931 | @@ -64,42 +65,14 @@ |
2932 | } |
2933 | } |
2934 | |
2935 | - |
2936 | -- (void)encodeWithCoder:(NSCoder*)encoder |
2937 | +- (NSURL*)cachedSongURL |
2938 | { |
2939 | - [encoder encodeObject:self.title forKey:@"title"]; |
2940 | - [encoder encodeObject:self.songId forKey:@"songId"]; |
2941 | - [encoder encodeObject:self.artist forKey:@"artist"]; |
2942 | - [encoder encodeObject:self.album forKey:@"album"]; |
2943 | - [encoder encodeObject:self.genre forKey:@"genre"]; |
2944 | - [encoder encodeObject:self.coverArtId forKey:@"coverArtId"]; |
2945 | - [encoder encodeObject:self.path forKey:@"path"]; |
2946 | - [encoder encodeObject:self.duration forKey:@"duration"]; |
2947 | - [encoder encodeObject:self.bitRate forKey:@"bitRate"]; |
2948 | - [encoder encodeObject:self.track forKey:@"track"]; |
2949 | - [encoder encodeObject:self.year forKey:@"year"]; |
2950 | - [encoder encodeObject:self.size forKey:@"size"]; |
2951 | + return [CachedMusicDirectory() URLByAppendingPathComponent:self.songId]; |
2952 | } |
2953 | |
2954 | - |
2955 | -- (id)initWithCoder:(NSCoder*)decoder |
2956 | +- (BOOL)cachedSongExists |
2957 | { |
2958 | - if ((self = [super init])) |
2959 | - { |
2960 | - self.title = [[decoder decodeObjectForKey:@"title"] retain]; |
2961 | - self.songId = [[decoder decodeObjectForKey:@"songId"] retain]; |
2962 | - self.artist = [[decoder decodeObjectForKey:@"artist"] retain]; |
2963 | - self.album = [[decoder decodeObjectForKey:@"album"] retain]; |
2964 | - self.genre = [[decoder decodeObjectForKey:@"genre"] retain]; |
2965 | - self.coverArtId = [[decoder decodeObjectForKey:@"coverArtId"] retain]; |
2966 | - self.path = [[decoder decodeObjectForKey:@"path"] retain]; |
2967 | - self.duration = [[decoder decodeObjectForKey:@"duration"] retain]; |
2968 | - self.bitRate = [[decoder decodeObjectForKey:@"bitRate"] retain]; |
2969 | - self.track = [[decoder decodeObjectForKey:@"track"] retain]; |
2970 | - self.year = [[decoder decodeObjectForKey:@"year"] retain]; |
2971 | - self.size = [[decoder decodeObjectForKey:@"size"] retain]; |
2972 | - } |
2973 | - return self; |
2974 | + return [[NSFileManager defaultManager] fileExistsAtPath:[[self cachedSongURL] path]]; |
2975 | } |
2976 | |
2977 | - (NSComparisonResult)compare:(Song*)s |
2978 | @@ -126,4 +99,9 @@ |
2979 | return titleResultsRange.length > 0; |
2980 | } |
2981 | |
2982 | +- (NSString *)dearticlizedTitle |
2983 | +{ |
2984 | + return [self.title dearticlizedString]; |
2985 | +} |
2986 | + |
2987 | @end |
2988 | |
2989 | === modified file 'musicstreaming/music.xcdatamodeld/music.xcdatamodel/elements' |
2990 | Binary files musicstreaming/music.xcdatamodeld/music.xcdatamodel/elements 2011-05-02 04:54:02 +0000 and musicstreaming/music.xcdatamodeld/music.xcdatamodel/elements 2011-06-13 16:58:33 +0000 differ |
2991 | === modified file 'musicstreaming/music.xcdatamodeld/music.xcdatamodel/layout' |
2992 | Binary files musicstreaming/music.xcdatamodeld/music.xcdatamodel/layout 2011-05-02 04:54:02 +0000 and musicstreaming/music.xcdatamodeld/music.xcdatamodel/layout 2011-06-13 16:58:33 +0000 differ |
2993 | === added file 'musicstreaming/partiallycached.png' |
2994 | Binary files musicstreaming/partiallycached.png 1970-01-01 00:00:00 +0000 and musicstreaming/partiallycached.png 2011-06-13 16:58:33 +0000 differ |
2995 | === added file 'musicstreaming/partiallycached@2x.png' |
2996 | Binary files musicstreaming/partiallycached@2x.png 1970-01-01 00:00:00 +0000 and musicstreaming/partiallycached@2x.png 2011-06-13 16:58:33 +0000 differ |
2997 | === added file 'musicstreaming/playlists.png' |
2998 | Binary files musicstreaming/playlists.png 1970-01-01 00:00:00 +0000 and musicstreaming/playlists.png 2011-06-13 16:58:33 +0000 differ |
2999 | === added file 'musicstreaming/playlists@2x.png' |
3000 | Binary files musicstreaming/playlists@2x.png 1970-01-01 00:00:00 +0000 and musicstreaming/playlists@2x.png 2011-06-13 16:58:33 +0000 differ |
3001 | === added file 'musicstreaming/settings.png' |
3002 | Binary files musicstreaming/settings.png 1970-01-01 00:00:00 +0000 and musicstreaming/settings.png 2011-06-13 16:58:33 +0000 differ |
3003 | === added file 'musicstreaming/settings@2x.png' |
3004 | Binary files musicstreaming/settings@2x.png 1970-01-01 00:00:00 +0000 and musicstreaming/settings@2x.png 2011-06-13 16:58:33 +0000 differ |
3005 | === added file 'musicstreaming/songs.png' |
3006 | Binary files musicstreaming/songs.png 1970-01-01 00:00:00 +0000 and musicstreaming/songs.png 2011-06-13 16:58:33 +0000 differ |
3007 | === added file 'musicstreaming/songs@2x.png' |
3008 | Binary files musicstreaming/songs@2x.png 1970-01-01 00:00:00 +0000 and musicstreaming/songs@2x.png 2011-06-13 16:58:33 +0000 differ |
3009 | === added file 'musicstreaming/uncached.png' |
3010 | Binary files musicstreaming/uncached.png 1970-01-01 00:00:00 +0000 and musicstreaming/uncached.png 2011-06-13 16:58:33 +0000 differ |
3011 | === added file 'musicstreaming/uncached@2x.png' |
3012 | Binary files musicstreaming/uncached@2x.png 1970-01-01 00:00:00 +0000 and musicstreaming/uncached@2x.png 2011-06-13 16:58:33 +0000 differ |
3013 | === modified file 'musicstreaming/utilities/AlbumListParser.m' |
3014 | --- musicstreaming/utilities/AlbumListParser.m 2011-05-02 07:15:23 +0000 |
3015 | +++ musicstreaming/utilities/AlbumListParser.m 2011-06-13 16:58:33 +0000 |
3016 | @@ -22,16 +22,6 @@ |
3017 | |
3018 | @implementation AlbumListParser |
3019 | |
3020 | -- (id)init |
3021 | -{ |
3022 | - if ((self = [super init])) |
3023 | - { |
3024 | - // |
3025 | - } |
3026 | - return self; |
3027 | -} |
3028 | - |
3029 | - |
3030 | - (void) subsonicErrorCode:(NSString *)errorCode message:(NSString *)message |
3031 | { |
3032 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:message delegate:nil cancelButtonTitle:NSLocalizedString(@"Dismiss", @"") otherButtonTitles:nil]; |
3033 | @@ -55,27 +45,11 @@ |
3034 | album.title = [attributeDict objectForKey:@"title"]; |
3035 | album.albumId = [attributeDict objectForKey:@"id"]; |
3036 | album.artist = [attributeDict objectForKey:@"artist"]; |
3037 | - |
3038 | - if ([attributeDict objectForKey:@"coverArt"]) |
3039 | - { |
3040 | - album.coverArtId = [attributeDict objectForKey:@"coverArt"]; |
3041 | - } |
3042 | + album.coverArtId = [attributeDict objectForKey:@"coverArt"]; |
3043 | |
3044 | SaveContext(); |
3045 | } |
3046 | } |
3047 | } |
3048 | |
3049 | - |
3050 | -- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName |
3051 | -{ |
3052 | - // |
3053 | -} |
3054 | - |
3055 | - |
3056 | -- (void) dealloc |
3057 | -{ |
3058 | - [super dealloc]; |
3059 | -} |
3060 | - |
3061 | @end |
3062 | \ No newline at end of file |
3063 | |
3064 | === modified file 'musicstreaming/utilities/AlbumParser.m' |
3065 | --- musicstreaming/utilities/AlbumParser.m 2011-05-05 18:12:15 +0000 |
3066 | +++ musicstreaming/utilities/AlbumParser.m 2011-06-13 16:58:33 +0000 |
3067 | @@ -51,11 +51,11 @@ |
3068 | } |
3069 | else if ([elementName isEqualToString:@"song"]) |
3070 | { |
3071 | - Song *existing = [Song songWithId:[attributeDict objectForKey:@"id"]]; |
3072 | + Song *song = [Song songWithId:[attributeDict objectForKey:@"id"]]; |
3073 | |
3074 | - if (nil == existing) |
3075 | + if (nil == song) |
3076 | { |
3077 | - Song *song = [NSEntityDescription insertNewObjectForEntityForName:@"Song" inManagedObjectContext:PerThreadManagedObjectContext()]; |
3078 | + song = [NSEntityDescription insertNewObjectForEntityForName:@"Song" inManagedObjectContext:PerThreadManagedObjectContext()]; |
3079 | |
3080 | song.title = [attributeDict nilifiedValueForKey:@"title"]; |
3081 | song.songId = [attributeDict nilifiedValueForKey:@"id"]; |
3082 | @@ -74,14 +74,10 @@ |
3083 | song.year = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"year"]]; |
3084 | song.size = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"size"]]; |
3085 | |
3086 | - [album addSongsObject:song]; |
3087 | - SaveContext(); |
3088 | - } |
3089 | - else if (nil == existing.albumEntity) |
3090 | - { |
3091 | - [album addSongsObject:existing]; |
3092 | - SaveContext(); |
3093 | - } |
3094 | + } |
3095 | + |
3096 | + [album addSongsObject:song]; |
3097 | + SaveContext(); |
3098 | } |
3099 | } |
3100 | |
3101 | |
3102 | === modified file 'musicstreaming/utilities/ArtistListParser.h' |
3103 | --- musicstreaming/utilities/ArtistListParser.h 2011-04-07 16:11:14 +0000 |
3104 | +++ musicstreaming/utilities/ArtistListParser.h 2011-06-13 16:58:33 +0000 |
3105 | @@ -23,15 +23,5 @@ |
3106 | |
3107 | @interface ArtistListParser : NSObject <NSXMLParserDelegate> |
3108 | { |
3109 | - NSMutableArray *artists; |
3110 | - NSMutableArray *indexes; |
3111 | - Artist *artist; |
3112 | - NSString *index; |
3113 | - NSMutableDictionary *groupedArtists; |
3114 | } |
3115 | -@property(nonatomic,retain) NSMutableDictionary *groupedArtists; |
3116 | -@property(nonatomic,retain) NSMutableArray *artists; |
3117 | -@property(nonatomic,retain) NSMutableArray *indexes; |
3118 | -@property(nonatomic,retain) Artist *artist; |
3119 | -@property(nonatomic,retain) NSString *index; |
3120 | @end |
3121 | |
3122 | === modified file 'musicstreaming/utilities/ArtistListParser.m' |
3123 | --- musicstreaming/utilities/ArtistListParser.m 2011-04-19 08:38:37 +0000 |
3124 | +++ musicstreaming/utilities/ArtistListParser.m 2011-06-13 16:58:33 +0000 |
3125 | @@ -22,23 +22,6 @@ |
3126 | |
3127 | @implementation ArtistListParser |
3128 | |
3129 | -@synthesize artists, indexes, groupedArtists; |
3130 | -@synthesize artist, index; |
3131 | - |
3132 | -- (id)init |
3133 | -{ |
3134 | - if ((self = [super init])) |
3135 | - { |
3136 | - artists = [[NSMutableArray alloc] init]; |
3137 | - indexes = [[NSMutableArray alloc] init]; |
3138 | - groupedArtists = [[NSMutableDictionary alloc] init]; |
3139 | - self.artist = NULL; |
3140 | - self.index = NULL; |
3141 | - } |
3142 | - return self; |
3143 | -} |
3144 | - |
3145 | - |
3146 | - (void)subsonicErrorCode:(NSString *)errorCode message:(NSString *)message |
3147 | { |
3148 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:message delegate:nil cancelButtonTitle:NSLocalizedString(@"Dismiss", @"") otherButtonTitles:nil]; |
3149 | @@ -46,57 +29,22 @@ |
3150 | [alert release]; |
3151 | } |
3152 | |
3153 | - |
3154 | - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict |
3155 | { |
3156 | if ([elementName isEqualToString:@"error"]) |
3157 | { |
3158 | [self subsonicErrorCode:[attributeDict objectForKey:@"code"] message:[attributeDict objectForKey:@"message"]]; |
3159 | } |
3160 | - else if ([elementName isEqualToString:@"index"]) //letters that appear on the right side of the table. |
3161 | - { |
3162 | - self.index = [attributeDict objectForKey:@"name"]; |
3163 | - [indexes addObject:self.index]; |
3164 | - [groupedArtists setObject:[NSMutableArray array] forKey:self.index]; |
3165 | - } |
3166 | else if ([elementName isEqualToString:@"artist"]) |
3167 | { |
3168 | if (![Artist artistWithIdExists:[attributeDict objectForKey:@"id"]] && ![[attributeDict objectForKey:@"name"] isEqual:@".AppleDouble"]) |
3169 | { |
3170 | - self.artist = [NSEntityDescription insertNewObjectForEntityForName:@"Artist" inManagedObjectContext:PerThreadManagedObjectContext()]; |
3171 | - self.artist.name = [attributeDict objectForKey:@"name"]; |
3172 | - self.artist.artistId = [attributeDict objectForKey:@"id"]; |
3173 | - |
3174 | - [artists addObject:self.artist]; |
3175 | - NSMutableArray *group = [groupedArtists objectForKey:self.index]; |
3176 | - [group addObject:self.artist]; |
3177 | + Artist *artist = [NSEntityDescription insertNewObjectForEntityForName:@"Artist" inManagedObjectContext:PerThreadManagedObjectContext()]; |
3178 | + artist.name = [attributeDict objectForKey:@"name"]; |
3179 | + artist.artistId = [attributeDict objectForKey:@"id"]; |
3180 | + SaveContext(); |
3181 | } |
3182 | } |
3183 | } |
3184 | |
3185 | - |
3186 | -- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName |
3187 | -{ |
3188 | - if ([elementName isEqualToString:@"artist"]) |
3189 | - { |
3190 | - SaveContext(); |
3191 | - self.artist = NULL; |
3192 | - } |
3193 | - else if ([elementName isEqualToString:@"index"]) |
3194 | - { |
3195 | - self.index = NULL; |
3196 | - } |
3197 | -} |
3198 | - |
3199 | - |
3200 | -- (void) dealloc |
3201 | -{ |
3202 | - self.artist = NULL; |
3203 | - self.index = NULL; |
3204 | - RELEASE_SAFELY(groupedArtists); |
3205 | - RELEASE_SAFELY(artists); |
3206 | - RELEASE_SAFELY(indexes); |
3207 | - [super dealloc]; |
3208 | -} |
3209 | - |
3210 | @end |
3211 | \ No newline at end of file |
3212 | |
3213 | === modified file 'musicstreaming/utilities/ArtistParser.m' |
3214 | --- musicstreaming/utilities/ArtistParser.m 2011-05-02 07:19:18 +0000 |
3215 | +++ musicstreaming/utilities/ArtistParser.m 2011-06-13 16:58:33 +0000 |
3216 | @@ -68,20 +68,17 @@ |
3217 | |
3218 | if (nil == album) |
3219 | { |
3220 | - Album *album = [NSEntityDescription insertNewObjectForEntityForName:@"Album" inManagedObjectContext:PerThreadManagedObjectContext()]; |
3221 | + album = [NSEntityDescription insertNewObjectForEntityForName:@"Album" inManagedObjectContext:PerThreadManagedObjectContext()]; |
3222 | |
3223 | album.title = [attributeDict objectForKey:@"title"]; |
3224 | album.albumId = [attributeDict objectForKey:@"id"]; |
3225 | - |
3226 | - if ([attributeDict objectForKey:@"coverArt"]) |
3227 | - { |
3228 | - album.coverArtId = [attributeDict objectForKey:@"coverArt"]; |
3229 | - } |
3230 | + album.coverArtId = [attributeDict objectForKey:@"coverArt"]; |
3231 | |
3232 | [artist addAlbumsObject:album]; |
3233 | SaveContext(); |
3234 | } |
3235 | - else if (nil == album.artistEntity) |
3236 | + |
3237 | + if (nil == album.artistEntity) |
3238 | { |
3239 | album.artistEntity = artist; |
3240 | SaveContext(); |
3241 | |
3242 | === modified file 'musicstreaming/utilities/AudioStreamer.h' |
3243 | --- musicstreaming/utilities/AudioStreamer.h 2010-10-01 22:26:06 +0000 |
3244 | +++ musicstreaming/utilities/AudioStreamer.h 2011-06-13 16:58:33 +0000 |
3245 | @@ -23,7 +23,7 @@ |
3246 | |
3247 | #define LOG_QUEUED_BUFFERS 0 |
3248 | |
3249 | -#define kNumAQBufs 32 // Number of audio queue buffers we allocate. |
3250 | +#define kNumAQBufs 64 // Number of audio queue buffers we allocate. |
3251 | // Needs to be big enough to keep audio pipeline |
3252 | // busy (non-zero number of queued buffers) but |
3253 | // not so big that audio takes too long to begin |
3254 | @@ -100,6 +100,7 @@ |
3255 | |
3256 | @interface AudioStreamer : NSObject |
3257 | { |
3258 | + UIBackgroundTaskIdentifier bgTaskId; |
3259 | NSURL *url; |
3260 | |
3261 | // |
3262 | @@ -155,6 +156,9 @@ |
3263 | // time) |
3264 | double packetDuration; // sample rate times frames per packet |
3265 | double lastProgress; // last calculated progress point |
3266 | + |
3267 | + // Flag to indicate if we are playing fixed length files. |
3268 | + BOOL fixedLength; |
3269 | } |
3270 | |
3271 | @property AudioStreamerErrorCode errorCode; |
3272 | @@ -165,6 +169,7 @@ |
3273 | @property (readonly) NSDictionary *httpHeaders; |
3274 | |
3275 | - (id)initWithURL:(NSURL *)aURL; |
3276 | +- (id)initWithFileURL:(NSURL*)aURL; |
3277 | - (void)start; |
3278 | - (void)stop; |
3279 | - (void)stop:(BOOL)force; |
3280 | |
3281 | === modified file 'musicstreaming/utilities/AudioStreamer.m' |
3282 | --- musicstreaming/utilities/AudioStreamer.m 2010-10-01 22:26:06 +0000 |
3283 | +++ musicstreaming/utilities/AudioStreamer.m 2011-06-13 16:58:33 +0000 |
3284 | @@ -225,12 +225,25 @@ |
3285 | self = [super init]; |
3286 | if (self != nil) |
3287 | { |
3288 | + fixedLength = NO; |
3289 | url = [aURL retain]; |
3290 | } |
3291 | return self; |
3292 | } |
3293 | |
3294 | // |
3295 | +// initWithFileURL |
3296 | +// |
3297 | +// Initialize with a local MP3 |
3298 | +// |
3299 | +- (id)initWithFileURL:(NSURL*)aURL |
3300 | +{ |
3301 | + [self initWithURL:aURL]; |
3302 | + fixedLength = YES; |
3303 | + return self; |
3304 | +} |
3305 | + |
3306 | +// |
3307 | // dealloc |
3308 | // |
3309 | // Releases instance memory. |
3310 | @@ -620,57 +633,64 @@ |
3311 | @"File stream download must be started on the internalThread"); |
3312 | NSAssert(stream == nil, @"Download stream already initialized"); |
3313 | |
3314 | - // |
3315 | - // Create the HTTP GET request |
3316 | - // |
3317 | - CFHTTPMessageRef message= CFHTTPMessageCreateRequest(NULL, (CFStringRef)@"GET", (CFURLRef)url, kCFHTTPVersion1_1); |
3318 | - |
3319 | - // |
3320 | - // If we are creating this request to seek to a location, set the |
3321 | - // requested byte range in the headers. |
3322 | - // |
3323 | - if (fileLength > 0 && seekByteOffset > 0) |
3324 | - { |
3325 | - CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Range"), |
3326 | - (CFStringRef)[NSString stringWithFormat:@"bytes=%ld-%ld", seekByteOffset, fileLength]); |
3327 | - discontinuous = YES; |
3328 | - } |
3329 | - |
3330 | - // |
3331 | - // Create the read stream that will receive data from the HTTP request |
3332 | - // |
3333 | - stream = CFReadStreamCreateForHTTPRequest(NULL, message); |
3334 | - CFRelease(message); |
3335 | - |
3336 | - // |
3337 | - // Enable stream redirection |
3338 | - // |
3339 | - if (CFReadStreamSetProperty( |
3340 | - stream, |
3341 | - kCFStreamPropertyHTTPShouldAutoredirect, |
3342 | - kCFBooleanTrue) == false) |
3343 | - { |
3344 | - [self presentAlertWithTitle:NSLocalizedStringFromTable(@"File Error", @"Errors", nil) |
3345 | - message:NSLocalizedStringFromTable(@"Unable to configure network read stream.", @"Errors", nil)]; |
3346 | - return NO; |
3347 | - } |
3348 | - |
3349 | - // |
3350 | - // Handle SSL connections |
3351 | - // |
3352 | - if( [[url absoluteString] rangeOfString:@"https"].location != NSNotFound ) |
3353 | - { |
3354 | - NSDictionary *sslSettings = |
3355 | - [NSDictionary dictionaryWithObjectsAndKeys: |
3356 | - (NSString *)kCFStreamSocketSecurityLevelNegotiatedSSL, kCFStreamSSLLevel, |
3357 | - [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates, |
3358 | - [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredRoots, |
3359 | - [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot, |
3360 | - [NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain, |
3361 | - [NSNull null], kCFStreamSSLPeerName, |
3362 | - nil]; |
3363 | - |
3364 | - CFReadStreamSetProperty(stream, kCFStreamPropertySSLSettings, sslSettings); |
3365 | + if (fixedLength) |
3366 | + { |
3367 | + stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, (CFURLRef)url); |
3368 | + } |
3369 | + else |
3370 | + { |
3371 | + // |
3372 | + // Create the HTTP GET request |
3373 | + // |
3374 | + CFHTTPMessageRef message= CFHTTPMessageCreateRequest(NULL, (CFStringRef)@"GET", (CFURLRef)url, kCFHTTPVersion1_1); |
3375 | + |
3376 | + // |
3377 | + // If we are creating this request to seek to a location, set the |
3378 | + // requested byte range in the headers. |
3379 | + // |
3380 | + if (fileLength > 0 && seekByteOffset > 0) |
3381 | + { |
3382 | + CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Range"), |
3383 | + (CFStringRef)[NSString stringWithFormat:@"bytes=%ld-%ld", seekByteOffset, fileLength]); |
3384 | + discontinuous = YES; |
3385 | + } |
3386 | + |
3387 | + // |
3388 | + // Create the read stream that will receive data from the HTTP request |
3389 | + // |
3390 | + stream = CFReadStreamCreateForHTTPRequest(NULL, message); |
3391 | + CFRelease(message); |
3392 | + |
3393 | + // |
3394 | + // Enable stream redirection |
3395 | + // |
3396 | + if (CFReadStreamSetProperty( |
3397 | + stream, |
3398 | + kCFStreamPropertyHTTPShouldAutoredirect, |
3399 | + kCFBooleanTrue) == false) |
3400 | + { |
3401 | + [self presentAlertWithTitle:NSLocalizedStringFromTable(@"File Error", @"Errors", nil) |
3402 | + message:NSLocalizedStringFromTable(@"Unable to configure network read stream.", @"Errors", nil)]; |
3403 | + return NO; |
3404 | + } |
3405 | + |
3406 | + // |
3407 | + // Handle SSL connections |
3408 | + // |
3409 | + if( [[url absoluteString] rangeOfString:@"https"].location != NSNotFound ) |
3410 | + { |
3411 | + NSDictionary *sslSettings = |
3412 | + [NSDictionary dictionaryWithObjectsAndKeys: |
3413 | + (NSString *)kCFStreamSocketSecurityLevelNegotiatedSSL, kCFStreamSSLLevel, |
3414 | + [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates, |
3415 | + [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredRoots, |
3416 | + [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot, |
3417 | + [NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain, |
3418 | + [NSNull null], kCFStreamSSLPeerName, |
3419 | + nil]; |
3420 | + |
3421 | + CFReadStreamSetProperty(stream, kCFStreamPropertySSLSettings, sslSettings); |
3422 | + } |
3423 | } |
3424 | |
3425 | // |
3426 | @@ -1111,6 +1131,7 @@ |
3427 | else if (state == AS_PAUSED) |
3428 | { |
3429 | err = AudioQueueStart(audioQueue, NULL); |
3430 | + bgTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL]; |
3431 | if (err) |
3432 | { |
3433 | [self failWithErrorCode:AS_AUDIO_QUEUE_START_FAILED]; |
3434 | @@ -1272,19 +1293,21 @@ |
3435 | { |
3436 | if (!httpHeaders) |
3437 | { |
3438 | - CFTypeRef message = |
3439 | - CFReadStreamCopyProperty(stream, kCFStreamPropertyHTTPResponseHeader); |
3440 | - httpHeaders = |
3441 | - (NSDictionary *)CFHTTPMessageCopyAllHeaderFields((CFHTTPMessageRef)message); |
3442 | - CFRelease(message); |
3443 | + CFTypeRef message = CFReadStreamCopyProperty(stream, kCFStreamPropertyHTTPResponseHeader); |
3444 | |
3445 | - // |
3446 | - // Only read the content length if we seeked to time zero, otherwise |
3447 | - // we only have a subset of the total bytes. |
3448 | - // |
3449 | - if (seekByteOffset == 0) |
3450 | + if (message) |
3451 | { |
3452 | - fileLength = [[httpHeaders objectForKey:@"Content-Length"] integerValue]; |
3453 | + httpHeaders = (NSDictionary *)CFHTTPMessageCopyAllHeaderFields((CFHTTPMessageRef)message); |
3454 | + CFRelease(message); |
3455 | + |
3456 | + // |
3457 | + // Only read the content length if we seeked to time zero, otherwise |
3458 | + // we only have a subset of the total bytes. |
3459 | + // |
3460 | + if (seekByteOffset == 0) |
3461 | + { |
3462 | + fileLength = [[httpHeaders objectForKey:@"Content-Length"] integerValue]; |
3463 | + } |
3464 | } |
3465 | } |
3466 | |
3467 | @@ -1415,6 +1438,7 @@ |
3468 | if (self.state == AS_BUFFERING) |
3469 | { |
3470 | err = AudioQueueStart(audioQueue, NULL); |
3471 | + bgTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL]; |
3472 | if (err) |
3473 | { |
3474 | [self failWithErrorCode:AS_AUDIO_QUEUE_START_FAILED]; |
3475 | @@ -1427,6 +1451,7 @@ |
3476 | self.state = AS_WAITING_FOR_QUEUE_TO_START; |
3477 | |
3478 | err = AudioQueueStart(audioQueue, NULL); |
3479 | + bgTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL]; |
3480 | if (err) |
3481 | { |
3482 | [self failWithErrorCode:AS_AUDIO_QUEUE_START_FAILED]; |
3483 | @@ -1888,6 +1913,8 @@ |
3484 | propertyID:(AudioQueuePropertyID)inID |
3485 | { |
3486 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
3487 | + UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid; |
3488 | + |
3489 | |
3490 | @synchronized(self) |
3491 | { |
3492 | @@ -1914,9 +1941,17 @@ |
3493 | // thread destruction order and seems to avoid this crash bug -- or |
3494 | // at least I haven't had it since (nasty hard to reproduce error!) |
3495 | // |
3496 | + |
3497 | + newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL]; |
3498 | [NSRunLoop currentRunLoop]; |
3499 | |
3500 | self.state = AS_PLAYING; |
3501 | + |
3502 | + if (bgTaskId != UIBackgroundTaskInvalid) { |
3503 | + [[UIApplication sharedApplication] endBackgroundTask: bgTaskId]; |
3504 | + } |
3505 | + |
3506 | + bgTaskId = newTaskId; |
3507 | } |
3508 | else |
3509 | { |
3510 | |
3511 | === removed file 'musicstreaming/utilities/DataCache.h' |
3512 | --- musicstreaming/utilities/DataCache.h 2011-03-29 14:22:42 +0000 |
3513 | +++ musicstreaming/utilities/DataCache.h 1970-01-01 00:00:00 +0000 |
3514 | @@ -1,29 +0,0 @@ |
3515 | -// |
3516 | -// DataCache.h |
3517 | -// iSub |
3518 | -// |
3519 | -// Created by Aaron Brethorst on 9/23/10. |
3520 | -// Copyright 2010 Canonical Ltd. |
3521 | -// |
3522 | -// This program is free software: you can redistribute it and/or modify it |
3523 | -// under the terms of the GNU Affero General Public License version 3, |
3524 | -// as published by the Free Software Foundation. |
3525 | -// |
3526 | -// This program is distributed in the hope that it will be useful, but |
3527 | -// WITHOUT ANY WARRANTY; without even the implied warranties of |
3528 | -// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3529 | -// PURPOSE. See the GNU Affero General Public License for more details. |
3530 | -// |
3531 | -// You should have received a copy of the GNU Affero General Public License |
3532 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. |
3533 | - |
3534 | -#import <Foundation/Foundation.h> |
3535 | - |
3536 | -@interface DataCache : NSObject |
3537 | -{ |
3538 | - NSMutableDictionary *cacheDictionary; |
3539 | -} |
3540 | -+ (DataCache*)sharedDataCache; |
3541 | -- (void)setObject:(id<NSCoding>)object forKey:(NSString*)key; |
3542 | -- (id)objectForKey:(NSString*)key; |
3543 | -@end |
3544 | |
3545 | === removed file 'musicstreaming/utilities/DataCache.m' |
3546 | --- musicstreaming/utilities/DataCache.m 2011-03-29 14:22:42 +0000 |
3547 | +++ musicstreaming/utilities/DataCache.m 1970-01-01 00:00:00 +0000 |
3548 | @@ -1,56 +0,0 @@ |
3549 | -// |
3550 | -// DataCache.m |
3551 | -// iSub |
3552 | -// |
3553 | -// Created by Aaron Brethorst on 9/23/10. |
3554 | -// Copyright 2010 Canonical Ltd. |
3555 | -// |
3556 | -// This program is free software: you can redistribute it and/or modify it |
3557 | -// under the terms of the GNU Affero General Public License version 3, |
3558 | -// as published by the Free Software Foundation. |
3559 | -// |
3560 | -// This program is distributed in the hope that it will be useful, but |
3561 | -// WITHOUT ANY WARRANTY; without even the implied warranties of |
3562 | -// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3563 | -// PURPOSE. See the GNU Affero General Public License for more details. |
3564 | -// |
3565 | -// You should have received a copy of the GNU Affero General Public License |
3566 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. |
3567 | - |
3568 | -#import "DataCache.h" |
3569 | -#import "SynthesizeSingleton.h" |
3570 | - |
3571 | -@implementation DataCache |
3572 | - |
3573 | -SYNTHESIZE_SINGLETON_FOR_CLASS(DataCache) |
3574 | - |
3575 | -- (id)init |
3576 | -{ |
3577 | - if ((self = [super init])) |
3578 | - { |
3579 | - cacheDictionary = [[NSMutableDictionary alloc] init]; |
3580 | - } |
3581 | - return self; |
3582 | -} |
3583 | - |
3584 | -- (void)setObject:(id<NSCoding>)object forKey:(NSString*)key |
3585 | -{ |
3586 | - NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object]; |
3587 | - [cacheDictionary setObject:data forKey:key]; |
3588 | -} |
3589 | - |
3590 | -- (id)objectForKey:(NSString*)key |
3591 | -{ |
3592 | - NSData *data = [cacheDictionary objectForKey:key]; |
3593 | - |
3594 | - if (data) |
3595 | - { |
3596 | - return [NSKeyedUnarchiver unarchiveObjectWithData:data]; |
3597 | - } |
3598 | - else |
3599 | - { |
3600 | - return nil; |
3601 | - } |
3602 | -} |
3603 | - |
3604 | -@end |
3605 | |
3606 | === added file 'musicstreaming/utilities/Globals.h' |
3607 | --- musicstreaming/utilities/Globals.h 1970-01-01 00:00:00 +0000 |
3608 | +++ musicstreaming/utilities/Globals.h 2011-06-13 16:58:33 +0000 |
3609 | @@ -0,0 +1,21 @@ |
3610 | +// |
3611 | +// Globals.h |
3612 | +// iSub |
3613 | +// |
3614 | +// Created by Aaron Brethorst on 5/13/11. |
3615 | +// Copyright 2011 Canonical. All rights reserved. |
3616 | +// |
3617 | + |
3618 | +#import <Foundation/Foundation.h> |
3619 | + |
3620 | +NSURL* ApplicationDocumentsDirectory( void ); |
3621 | +NSURL* DatabaseFile( void ); |
3622 | +BOOL CacheContainsFile(NSString *aFilePath); |
3623 | +NSURL* CachedMusicDirectory( void ); |
3624 | +NSString* CachedMusicPathForFilename(NSString *aFileName); |
3625 | +NSURL* CachedAlbumArtDirectory( void ); |
3626 | +NSString* CachedAlbumArtPathForArtId(NSString *anArtId); |
3627 | + |
3628 | +extern NSString * const NOTIF_downloadComplete; |
3629 | +extern NSString * const NOTIF_removeCachedContent; |
3630 | +extern NSString * const NOTIF_reloadAccountCredentials; |
3631 | |
3632 | === added file 'musicstreaming/utilities/Globals.m' |
3633 | --- musicstreaming/utilities/Globals.m 1970-01-01 00:00:00 +0000 |
3634 | +++ musicstreaming/utilities/Globals.m 2011-06-13 16:58:33 +0000 |
3635 | @@ -0,0 +1,51 @@ |
3636 | +// |
3637 | +// Globals.m |
3638 | +// iSub |
3639 | +// |
3640 | +// Created by Aaron Brethorst on 5/13/11. |
3641 | +// Copyright 2011 Canonical. All rights reserved. |
3642 | +// |
3643 | + |
3644 | +#import "Globals.h" |
3645 | + |
3646 | +NSURL* ApplicationDocumentsDirectory( void ) |
3647 | +{ |
3648 | + return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; |
3649 | +} |
3650 | + |
3651 | +NSURL* DatabaseFile( void ) |
3652 | +{ |
3653 | + NSURL* docs = ApplicationDocumentsDirectory(); |
3654 | + return [docs URLByAppendingPathComponent:@"music.sqlite"]; |
3655 | +} |
3656 | + |
3657 | +BOOL CacheContainsFile(NSString *aFilePath) |
3658 | +{ |
3659 | + return [[NSFileManager defaultManager] fileExistsAtPath:aFilePath]; |
3660 | +} |
3661 | + |
3662 | +NSURL* CachedMusicDirectory( void ) |
3663 | +{ |
3664 | + NSURL* docs = ApplicationDocumentsDirectory(); |
3665 | + return [docs URLByAppendingPathComponent:@"cached_music"]; |
3666 | +} |
3667 | + |
3668 | +NSString* CachedMusicPathForFilename(NSString *aFileName) |
3669 | +{ |
3670 | + return [[CachedMusicDirectory() path] stringByAppendingPathComponent:aFileName]; |
3671 | +} |
3672 | + |
3673 | +NSURL* CachedAlbumArtDirectory( void ) |
3674 | +{ |
3675 | + NSURL* docs = ApplicationDocumentsDirectory(); |
3676 | + return [docs URLByAppendingPathComponent:@"cached_album_art"]; |
3677 | +} |
3678 | + |
3679 | +NSString* CachedAlbumArtPathForArtId(NSString *anArtId) |
3680 | +{ |
3681 | + return [[CachedAlbumArtDirectory() path] stringByAppendingPathComponent:anArtId]; |
3682 | +} |
3683 | + |
3684 | +NSString * const NOTIF_downloadComplete = @"DownloadComplete"; |
3685 | +NSString * const NOTIF_removeCachedContent = @"RemoveCachedContent"; |
3686 | +NSString * const NOTIF_reloadAccountCredentials = @"ReloadAccountCredentials"; |
3687 | |
3688 | === modified file 'musicstreaming/utilities/PlaylistListParser.h' |
3689 | --- musicstreaming/utilities/PlaylistListParser.h 2011-04-07 16:11:14 +0000 |
3690 | +++ musicstreaming/utilities/PlaylistListParser.h 2011-06-13 16:58:33 +0000 |
3691 | @@ -21,7 +21,5 @@ |
3692 | |
3693 | @interface PlaylistListParser : NSObject <NSXMLParserDelegate> |
3694 | { |
3695 | - NSMutableArray *names; |
3696 | } |
3697 | -@property(nonatomic,retain) NSMutableArray *names; |
3698 | @end |
3699 | |
3700 | === modified file 'musicstreaming/utilities/PlaylistListParser.m' |
3701 | --- musicstreaming/utilities/PlaylistListParser.m 2011-04-07 20:51:01 +0000 |
3702 | +++ musicstreaming/utilities/PlaylistListParser.m 2011-06-13 16:58:33 +0000 |
3703 | @@ -22,18 +22,6 @@ |
3704 | |
3705 | @implementation PlaylistListParser |
3706 | |
3707 | -@synthesize names; |
3708 | - |
3709 | -- (id)init |
3710 | -{ |
3711 | - if ((self = [super init])) |
3712 | - { |
3713 | - names = [[NSMutableArray alloc] init]; |
3714 | - } |
3715 | - return self; |
3716 | -} |
3717 | - |
3718 | - |
3719 | - (void) subsonicErrorCode:(NSString *)errorCode message:(NSString *)message |
3720 | { |
3721 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:message delegate:nil cancelButtonTitle:NSLocalizedString(@"Dismiss", @"") otherButtonTitles:nil]; |
3722 | @@ -49,22 +37,16 @@ |
3723 | } |
3724 | else if ([elementName isEqualToString:@"playlist"]) |
3725 | { |
3726 | - Playlist *playlist = [[[Playlist alloc] init] autorelease]; |
3727 | - playlist.name = [attributeDict objectForKey:@"name"]; |
3728 | - playlist.playlistId = [attributeDict objectForKey:@"id"]; |
3729 | - |
3730 | - if (![playlist.name isEqual:@".AppleDouble"]) |
3731 | + if (![Playlist playlistWithIdExists:[attributeDict objectForKey:@"id"]] && ![[attributeDict objectForKey:@"title"] isEqual:@".AppleDouble"]) |
3732 | { |
3733 | - [names addObject:playlist]; |
3734 | - } |
3735 | - } |
3736 | -} |
3737 | - |
3738 | - |
3739 | -- (void) dealloc |
3740 | -{ |
3741 | - RELEASE_SAFELY(names); |
3742 | - [super dealloc]; |
3743 | + Playlist *playlist = [NSEntityDescription insertNewObjectForEntityForName:@"Playlist" inManagedObjectContext:PerThreadManagedObjectContext()]; |
3744 | + |
3745 | + playlist.name = [attributeDict objectForKey:@"name"]; |
3746 | + playlist.playlistId = [attributeDict objectForKey:@"id"]; |
3747 | + |
3748 | + SaveContext(); |
3749 | + } |
3750 | + } |
3751 | } |
3752 | |
3753 | @end |
3754 | |
3755 | === modified file 'musicstreaming/utilities/PlaylistParser.h' |
3756 | --- musicstreaming/utilities/PlaylistParser.h 2011-04-13 15:27:34 +0000 |
3757 | +++ musicstreaming/utilities/PlaylistParser.h 2011-06-13 16:58:33 +0000 |
3758 | @@ -19,15 +19,14 @@ |
3759 | |
3760 | #import <Foundation/Foundation.h> |
3761 | |
3762 | +@class Playlist; |
3763 | + |
3764 | @interface PlaylistParser : NSObject <NSXMLParserDelegate> |
3765 | { |
3766 | - NSString *playlistId; |
3767 | - NSString *name; |
3768 | - NSMutableArray *contents; |
3769 | - NSMutableArray *songIds; |
3770 | + Playlist *playlist; |
3771 | + NSMutableArray *songs; |
3772 | + NSNumberFormatter *numberFormatter; |
3773 | } |
3774 | -@property(nonatomic,retain) NSString *playlistId; |
3775 | -@property(nonatomic,retain) NSString *name; |
3776 | -@property(nonatomic,retain) NSMutableArray *contents; |
3777 | -@property(nonatomic,retain) NSMutableArray *songIds; |
3778 | +@property(nonatomic,retain) NSManagedObjectID *playlistObjectId; |
3779 | +@property(nonatomic,retain) NSMutableArray *songs; |
3780 | @end |
3781 | |
3782 | === modified file 'musicstreaming/utilities/PlaylistParser.m' |
3783 | --- musicstreaming/utilities/PlaylistParser.m 2011-04-13 15:27:34 +0000 |
3784 | +++ musicstreaming/utilities/PlaylistParser.m 2011-06-13 16:58:33 +0000 |
3785 | @@ -18,25 +18,24 @@ |
3786 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
3787 | |
3788 | #import "PlaylistParser.h" |
3789 | +#import "Playlist.h" |
3790 | #import "Song.h" |
3791 | - |
3792 | +#import "NSDictionary+Extras.h" |
3793 | |
3794 | @implementation PlaylistParser |
3795 | -@synthesize playlistId, name, contents, songIds; |
3796 | +@synthesize songs; |
3797 | +@dynamic playlistObjectId; |
3798 | |
3799 | - (id)init |
3800 | { |
3801 | if ((self = [super init])) |
3802 | { |
3803 | - playlistId = nil; |
3804 | - name = nil; |
3805 | - contents = [[NSMutableArray alloc] init]; |
3806 | - songIds = [[NSMutableArray alloc] init]; |
3807 | + songs = [[NSMutableArray alloc] init]; |
3808 | + numberFormatter = [[NSNumberFormatter alloc] init]; |
3809 | } |
3810 | return self; |
3811 | } |
3812 | |
3813 | - |
3814 | - (void) subsonicErrorCode:(NSString *)errorCode message:(NSString *)message |
3815 | { |
3816 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:message delegate:nil cancelButtonTitle:NSLocalizedString(@"Dismiss", @"") otherButtonTitles:nil]; |
3817 | @@ -50,32 +49,61 @@ |
3818 | { |
3819 | [self subsonicErrorCode:[attributeDict objectForKey:@"code"] message:[attributeDict objectForKey:@"message"]]; |
3820 | } |
3821 | - else if ([elementName isEqualToString:@"playlist"]) |
3822 | - { |
3823 | - if (![[attributeDict objectForKey:@"name"] isEqual:@".AppleDouble"]) |
3824 | + else if ([elementName isEqualToString:@"entry"]) |
3825 | + { |
3826 | + Song *song = [Song songWithId:[attributeDict objectForKey:@"id"]]; |
3827 | + |
3828 | + if (nil == song) |
3829 | { |
3830 | - self.playlistId = [attributeDict objectForKey:@"id"]; |
3831 | - self.name = [attributeDict objectForKey:@"name"]; |
3832 | + song = [NSEntityDescription insertNewObjectForEntityForName:@"Song" inManagedObjectContext:PerThreadManagedObjectContext()]; |
3833 | + |
3834 | + song.title = [attributeDict nilifiedValueForKey:@"title"]; |
3835 | + song.songId = [attributeDict nilifiedValueForKey:@"id"]; |
3836 | + song.artist = [attributeDict nilifiedValueForKey:@"artist"]; |
3837 | + |
3838 | + song.album = [attributeDict nilifiedValueForKey:@"album"]; |
3839 | + song.genre = [attributeDict nilifiedValueForKey:@"genre"]; |
3840 | + |
3841 | + song.coverArtId = [attributeDict nilifiedValueForKey:@"coverArt"]; |
3842 | + |
3843 | + song.path = [attributeDict nilifiedValueForKey:@"path"]; |
3844 | + |
3845 | + song.duration = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"duration"]]; |
3846 | + song.bitRate = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"bitRate"]]; |
3847 | + song.track = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"track"]]; |
3848 | + song.year = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"year"]]; |
3849 | + song.size = [numberFormatter numberFromString:[attributeDict nilifiedValueForKey:@"size"]]; |
3850 | + |
3851 | } |
3852 | - } |
3853 | - else if ([elementName isEqualToString:@"entry"]) |
3854 | - { |
3855 | - Song *song = [[Song alloc] initWithDictionary:attributeDict]; |
3856 | - [contents addObject:song]; |
3857 | - [songIds addObject:song.songId]; |
3858 | - [song release]; |
3859 | + |
3860 | + // do something with the order of songs. |
3861 | + [song addPlaylistEntitiesObject:playlist]; |
3862 | + [playlist addSongsObject:song]; |
3863 | + SaveContext(); |
3864 | } |
3865 | } |
3866 | |
3867 | - |
3868 | - (void) dealloc |
3869 | { |
3870 | - playlistId = NULL; |
3871 | - name = NULL; |
3872 | - RELEASE_SAFELY(contents); |
3873 | - RELEASE_SAFELY(songIds); |
3874 | + [numberFormatter release]; |
3875 | + [playlist release]; |
3876 | + [songs release]; |
3877 | [super dealloc]; |
3878 | } |
3879 | |
3880 | +#pragma mark - |
3881 | +#pragma mark Accessors |
3882 | + |
3883 | +- (void)setPlaylistObjectId:(NSManagedObjectID *)oid |
3884 | +{ |
3885 | + Playlist *aPlaylist = [[PerThreadManagedObjectContext() objectWithID:oid] retain]; |
3886 | + [playlist release]; |
3887 | + playlist = aPlaylist; |
3888 | +} |
3889 | + |
3890 | +- (NSManagedObjectID*)playlistObjectID |
3891 | +{ |
3892 | + return [playlist objectID]; |
3893 | +} |
3894 | |
3895 | @end |
3896 | |
3897 | === modified file 'musicstreaming/utilities/StreamingPlayer.m' |
3898 | --- musicstreaming/utilities/StreamingPlayer.m 2011-04-08 19:47:46 +0000 |
3899 | +++ musicstreaming/utilities/StreamingPlayer.m 2011-06-13 16:58:33 +0000 |
3900 | @@ -154,7 +154,17 @@ |
3901 | { |
3902 | [self destroyStreamer]; |
3903 | |
3904 | - AudioStreamer *as = [[AudioStreamer alloc] initWithURL:songUrl]; |
3905 | + AudioStreamer *as = nil; |
3906 | + |
3907 | + if ([self.currentSong cachedSongExists]) |
3908 | + { |
3909 | + as = [[AudioStreamer alloc] initWithFileURL:[self.currentSong cachedSongURL]]; |
3910 | + } |
3911 | + else |
3912 | + { |
3913 | + as = [[AudioStreamer alloc] initWithURL:songUrl]; |
3914 | + } |
3915 | + |
3916 | self.streamer = as; |
3917 | [as release]; |
3918 | #if DEBUG_STREAMER_RETAIN |
3919 | |
3920 | === modified file 'musicstreaming/utilities/Subsonic.m' |
3921 | --- musicstreaming/utilities/Subsonic.m 2011-04-19 01:50:55 +0000 |
3922 | +++ musicstreaming/utilities/Subsonic.m 2011-06-13 16:58:33 +0000 |
3923 | @@ -36,7 +36,9 @@ |
3924 | if ((self = [super init])) |
3925 | { |
3926 | self.defaultURL = @"https://streaming.one.ubuntu.com/rest"; |
3927 | +// self.defaultURL = @"http://10.59.1.19:35204/musicstreaming/rest"; |
3928 | self.credsURL = @"https://one.ubuntu.com/phones/creds/ios?scheme=x-ubuntuone-music"; |
3929 | +// self.credsURL = @"http://10.59.1.19:41858/phones/creds/ios?scheme=x-ubuntuone-music"; |
3930 | } |
3931 | return self; |
3932 | } |
3933 | @@ -105,7 +107,9 @@ |
3934 | [params addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"v", @"1.1.0", nil]]; |
3935 | [params addKeyValueObjectFromArray:[NSArray arrayWithObjects:@"c", @"iSub", nil]]; |
3936 | |
3937 | - return [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@?%@", self.defaultURL, action, [params urlEncodedString]]]; |
3938 | + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@?%@", self.defaultURL, action, [params urlEncodedString]]]; |
3939 | + NSLog(@"URL generated: %@", url); |
3940 | + return url; |
3941 | } |
3942 | else |
3943 | { |
3944 | |
3945 | === added directory 'musicstreaming/utilities/operations' |
3946 | === added file 'musicstreaming/utilities/operations/AbstractNetworkOperation.h' |
3947 | --- musicstreaming/utilities/operations/AbstractNetworkOperation.h 1970-01-01 00:00:00 +0000 |
3948 | +++ musicstreaming/utilities/operations/AbstractNetworkOperation.h 2011-06-13 16:58:33 +0000 |
3949 | @@ -0,0 +1,35 @@ |
3950 | +// |
3951 | +// AbstractNetworkOperation.h |
3952 | +// iSub |
3953 | +// |
3954 | +// Created by Aaron Brethorst on 5/12/11. |
3955 | +// Copyright 2011 Canonical. All rights reserved. |
3956 | +// |
3957 | + |
3958 | +#import <Foundation/Foundation.h> |
3959 | + |
3960 | +@interface AbstractNetworkOperation : NSOperation |
3961 | +{ |
3962 | + NSURL * _url; |
3963 | + NSURLConnection * _connection; |
3964 | + NSInteger _statusCode; |
3965 | + NSError * _error; |
3966 | + |
3967 | + BOOL _isExecuting; |
3968 | + BOOL _isFinished; |
3969 | +} |
3970 | +@property (readonly, copy) NSURL * url; |
3971 | +@property (readonly) NSInteger statusCode; |
3972 | +@property (readonly, retain) NSError * error; |
3973 | + |
3974 | +@property (readonly) BOOL isExecuting; |
3975 | +@property (readonly) BOOL isFinished; |
3976 | + |
3977 | +- (id)initWithUrl:(NSURL *)url; |
3978 | + |
3979 | +//NSURLConnection delegate methods (for subclasses to implement) |
3980 | +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response; |
3981 | +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data; |
3982 | +- (void)connectionDidFinishLoading:(NSURLConnection *)connection; |
3983 | +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error; |
3984 | +@end |
3985 | |
3986 | === added file 'musicstreaming/utilities/operations/AbstractNetworkOperation.m' |
3987 | --- musicstreaming/utilities/operations/AbstractNetworkOperation.m 1970-01-01 00:00:00 +0000 |
3988 | +++ musicstreaming/utilities/operations/AbstractNetworkOperation.m 2011-06-13 16:58:33 +0000 |
3989 | @@ -0,0 +1,116 @@ |
3990 | +// |
3991 | +// AbstractNetworkOperation.m |
3992 | +// iSub |
3993 | +// |
3994 | +// Created by Aaron Brethorst on 5/12/11. |
3995 | +// Copyright 2011 Canonical. All rights reserved. |
3996 | +// |
3997 | + |
3998 | +#import "AbstractNetworkOperation.h" |
3999 | + |
4000 | +@interface AbstractNetworkOperation () |
4001 | +- (void)finish; |
4002 | +@end |
4003 | + |
4004 | +@implementation AbstractNetworkOperation |
4005 | +@synthesize url = _url; |
4006 | +@synthesize statusCode = _statusCode; |
4007 | +@synthesize error = _error; |
4008 | +@synthesize isExecuting = _isExecuting; |
4009 | +@synthesize isFinished = _isFinished; |
4010 | + |
4011 | +- (id)initWithUrl:(NSURL *)url |
4012 | +{ |
4013 | + self = [super init]; |
4014 | + if (self == nil) |
4015 | + return nil; |
4016 | + |
4017 | + _url = [url copy]; |
4018 | + _isExecuting = NO; |
4019 | + _isFinished = NO; |
4020 | + |
4021 | + return self; |
4022 | +} |
4023 | + |
4024 | +- (void)dealloc |
4025 | +{ |
4026 | + [_url release]; |
4027 | + [_connection release]; |
4028 | + [_error release]; |
4029 | + [super dealloc]; |
4030 | +} |
4031 | + |
4032 | +- (BOOL)isConcurrent |
4033 | +{ |
4034 | + return YES; |
4035 | +} |
4036 | + |
4037 | +- (void)start |
4038 | +{ |
4039 | + if (![NSThread isMainThread]) |
4040 | + { |
4041 | + [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO]; |
4042 | + return; |
4043 | + } |
4044 | + |
4045 | + NSLog(@"operation for <%@> started.", _url); |
4046 | + |
4047 | + [self willChangeValueForKey:@"isExecuting"]; |
4048 | + _isExecuting = YES; |
4049 | + [self didChangeValueForKey:@"isExecuting"]; |
4050 | + |
4051 | + NSURLRequest * request = [NSURLRequest requestWithURL:_url]; |
4052 | + _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; |
4053 | + if (nil == _connection) |
4054 | + { |
4055 | + [self finish]; |
4056 | + } |
4057 | +} |
4058 | + |
4059 | +- (void)finish |
4060 | +{ |
4061 | + NSLog(@"operation for <%@> finished. " |
4062 | + @"status code: %d, error: %@", |
4063 | + _url, _statusCode, _error); |
4064 | + |
4065 | + [_connection release]; |
4066 | + _connection = nil; |
4067 | + |
4068 | + [self willChangeValueForKey:@"isExecuting"]; |
4069 | + [self willChangeValueForKey:@"isFinished"]; |
4070 | + |
4071 | + _isExecuting = NO; |
4072 | + _isFinished = YES; |
4073 | + |
4074 | + [self didChangeValueForKey:@"isExecuting"]; |
4075 | + [self didChangeValueForKey:@"isFinished"]; |
4076 | +} |
4077 | + |
4078 | +#pragma mark - |
4079 | +#pragma mark NSURLConnection delegate |
4080 | + |
4081 | +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response |
4082 | +{ |
4083 | + NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response; |
4084 | + _statusCode = [httpResponse statusCode]; |
4085 | +} |
4086 | + |
4087 | +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data |
4088 | +{ |
4089 | + //no-op, subclasses must implement this. |
4090 | +} |
4091 | + |
4092 | +- (void)connectionDidFinishLoading:(NSURLConnection *)connection |
4093 | +{ |
4094 | + [self finish]; |
4095 | +} |
4096 | + |
4097 | +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error |
4098 | +{ |
4099 | + _error = [error copy]; |
4100 | + [self finish]; |
4101 | +} |
4102 | + |
4103 | + |
4104 | + |
4105 | +@end |
4106 | |
4107 | === renamed file 'musicstreaming/utilities/ImageLoader.h' => 'musicstreaming/utilities/operations/AlbumArtLoader.h' |
4108 | --- musicstreaming/utilities/ImageLoader.h 2011-05-05 16:52:14 +0000 |
4109 | +++ musicstreaming/utilities/operations/AlbumArtLoader.h 2011-06-13 16:58:33 +0000 |
4110 | @@ -1,5 +1,5 @@ |
4111 | // |
4112 | -// ImageLoader.h |
4113 | +// AlbumArtLoader.h |
4114 | // iSub |
4115 | // |
4116 | // Created by Aaron Brethorst on 5/4/11. |
4117 | @@ -7,25 +7,28 @@ |
4118 | // |
4119 | |
4120 | #import <UIKit/UIKit.h> |
4121 | -#import "ImageLoadingOperation.h" |
4122 | +#import "AlbumArtLoadingOperation.h" |
4123 | |
4124 | -@protocol ImageLoaderDelegate<NSObject> |
4125 | +@protocol AlbumArtLoaderDelegate<NSObject> |
4126 | - (void)reloadImages; |
4127 | @optional |
4128 | - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; |
4129 | @end |
4130 | |
4131 | |
4132 | -@interface ImageLoader : NSObject <ImageLoadingOperationDelegate> |
4133 | +@interface AlbumArtLoader : NSObject <AlbumArtLoadingOperationDelegate> |
4134 | { |
4135 | NSMutableSet *downloadedURLs; |
4136 | NSMutableDictionary *downloadCache; |
4137 | NSOperationQueue *queue; |
4138 | - id<ImageLoaderDelegate> delegate; |
4139 | + id<AlbumArtLoaderDelegate> delegate; |
4140 | int imageSize; |
4141 | + UIImage *defaultAlbumArt; |
4142 | } |
4143 | @property(nonatomic) int imageSize; |
4144 | -@property(nonatomic,assign) id<ImageLoaderDelegate> delegate; |
4145 | -- (UIImage*)imageForArtID:(NSString*)artID; |
4146 | +@property(nonatomic,assign) id<AlbumArtLoaderDelegate> delegate; |
4147 | +@property(nonatomic,retain) UIImage *defaultAlbumArt; |
4148 | +- (UIImage*)imageForArtID:(NSString*)artID error:(NSError**)error; |
4149 | - (void)download:(NSString*)artID; |
4150 | ++ (NSString*)cacheSize; |
4151 | @end |
4152 | |
4153 | === renamed file 'musicstreaming/utilities/ImageLoader.m' => 'musicstreaming/utilities/operations/AlbumArtLoader.m' |
4154 | --- musicstreaming/utilities/ImageLoader.m 2011-05-05 16:52:14 +0000 |
4155 | +++ musicstreaming/utilities/operations/AlbumArtLoader.m 2011-06-13 16:58:33 +0000 |
4156 | @@ -1,30 +1,35 @@ |
4157 | // |
4158 | -// ImageLoader.m |
4159 | +// AlbumArtLoader.m |
4160 | // iSub |
4161 | // |
4162 | // Created by Aaron Brethorst on 5/4/11. |
4163 | // Copyright 2011 Canonical. All rights reserved. |
4164 | // |
4165 | |
4166 | -#import "ImageLoader.h" |
4167 | +#import "AlbumArtLoader.h" |
4168 | #import "Subsonic.h" |
4169 | #import "NSMutableSet+Extras.h" |
4170 | #import "UIImage+Resize.h" |
4171 | |
4172 | -@interface ImageLoader () |
4173 | +@interface AlbumArtLoader () |
4174 | +- (void)createAlbumArtDirectory; |
4175 | - (NSString*)URLFromCoverArtID:(NSString*)artID; |
4176 | @end |
4177 | |
4178 | |
4179 | -@implementation ImageLoader |
4180 | +@implementation AlbumArtLoader |
4181 | @synthesize delegate; |
4182 | @synthesize imageSize; |
4183 | +@synthesize defaultAlbumArt; |
4184 | |
4185 | - (id)init |
4186 | { |
4187 | if ((self = [super init])) |
4188 | { |
4189 | - self.imageSize = 120; |
4190 | + [self createAlbumArtDirectory]; |
4191 | + |
4192 | + self.imageSize = 640; // Default to maximum size we need |
4193 | + self.defaultAlbumArt = [UIImage imageNamed:@"default-album-art"]; |
4194 | |
4195 | downloadCache = [[NSMutableDictionary alloc] init]; |
4196 | downloadedURLs = [[NSMutableSet alloc] init]; |
4197 | @@ -39,6 +44,7 @@ |
4198 | [downloadCache release]; |
4199 | [downloadedURLs release]; |
4200 | [queue release]; |
4201 | + [defaultAlbumArt release]; |
4202 | |
4203 | [super dealloc]; |
4204 | } |
4205 | @@ -46,9 +52,16 @@ |
4206 | #pragma mark - |
4207 | #pragma mark Public Methods |
4208 | |
4209 | -- (UIImage*)imageForArtID:(NSString*)artID |
4210 | +- (UIImage*)imageForArtID:(NSString*)artID error:(NSError**)error |
4211 | { |
4212 | - UIImage *image = [downloadCache objectForKey:[self URLFromCoverArtID:artID]]; |
4213 | + NSString *path = CachedAlbumArtPathForArtId(artID); |
4214 | + UIImage *image = [UIImage imageWithContentsOfFile:path]; |
4215 | + |
4216 | + if (nil == image) { |
4217 | + // Cache fault: return the default image, and set the error so the caller can dispatch for an attempt at download |
4218 | + image = self.defaultAlbumArt; |
4219 | + *error = [NSError errorWithDomain:@"U1Music" code:1 userInfo:nil]; |
4220 | + } |
4221 | return [image resizedImage:CGSizeMake(self.imageSize, self.imageSize) interpolationQuality:kCGInterpolationHigh]; |
4222 | } |
4223 | |
4224 | @@ -67,7 +80,7 @@ |
4225 | { |
4226 | [downloadedURLs addObject:url]; |
4227 | |
4228 | - ImageLoadingOperation *operation = [[ImageLoadingOperation alloc] initWithUrl:url]; |
4229 | + AlbumArtLoadingOperation *operation = [[AlbumArtLoadingOperation alloc] initWithArtId: artID URL:url]; |
4230 | operation.delegate = self; |
4231 | [queue addOperation:operation]; |
4232 | [operation release]; |
4233 | @@ -75,6 +88,30 @@ |
4234 | } |
4235 | } |
4236 | |
4237 | ++ (NSString*)cacheSize |
4238 | +{ |
4239 | + static int minBlock = 4096; |
4240 | + |
4241 | + NSString *file = nil; |
4242 | + NSDictionary *fileAttrs = nil; |
4243 | + |
4244 | + double totalSize = 0; |
4245 | + |
4246 | + NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtPath:[CachedAlbumArtDirectory() path]]; |
4247 | + |
4248 | + while (file = [enumerator nextObject]) |
4249 | + { |
4250 | + fileAttrs = [enumerator fileAttributes]; |
4251 | + |
4252 | + if (![[fileAttrs valueForKey:NSFileType] isEqual:NSFileTypeDirectory]) |
4253 | + { |
4254 | + totalSize += ((([[fileAttrs valueForKey:NSFileSize] unsignedIntValue] + minBlock - 1) / minBlock) * minBlock); |
4255 | + } |
4256 | + } |
4257 | + |
4258 | + return [NSString stringWithFormat:@"%.2f MB",((totalSize / 1024.0f) / 1024.0f)]; |
4259 | +} |
4260 | + |
4261 | #pragma mark - |
4262 | #pragma mark Private Methods |
4263 | |
4264 | @@ -90,14 +127,26 @@ |
4265 | return [url absoluteString]; |
4266 | } |
4267 | |
4268 | +- (void)createAlbumArtDirectory |
4269 | +{ |
4270 | + NSError *error = nil; |
4271 | + BOOL yn = [[NSFileManager defaultManager] createDirectoryAtPath:[CachedAlbumArtDirectory() path] withIntermediateDirectories:YES attributes:nil error:&error]; |
4272 | + |
4273 | + if (!yn || error) |
4274 | + { |
4275 | + NSLog(@"%@", error); |
4276 | + } |
4277 | +} |
4278 | + |
4279 | #pragma mark - |
4280 | -#pragma mark ImageLoadingOperationDelegate |
4281 | +#pragma mark AlbumArtLoadingOperationDelegate |
4282 | |
4283 | -- (void)imageLoaded:(UIImage*)image forURL:(NSURL*)URL |
4284 | +- (void)imageLoaded:(UIImage*)image forArtId:(NSString *)artId |
4285 | { |
4286 | - [downloadCache setObject:image forKey:[URL absoluteString]]; |
4287 | + NSData *imageData = UIImagePNGRepresentation(image); |
4288 | + [imageData writeToFile:CachedAlbumArtPathForArtId(artId) atomically:YES]; |
4289 | |
4290 | - if (self.delegate && [self.delegate respondsToSelector:@selector(reloadImages)]) |
4291 | + if (self.delegate) |
4292 | { |
4293 | [self.delegate performSelectorOnMainThread:@selector(reloadImages) withObject:nil waitUntilDone:NO]; |
4294 | } |
4295 | |
4296 | === renamed file 'musicstreaming/utilities/ImageLoadingOperation.h' => 'musicstreaming/utilities/operations/AlbumArtLoadingOperation.h' |
4297 | --- musicstreaming/utilities/ImageLoadingOperation.h 2011-05-05 07:27:41 +0000 |
4298 | +++ musicstreaming/utilities/operations/AlbumArtLoadingOperation.h 2011-06-13 16:58:33 +0000 |
4299 | @@ -1,5 +1,5 @@ |
4300 | // |
4301 | -// ImageLoadingOperation.h |
4302 | +// AlbumArtLoadingOperation.h |
4303 | // iSub |
4304 | // |
4305 | // Created by Aaron Brethorst on 5/4/11. |
4306 | @@ -7,36 +7,22 @@ |
4307 | // |
4308 | |
4309 | #import <UIKit/UIKit.h> |
4310 | +#import "AbstractNetworkOperation.h" |
4311 | |
4312 | -@protocol ImageLoadingOperationDelegate<NSObject> |
4313 | -- (void)imageLoaded:(UIImage*)image forURL:(NSURL*)URL; |
4314 | +@protocol AlbumArtLoadingOperationDelegate<NSObject> |
4315 | +- (void)imageLoaded:(UIImage*)image forArtId:(NSString *)artId; |
4316 | @end |
4317 | |
4318 | - |
4319 | -@interface ImageLoadingOperation : NSOperation |
4320 | -{ |
4321 | - NSURL * _url; |
4322 | - NSURLConnection * _connection; |
4323 | - NSInteger _statusCode; |
4324 | - NSMutableData * _data; |
4325 | - NSError * _error; |
4326 | - |
4327 | - BOOL _isExecuting; |
4328 | - BOOL _isFinished; |
4329 | - |
4330 | - id<ImageLoadingOperationDelegate> delegate; |
4331 | +@interface AlbumArtLoadingOperation : AbstractNetworkOperation |
4332 | +{ |
4333 | + NSMutableData * _data; |
4334 | + NSString *_artId; |
4335 | + id<AlbumArtLoadingOperationDelegate> delegate; |
4336 | } |
4337 | -@property (nonatomic, assign) id<ImageLoadingOperationDelegate> delegate; |
4338 | -@property (readonly, copy) NSURL * url; |
4339 | -@property (readonly) NSInteger statusCode; |
4340 | +@property (nonatomic, assign) id<AlbumArtLoadingOperationDelegate> delegate; |
4341 | @property (readonly, retain) NSData * data; |
4342 | -@property (readonly, retain) NSError * error; |
4343 | - |
4344 | -@property (readonly) BOOL isExecuting; |
4345 | -@property (readonly) BOOL isFinished; |
4346 | - |
4347 | -+ (id)imageLoaderWithUrlString:(NSString *)urlString; |
4348 | - |
4349 | -- (id)initWithUrl:(NSURL *)url; |
4350 | +- (id)initWithArtId:(NSString *)artId URL:(NSURL *)url; |
4351 | + |
4352 | ++ (id)AlbumArtLoaderWithUrlString:(NSString *)urlString; |
4353 | |
4354 | @end |
4355 | \ No newline at end of file |
4356 | |
4357 | === renamed file 'musicstreaming/utilities/ImageLoadingOperation.m' => 'musicstreaming/utilities/operations/AlbumArtLoadingOperation.m' |
4358 | --- musicstreaming/utilities/ImageLoadingOperation.m 2011-05-05 07:27:41 +0000 |
4359 | +++ musicstreaming/utilities/operations/AlbumArtLoadingOperation.m 2011-06-13 16:58:33 +0000 |
4360 | @@ -1,5 +1,5 @@ |
4361 | // |
4362 | -// ImageLoadingOperation.m |
4363 | +// AlbumArtLoadingOperation.m |
4364 | // iSub |
4365 | // |
4366 | // Created by Aaron Brethorst on 5/4/11. |
4367 | @@ -8,131 +8,68 @@ |
4368 | |
4369 | // adapted from http://www.dribin.org/dave/blog/archives/2009/05/05/concurrent_operations/ |
4370 | |
4371 | -#import "ImageLoadingOperation.h" |
4372 | - |
4373 | -@interface ImageLoadingOperation () |
4374 | -- (void)finish; |
4375 | -@end |
4376 | - |
4377 | -@implementation ImageLoadingOperation |
4378 | +#import "AlbumArtLoadingOperation.h" |
4379 | + |
4380 | +@implementation AlbumArtLoadingOperation |
4381 | @synthesize delegate; |
4382 | -@synthesize url = _url; |
4383 | -@synthesize statusCode = _statusCode; |
4384 | @synthesize data = _data; |
4385 | -@synthesize error = _error; |
4386 | -@synthesize isExecuting = _isExecuting; |
4387 | -@synthesize isFinished = _isFinished; |
4388 | |
4389 | -+ (id)imageLoaderWithUrlString:(NSString *)urlString |
4390 | ++ (id)AlbumArtLoaderWithUrlString:(NSString *)urlString |
4391 | { |
4392 | NSURL * url = [NSURL URLWithString:urlString]; |
4393 | - ImageLoadingOperation * operation = [[self alloc] initWithUrl:url]; |
4394 | + AlbumArtLoadingOperation * operation = [[self alloc] initWithUrl:url]; |
4395 | return [operation autorelease]; |
4396 | } |
4397 | |
4398 | -- (id)initWithUrl:(NSURL *)url |
4399 | +- (id)initWithArtId:(NSString *)artId URL:(NSURL *)url |
4400 | { |
4401 | - self = [super init]; |
4402 | + self = [super initWithUrl:url]; |
4403 | if (self == nil) |
4404 | return nil; |
4405 | |
4406 | - _url = [url copy]; |
4407 | - _isExecuting = NO; |
4408 | - _isFinished = NO; |
4409 | - |
4410 | + _artId = [artId retain]; |
4411 | return self; |
4412 | + |
4413 | } |
4414 | |
4415 | - (void)dealloc |
4416 | { |
4417 | - [_url release]; |
4418 | - [_connection release]; |
4419 | - [_data release]; |
4420 | - [_error release]; |
4421 | - [super dealloc]; |
4422 | -} |
4423 | - |
4424 | -- (BOOL)isConcurrent |
4425 | -{ |
4426 | - return YES; |
4427 | -} |
4428 | - |
4429 | -- (void)start |
4430 | -{ |
4431 | - if (![NSThread isMainThread]) |
4432 | - { |
4433 | - [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO]; |
4434 | - return; |
4435 | - } |
4436 | - |
4437 | - NSLog(@"opeartion for <%@> started.", _url); |
4438 | - |
4439 | - [self willChangeValueForKey:@"isExecuting"]; |
4440 | - _isExecuting = YES; |
4441 | - [self didChangeValueForKey:@"isExecuting"]; |
4442 | - |
4443 | - NSURLRequest * request = [NSURLRequest requestWithURL:_url]; |
4444 | - _connection = [[NSURLConnection alloc] initWithRequest:request |
4445 | - delegate:self]; |
4446 | - if (_connection == nil) |
4447 | - [self finish]; |
4448 | -} |
4449 | - |
4450 | -- (void)finish |
4451 | -{ |
4452 | - NSLog(@"operation for <%@> finished. " |
4453 | - @"status code: %d, error: %@, data size: %u", |
4454 | - _url, _statusCode, _error, [_data length]); |
4455 | - |
4456 | - [_connection release]; |
4457 | - _connection = nil; |
4458 | - |
4459 | - [self willChangeValueForKey:@"isExecuting"]; |
4460 | - [self willChangeValueForKey:@"isFinished"]; |
4461 | - |
4462 | - _isExecuting = NO; |
4463 | - _isFinished = YES; |
4464 | - |
4465 | - [self didChangeValueForKey:@"isExecuting"]; |
4466 | - [self didChangeValueForKey:@"isFinished"]; |
4467 | + [_data release]; |
4468 | + [_artId release]; |
4469 | + [super dealloc]; |
4470 | } |
4471 | |
4472 | #pragma mark - |
4473 | #pragma mark NSURLConnection delegate |
4474 | |
4475 | -- (void)connection:(NSURLConnection *)connection |
4476 | -didReceiveResponse:(NSURLResponse *)response |
4477 | +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response |
4478 | { |
4479 | + [super connection:connection didReceiveResponse:response]; |
4480 | + |
4481 | [_data release]; |
4482 | _data = [[NSMutableData alloc] init]; |
4483 | - |
4484 | - NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response; |
4485 | - _statusCode = [httpResponse statusCode]; |
4486 | } |
4487 | |
4488 | -- (void)connection:(NSURLConnection *)connection |
4489 | - didReceiveData:(NSData *)data |
4490 | +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data |
4491 | { |
4492 | + [super connection:connection didReceiveData:data]; |
4493 | + |
4494 | [_data appendData:data]; |
4495 | } |
4496 | |
4497 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection |
4498 | { |
4499 | - UIImage *image = [[UIImage alloc] initWithData:_data]; |
4500 | + UIImage *image = [[[UIImage alloc] initWithData:_data] autorelease]; |
4501 | if (image) |
4502 | { |
4503 | - [self.delegate imageLoaded:image forURL:_url]; |
4504 | + [self.delegate imageLoaded:image forArtId:_artId]; |
4505 | } |
4506 | - [self finish]; |
4507 | + [super connectionDidFinishLoading:connection]; |
4508 | } |
4509 | |
4510 | -- (void)connection:(NSURLConnection *)connection |
4511 | - didFailWithError:(NSError *)error |
4512 | +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error |
4513 | { |
4514 | - _error = [error copy]; |
4515 | - [self finish]; |
4516 | + [super connection:connection didFailWithError:error]; |
4517 | } |
4518 | |
4519 | - |
4520 | - |
4521 | @end |
4522 | |
4523 | === added file 'musicstreaming/utilities/operations/DownloadOperation.h' |
4524 | --- musicstreaming/utilities/operations/DownloadOperation.h 1970-01-01 00:00:00 +0000 |
4525 | +++ musicstreaming/utilities/operations/DownloadOperation.h 2011-06-13 16:58:33 +0000 |
4526 | @@ -0,0 +1,32 @@ |
4527 | +// |
4528 | +// DownloadOperation.h |
4529 | +// iSub |
4530 | +// |
4531 | +// Created by Aaron Brethorst on 5/12/11. |
4532 | +// Copyright 2011 Canonical. All rights reserved. |
4533 | +// |
4534 | + |
4535 | +#import <UIKit/UIKit.h> |
4536 | +#import "AbstractNetworkOperation.h" |
4537 | + |
4538 | +@protocol DownloadOperationDelegate |
4539 | +- (void)songDownloadedToPath:(NSString*)path; |
4540 | +@optional |
4541 | +- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; |
4542 | +@end |
4543 | + |
4544 | + |
4545 | +@interface DownloadOperation : AbstractNetworkOperation |
4546 | +{ |
4547 | + NSString *_filePath; |
4548 | + NSFileHandle *_fileHandle; |
4549 | + |
4550 | + id<DownloadOperationDelegate> _delegate; |
4551 | +} |
4552 | +@property(nonatomic,retain) NSString *filePath; |
4553 | +@property(nonatomic,assign) id<DownloadOperationDelegate> delegate; |
4554 | + |
4555 | ++ (id)downloadOperationWithURL:(NSURL*)anURL filePath:(NSString*)aFilePath; |
4556 | +- (id)initWithUrl:(NSURL*)anUrl filePath:(NSString*)aFilePath; |
4557 | + |
4558 | +@end |
4559 | \ No newline at end of file |
4560 | |
4561 | === added file 'musicstreaming/utilities/operations/DownloadOperation.m' |
4562 | --- musicstreaming/utilities/operations/DownloadOperation.m 1970-01-01 00:00:00 +0000 |
4563 | +++ musicstreaming/utilities/operations/DownloadOperation.m 2011-06-13 16:58:33 +0000 |
4564 | @@ -0,0 +1,79 @@ |
4565 | +// |
4566 | +// DownloadOperation.m |
4567 | +// iSub |
4568 | +// |
4569 | +// Created by Aaron Brethorst on 5/12/11. |
4570 | +// Copyright 2011 Canonical. All rights reserved. |
4571 | +// |
4572 | + |
4573 | +#import "DownloadOperation.h" |
4574 | + |
4575 | +@implementation DownloadOperation |
4576 | +@synthesize filePath = _filePath; |
4577 | +@synthesize delegate = _delegate; |
4578 | + |
4579 | ++ (id)downloadOperationWithURL:(NSURL*)anURL filePath:(NSString*)aFilePath |
4580 | +{ |
4581 | + DownloadOperation *operation = [[[DownloadOperation alloc] initWithUrl:anURL filePath:aFilePath] autorelease]; |
4582 | + return operation; |
4583 | +} |
4584 | + |
4585 | +- (id)initWithUrl:(NSURL*)anUrl filePath:(NSString*)aFilePath |
4586 | +{ |
4587 | + if ((self = [super initWithUrl:anUrl])) |
4588 | + { |
4589 | + self.delegate = nil; |
4590 | + |
4591 | + self.filePath = aFilePath; |
4592 | + |
4593 | + [[NSFileManager defaultManager] createFileAtPath:self.filePath contents:[NSData data] attributes:nil]; |
4594 | + _fileHandle = [[NSFileHandle fileHandleForWritingAtPath:self.filePath] retain]; |
4595 | + } |
4596 | + return self; |
4597 | +} |
4598 | + |
4599 | +- (void)dealloc |
4600 | +{ |
4601 | + self.delegate = nil; |
4602 | + self.filePath = nil; |
4603 | + [_fileHandle release]; |
4604 | + [super dealloc]; |
4605 | +} |
4606 | + |
4607 | +#pragma mark - |
4608 | +#pragma mark NSURLConnection delegate |
4609 | + |
4610 | +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response |
4611 | +{ |
4612 | + [super connection:connection didReceiveResponse:response]; |
4613 | +} |
4614 | + |
4615 | +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data |
4616 | +{ |
4617 | + [super connection:connection didReceiveData:data]; |
4618 | + |
4619 | + [_fileHandle writeData:data]; |
4620 | +} |
4621 | + |
4622 | +- (void)connectionDidFinishLoading:(NSURLConnection *)connection |
4623 | +{ |
4624 | + [_fileHandle closeFile]; |
4625 | + |
4626 | + if (nil != self.delegate) |
4627 | + { |
4628 | + [self.delegate performSelectorOnMainThread:@selector(songDownloadedToPath:) withObject:self.filePath waitUntilDone:NO]; |
4629 | + } |
4630 | + |
4631 | + [super connectionDidFinishLoading:connection]; |
4632 | +} |
4633 | + |
4634 | +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error |
4635 | +{ |
4636 | + [_fileHandle closeFile]; |
4637 | + [[NSFileManager defaultManager] removeItemAtPath:self.filePath error:nil]; |
4638 | + |
4639 | + [super connection:connection didFailWithError:error]; |
4640 | +} |
4641 | + |
4642 | +@end |
4643 | + |
4644 | |
4645 | === added file 'musicstreaming/utilities/operations/Downloader.h' |
4646 | --- musicstreaming/utilities/operations/Downloader.h 1970-01-01 00:00:00 +0000 |
4647 | +++ musicstreaming/utilities/operations/Downloader.h 2011-06-13 16:58:33 +0000 |
4648 | @@ -0,0 +1,29 @@ |
4649 | +// |
4650 | +// Downloader.h |
4651 | +// iSub |
4652 | +// |
4653 | +// Created by Aaron Brethorst on 5/12/11. |
4654 | +// Copyright 2011 Canonical. All rights reserved. |
4655 | +// |
4656 | + |
4657 | +#import <UIKit/UIKit.h> |
4658 | +#import "DownloadOperation.h" |
4659 | + |
4660 | +@class Artist, Album; |
4661 | + |
4662 | +@interface Downloader : NSObject <DownloadOperationDelegate> |
4663 | +{ |
4664 | + NSOperationQueue *contentEnumerationQueue; |
4665 | + NSOperationQueue *queue; |
4666 | + NSMutableSet *downloads; |
4667 | +} |
4668 | ++ (Downloader*)sharedDownloader; |
4669 | ++ (NSString*)cacheSize; |
4670 | + |
4671 | +- (void)enqueueArtist:(Artist*)anArtist; |
4672 | +- (void)enqueueAlbum:(Album*)anAlbum; |
4673 | +- (void)downloadFile:(NSURL*)url withName:(NSString*)fileName; |
4674 | +- (BOOL)isDownloading:(NSString *)fileName; |
4675 | + |
4676 | +extern NSString * const NOTIF_downloadComplete; |
4677 | +@end |
4678 | |
4679 | === added file 'musicstreaming/utilities/operations/Downloader.m' |
4680 | --- musicstreaming/utilities/operations/Downloader.m 1970-01-01 00:00:00 +0000 |
4681 | +++ musicstreaming/utilities/operations/Downloader.m 2011-06-13 16:58:33 +0000 |
4682 | @@ -0,0 +1,188 @@ |
4683 | +// |
4684 | +// Downloader.m |
4685 | +// iSub |
4686 | +// |
4687 | +// Created by Aaron Brethorst on 5/12/11. |
4688 | +// Copyright 2011 Canonical. All rights reserved. |
4689 | +// |
4690 | + |
4691 | +#import "Downloader.h" |
4692 | +#import "DownloadOperation.h" |
4693 | +#import "SynthesizeSingleton.h" |
4694 | +#import "Artist.h" |
4695 | +#import "Album.h" |
4696 | +#import "Song.h" |
4697 | +#import "Subsonic.h" |
4698 | + |
4699 | +@interface Downloader () |
4700 | +- (void)createMusicDirectory; |
4701 | + |
4702 | +- (void)startArtistEnqueueing:(Artist*)anArtist; |
4703 | +- (void)completeArtistEnqueueing:(Artist*)anArtist; |
4704 | + |
4705 | +- (void)startAlbumEnqueueing:(Album*)anAlbum; |
4706 | +- (void)completeAlbumEnqueueing:(Album*)anAlbum; |
4707 | +@end |
4708 | + |
4709 | +@implementation Downloader |
4710 | + |
4711 | +SYNTHESIZE_SINGLETON_FOR_CLASS(Downloader); |
4712 | + |
4713 | +- (id)init |
4714 | +{ |
4715 | + if ((self = [super init])) |
4716 | + { |
4717 | + [self createMusicDirectory]; |
4718 | + |
4719 | + downloads = [[NSMutableSet alloc] init]; |
4720 | + |
4721 | + queue = [[NSOperationQueue alloc] init]; |
4722 | + [queue setSuspended:NO]; |
4723 | + |
4724 | + contentEnumerationQueue = [[NSOperationQueue alloc] init]; |
4725 | + [contentEnumerationQueue setSuspended:NO]; |
4726 | + } |
4727 | + return self; |
4728 | +} |
4729 | + |
4730 | +- (void)dealloc |
4731 | +{ |
4732 | + [contentEnumerationQueue release]; |
4733 | + [downloads release]; |
4734 | + [queue release]; |
4735 | + |
4736 | + [super dealloc]; |
4737 | +} |
4738 | + |
4739 | +#pragma mark - |
4740 | +#pragma mark Public Methods |
4741 | + |
4742 | +- (void)enqueueArtist:(Artist*)anArtist |
4743 | +{ |
4744 | + NSInvocationOperation *invOp = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(startArtistEnqueueing:) object:anArtist] autorelease]; |
4745 | + [contentEnumerationQueue addOperation:invOp]; |
4746 | +} |
4747 | + |
4748 | +- (void)enqueueAlbum:(Album*)anAlbum |
4749 | +{ |
4750 | + NSInvocationOperation *invOp = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(startAlbumEnqueueing:) object:anAlbum] autorelease]; |
4751 | + [contentEnumerationQueue addOperation:invOp]; |
4752 | +} |
4753 | + |
4754 | +- (void)downloadFile:(NSURL*)url withName:(NSString*)fileName |
4755 | +{ |
4756 | + @synchronized(self) |
4757 | + { |
4758 | + if ([downloads containsObject:fileName]) |
4759 | + { |
4760 | + return; |
4761 | + } |
4762 | + else if (CacheContainsFile(CachedMusicPathForFilename(fileName))) |
4763 | + { |
4764 | + return; |
4765 | + } |
4766 | + else |
4767 | + { |
4768 | + [downloads addObject:fileName]; |
4769 | + // Disable idle timer sleep while downloading |
4770 | + [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; |
4771 | + |
4772 | + DownloadOperation *download = [DownloadOperation downloadOperationWithURL:url |
4773 | + filePath:CachedMusicPathForFilename(fileName)]; |
4774 | + download.delegate = self; |
4775 | + [queue addOperation:download]; |
4776 | + } |
4777 | + } |
4778 | +} |
4779 | + |
4780 | +- (BOOL)isDownloading:(NSString *)fileName |
4781 | +{ |
4782 | + return [downloads containsObject:fileName]; |
4783 | +} |
4784 | + |
4785 | ++ (NSString*)cacheSize |
4786 | +{ |
4787 | + static int minBlock = 4096; |
4788 | + |
4789 | + NSString *file = nil; |
4790 | + NSDictionary *fileAttrs = nil; |
4791 | + |
4792 | + double totalSize = 0; |
4793 | + |
4794 | + NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtPath:[CachedMusicDirectory() path]]; |
4795 | + |
4796 | + while (file = [enumerator nextObject]) |
4797 | + { |
4798 | + fileAttrs = [enumerator fileAttributes]; |
4799 | + |
4800 | + if (![[fileAttrs valueForKey:NSFileType] isEqual:NSFileTypeDirectory]) |
4801 | + { |
4802 | + totalSize += ((([[fileAttrs valueForKey:NSFileSize] unsignedIntValue] + minBlock - 1) / minBlock) * minBlock); |
4803 | + } |
4804 | + } |
4805 | + |
4806 | + return [NSString stringWithFormat:@"%.2f MB",((totalSize / 1024.0f) / 1024.0f)]; |
4807 | +} |
4808 | + |
4809 | +#pragma mark - |
4810 | +#pragma mark DownloadOperationDelegate |
4811 | + |
4812 | +- (void)songDownloadedToPath:(NSString*)path |
4813 | +{ |
4814 | + [downloads removeObject:[path lastPathComponent]]; |
4815 | + if ([downloads count] == 0) |
4816 | + { |
4817 | + // If downloads is empty, go back to idle timing for sleep |
4818 | + [[UIApplication sharedApplication] setIdleTimerDisabled:NO]; |
4819 | + } |
4820 | + // Coarse-grained, blanket notification that any download has completed. |
4821 | + [[NSNotificationCenter defaultCenter] postNotificationName:NOTIF_downloadComplete object:nil]; |
4822 | +} |
4823 | + |
4824 | +#pragma mark - |
4825 | +#pragma mark Private Methods |
4826 | + |
4827 | +- (void)startArtistEnqueueing:(Artist*)anArtist |
4828 | +{ |
4829 | + [anArtist loadAlbums]; |
4830 | + [self performSelectorOnMainThread:@selector(completeArtistEnqueueing:) withObject:anArtist waitUntilDone:NO]; |
4831 | +} |
4832 | + |
4833 | +- (void)completeArtistEnqueueing:(Artist*)anArtist |
4834 | +{ |
4835 | + [PerThreadManagedObjectContext() refreshObject:anArtist mergeChanges:YES]; //force the artist to reload its set of albums from the persistent store. |
4836 | + |
4837 | + for (Album *a in anArtist.albums) |
4838 | + { |
4839 | + [self enqueueAlbum:a]; |
4840 | + } |
4841 | +} |
4842 | + |
4843 | +- (void)startAlbumEnqueueing:(Album*)anAlbum |
4844 | +{ |
4845 | + [anAlbum loadSongs]; |
4846 | + [self performSelectorOnMainThread:@selector(completeAlbumEnqueueing:) withObject:anAlbum waitUntilDone:NO]; |
4847 | +} |
4848 | + |
4849 | +- (void)completeAlbumEnqueueing:(Album*)anAlbum |
4850 | +{ |
4851 | + [PerThreadManagedObjectContext() refreshObject:anAlbum mergeChanges:YES]; //force the album to reload its set of songs from the persistent store. |
4852 | + |
4853 | + for (Song *s in anAlbum.songs) |
4854 | + { |
4855 | + [self downloadFile:[[Subsonic sharedSubsonic] getStreamingURLForSongId:s.songId] withName:s.songId]; |
4856 | + } |
4857 | +} |
4858 | + |
4859 | +- (void)createMusicDirectory |
4860 | +{ |
4861 | + NSError *error = nil; |
4862 | + BOOL yn = [[NSFileManager defaultManager] createDirectoryAtPath:[CachedMusicDirectory() path] withIntermediateDirectories:YES attributes:nil error:&error]; |
4863 | + |
4864 | + if (!yn || error) |
4865 | + { |
4866 | + NSLog(@"%@", error); |
4867 | + } |
4868 | +} |
4869 | + |
4870 | +@end |
4871 | |
4872 | === modified file 'musicstreaming/view_controllers/AlbumListViewController.h' |
4873 | --- musicstreaming/view_controllers/AlbumListViewController.h 2011-05-05 07:27:41 +0000 |
4874 | +++ musicstreaming/view_controllers/AlbumListViewController.h 2011-06-13 16:58:33 +0000 |
4875 | @@ -18,11 +18,11 @@ |
4876 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
4877 | |
4878 | #import "SubsonicIndexedTableViewController.h" |
4879 | -#import "ImageLoader.h" |
4880 | +#import "AlbumArtLoader.h" |
4881 | |
4882 | -@interface AlbumListViewController : SubsonicIndexedTableViewController <ImageLoaderDelegate> |
4883 | +@interface AlbumListViewController : SubsonicIndexedTableViewController <AlbumArtLoaderDelegate> |
4884 | { |
4885 | - ImageLoader *loader; |
4886 | + AlbumArtLoader *loader; |
4887 | } |
4888 | + (UINavigationController *)navigableViewController; |
4889 | @end |
4890 | |
4891 | === modified file 'musicstreaming/view_controllers/AlbumListViewController.m' |
4892 | --- musicstreaming/view_controllers/AlbumListViewController.m 2011-05-06 00:41:57 +0000 |
4893 | +++ musicstreaming/view_controllers/AlbumListViewController.m 2011-06-13 16:58:33 +0000 |
4894 | @@ -18,12 +18,11 @@ |
4895 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
4896 | |
4897 | #import "AlbumListViewController.h" |
4898 | -#import "DataCache.h" |
4899 | #import "AlbumListParser.h" |
4900 | #import "AlbumArtistUITableViewCell.h" |
4901 | #import "Album.h" |
4902 | #import "AlbumViewController.h" |
4903 | -#import "AsynchronousImageViewCached.h" |
4904 | +#import "NSString+Extras.h" |
4905 | |
4906 | @implementation AlbumListViewController |
4907 | |
4908 | @@ -32,6 +31,7 @@ |
4909 | AlbumListViewController *albumListViewController = [[[AlbumListViewController alloc] initWithTitle:NSLocalizedString(@"Albums", @"")] autorelease]; |
4910 | UINavigationController *nav = [[[UINavigationController alloc] initWithRootViewController:albumListViewController] autorelease]; |
4911 | nav.navigationBar.barStyle = UIBarStyleBlack; |
4912 | + nav.tabBarItem.image = [UIImage imageNamed:@"albums"]; |
4913 | return nav; |
4914 | } |
4915 | |
4916 | @@ -42,7 +42,7 @@ |
4917 | self.tableView.rowHeight = 60.0f; |
4918 | [super viewDidLoad]; |
4919 | |
4920 | - loader = [[ImageLoader alloc] init]; |
4921 | + loader = [[AlbumArtLoader alloc] init]; |
4922 | loader.delegate = self; |
4923 | loader.imageSize = 120; |
4924 | } |
4925 | @@ -63,7 +63,7 @@ |
4926 | |
4927 | for (Album *a in self.tableData) |
4928 | { |
4929 | - NSString *index = [[a.title substringToIndex:1] uppercaseString]; |
4930 | + NSString *index = [[a.title dearticlizedIndex] uppercaseString]; |
4931 | NSMutableArray *group = [self.groupedTableData objectForKey:index]; |
4932 | |
4933 | if (nil == group) |
4934 | @@ -149,29 +149,17 @@ |
4935 | cell.albumNameLabel.text = a.title; |
4936 | cell.artistNameLabel.text = a.artist; |
4937 | |
4938 | - if (a.coverArtId) |
4939 | - { |
4940 | - UIImage *img = [loader imageForArtID:a.coverArtId]; |
4941 | - |
4942 | - if (img) |
4943 | - { |
4944 | - cell.coverArtView.image = img; |
4945 | - } |
4946 | - else |
4947 | - { |
4948 | - cell.coverArtView.image = [UIImage imageNamed:@"default-album-art.png"]; |
4949 | - |
4950 | - if (self.tableView.dragging == NO && self.tableView.decelerating == NO) |
4951 | - { |
4952 | - [loader download:a.coverArtId]; |
4953 | - } |
4954 | - } |
4955 | - } |
4956 | - else |
4957 | - { |
4958 | - cell.coverArtView.image = [UIImage imageNamed:@"default-album-art.png"]; |
4959 | - } |
4960 | - |
4961 | + NSError *error = nil; |
4962 | + cell.coverArtView.image = [loader imageForArtID:a.coverArtId error:&error]; |
4963 | + |
4964 | + if ([error code]) { |
4965 | + // Let's see if we need to wait for non-dragging/decelerating |
4966 | +// if (self.tableView.dragging == NO && self.tableView.decelerating == NO) |
4967 | +// { |
4968 | + [loader download:a.coverArtId]; |
4969 | +// } |
4970 | + } |
4971 | + |
4972 | return cell; |
4973 | } |
4974 | |
4975 | @@ -214,11 +202,11 @@ |
4976 | for (NSIndexPath *indexPath in [self.tableView indexPathsForVisibleRows]) |
4977 | { |
4978 | Album *album = [self.tableData objectAtIndex:indexPath.row]; |
4979 | + // This will prompt the album art to download, but doesn't try to load the image when it's done? |
4980 | [loader download:album.coverArtId]; |
4981 | } |
4982 | } |
4983 | |
4984 | - |
4985 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate |
4986 | { |
4987 | [super scrollViewDidEndDragging:scrollView willDecelerate:decelerate]; |
4988 | |
4989 | === modified file 'musicstreaming/view_controllers/AlbumViewController.h' |
4990 | --- musicstreaming/view_controllers/AlbumViewController.h 2011-05-02 04:54:02 +0000 |
4991 | +++ musicstreaming/view_controllers/AlbumViewController.h 2011-06-13 16:58:33 +0000 |
4992 | @@ -19,15 +19,18 @@ |
4993 | |
4994 | #import <UIKit/UIKit.h> |
4995 | #import "SubsonicTableViewController.h" |
4996 | - |
4997 | -@class Artist, Album, AsynchronousImageViewCached; |
4998 | - |
4999 | -@interface AlbumViewController : SubsonicTableViewController |
5000 | +#import "AlbumArtLoader.h" |