I find most of Apple’s SDK’s pretty good – but their limits are starting to show. Just wanted to briefly cover my experiences with a few.
The SDK is not all bad. Cocoa Touch is of course, awesome. It gives you plenty of freedom while constraining you in all the right places so you don’t end up with an unusable app. Most developers can’t do UI (look at some J2ME apps and you’ll know what I mean), but most iPhone apps are quite usable. Love the IB tool once you get your head round what it’s actually doing under the scenes. The widgets are customisable enough and using NSFetchedResultsController with a table is an efficient way to bind data to a table. UITouch events are simple to understand and the way messages cascade through view controllers via their subviews is great to work with.
Music Player Framework:
This is an unacceptable interface to the iPod library simply because it’s so inflexible and querying the library using MPMediaQuery and MPMediaPredicates is so inefficient and slow.
For example when you’re searching tracks by various properties you can only do either “exact match” or “contains”. There is no way of doing a “word begins” search like the iPod does. This would speed up some queries significantly. Furthermore, there is no efficient way to get a list of Artists, Albums, Playlists etc. You’d imagine you could just do something like NSArray *artists = [[MPMusicPlayerController iPodMusicPlayer] artists] that returns a list of artist strings but actually you have to do something really silly. You have to do a query on the whole media library and tell the Music Player Framework to group tracks into collections. These collections can be representative of your grouping criteria – which in this case would be artist. There’s lots of heavy lifting going on here as we have to retrieve all the tracks on the collection – and on my iPhone 3G with around 2GB of songs this takes more than a few seconds.
To get around this problem you can cache the music library, but although there is a mechanism for detecting an iTunes sync while your app is running, there is no way to find out exactly what has changed. There is an API call to get the last modified date of the library, but this time also includes any updates to the library metadata – e.g. track play count, which makes this useless for detecting collection changes. Apple, please do something about this!
I started using this because I thought it would be an easy and efficient way to query a large data set with basic math in the predicates (e.g. abs(r-%f) < .28 AND abs(g-%f) < .28 AND abs(b-%f) < .28) but even though the underlying store is SQLite I realise there are so many limitations. If I wanted to fetch 50 random items, I can’t do that. I can only sort by attribute name (e.g. title descending). That’s not very helpful… I might have to go back to the drawing board and use NSMutableDictionaries instead.
Maybe its time to wipe all preconceptions of programming that I’ve learnt from web development and start getting used to the Client API way of doing things. Lots of ups and downs but we’ll get there.
Thanks for reading