Ben Dodson

Freelance iOS, macOS, Apple Watch, and Apple TV Developer

Music Tracker v1.1 and Pocket Rocket v1.1 Released

Last week, version 1.1 of both Music Tracker and Pocket Rocket were released in the App Store.

The main new feature for Music Tracker v1.1 is native support for iPad. This includes not only the iPad Air and iPad Pro, but also all of the various split-screen modes that can be applied in both portrait and landscape. This release also includes landscape support for the iPhone. There were also a few minor bug fixes.

I’m aware that a few people with large libraries (anything over ~25000 tracks) are experiencing some performance issues which can cause the automatic tracking to fail; a new update is under development to fix that. If you have a large library and would like to test that release, please let me know.

Pocket Rocket v1.1 adds a few features that were requested from existing customers. These include the ability to see the total number of unread articles on the app icon and using Background App Refresh to keep that count up-to-date. There are also a few bug fixes (including a big one that crashed the app with certain query strings in URLs) and a 3D Touch Quick Action (for iPhone 6s) so you can see when the articles were last updated.

If there are any features you’d like to see added to either Pocket Rocket or Music Tracker, please get in touch.

Deleting all NSUserDefaults with Swift

NSUserDefaults is likely one of the most used APIs on iOS providing a quick and easy way to store basic configuration and settings. However, these can quickly mount up and you’ll typically end up with something like this in your project within a logout method:

let defaults = NSUserDefaults.standardUserDefaults()
defaults.removeObjectForKey("Username")
defaults.removeObjectForKey("Token")
defaults.removeObjectForKey("SomeSetting")
defaults.removeObjectForKey("FavouriteArtist")
defaults.synchronize()

(Note: you should never store secure information like a password or API token in NSUserDefaults; that’s what the Keychain is for. You should probably also use static constants in a config file for your keys but this will do for a demonstration)

The problem with something like this is that you have to remember to go and add an extra removeObjectForKey whenever you add a new setting and this can be easily forgotten and lead to settings being shared between different user accounts. I’ve definitely been guilty of doing this in the past and, whilst working on an update to Pocket Rocket, I found that this can be much simpler:

NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)
NSUserDefaults.standardUserDefaults().synchronize()

This will clear all of the NSUserDefaults that have been set by your code leaving you with a fresh slate just as if the app had been deleted and reinstalled. You don’t need to update your logout method whenever a new setting gets added and you can be sure that everything is being reset in full.

Update: a few people have asked why I perform NSUserDefaults.standardUserDefaults().synchronize() as this should happen automatically. The key word here is should; since iOS 7, NSUserDefaults do not get written to disk as frequently as previously (i.e. when going into the background). With the addition of things like watch extensions, widgets, and keyboards that can all access a shared NSUserDefaults, I find it is always best to perform a sync (which ensures the data is written to disk immediately) as then none of the other aspects of your app or extensions will access invalid data. It doesn’t add any significant performance overhead in my experience but can save you from embarrassing bugs.

Calm Radio for iOS

I’m happy to announce that the new iOS app I built for Calm Radio is now live in the App Store.

Last month, I announced the launch of the Apple TV app for Calm Radio; the client was so pleased with the end result that they commissioned me to also rebuild their existing universal iOS app. This is a special project for me as I didn’t only build the app from scratch, but I also designed it fully. With the Apple TV app, I took design cues from the stock apps provided by Apple such as Movies and TV Shows; with the iOS app, I’ve taken inspiration from that design and kept the vibrant backgrounds created by blurrding the rich artwork that was available for each channel.

As well as the standard playback and support for up to 3 ambient channels, the iOS app adds many features not found in the Apple TV app; an alarm clock, sleep timer, ability to skip track, favouriting channels, and full support for streaming to AirPlay and Chromecast devices. I also included support for 3D Touch by making use of Quick Actions to show your most recently listened to stations directly on the app icon. In addition, the app inherits many new features that were first designed for the Apple TV app such as video backgrounds.

One of the things I’m most proud of is the adaptability of the UI. The app can run in an incredible 20 different sizes and orientations1 based on the various iPhone and iPad sizes, portrait and landscape support, and the new split-screen modes available to more recent iPads.

I’m honoured that my work on the Apple TV app was so well received that I was able to bring the same design and functionality to the Calm Radio iOS app. You can download Calm Radio from the App Store or learn more on their website. The app is free although certain features are limited to paid subscriptions.

  1. The full list is iPhone 4s (portrait), iPhone 5 (portrait), iPhone 6 (portrait), iPhone 6 Plus (portrait), iPhone 4s (landscape), iPhone 5 (landscape), iPhone 6 (landscape), iPhone 6 Plus (landscape), iPad Mini (portrait), iPad Mini (landscape), iPad Air (portrait), iPad Air (landscape), iPad Air (30% width split-screen portrait), iPad Air (25% width split-screen landscape), iPad Air (50% width split-screen landscape), iPad Pro (portrait), iPad Pro (landscape), iPad Pro (30% width split-screen portrait), iPad Pro (25% width split-screen landscape), and iPad Pro (50% width split-screen landscape). ↩︎

The Divide #7 - Mind Missiles and The Internet of Stuff

The 7th episode of The Divide podcast is now available. Chris, John, and myself discuss a number of cool pieces of internet enabled hardware you can go and buy today. We’ll give examples of how to connect your home together with IFTTT, HomeKit, and devices like the Arduino and I spend a lot of time discussing my beloved Hue light bulbs. It turns out that John wants more Raspberry Pi’s in his life, I want the new Tesla update, and Chris has an interesting idea for a TV show…

You can get The Divide from these fine outlets:

Don’t forget to leave a review on iTunes and follow us on Twitter via @PodcastDivide.

Music Tracker

I’m very happy to announce that my latest self-published app, Music Tracker, is now available on the App Store.

Music Tracker is an iPhone app that keeps an eye on your music library and monitors additions, deletions, and any changes to your songs. With streaming becoming more popular, it is very easy for song metadata to change or for songs to disappear as licensing deals expire; with Music Tracker, you will always know when something in your library changes whether it was by you, a family member, or your streaming service.

I came up with the idea for Music Tracker after noticing that the amount of songs returned by iTunes was different to that in my Music app on my iPhone. This was due to a song I had in Apple Music that was no longer available in the UK and so had been automatically deleted from my iPhone and greyed out in my iTunes library on my mac. After a quick prototype, I had an app that would run on my phone and keep track of any deletions and additions so I’d be alerted if Apple altered my music. After a few weeks, there were several changes picked up by my app including a few songs that were just plain deleted and some that were completely altered (i.e. I had a studio recording of Uptown Girl by Billy Joel that was switched for a live recording - with Music Tracker, I could see this change and switch it out for a studio recording from a different album).

In my original prototype version, I actually exported the entire music library as a JSON file and uploaded it to GitHub1. However, to make it work natively on the device without an internet connection I made use of the Realm mobile database which is fantastic and insanely fast. The entire process of extracting the metadata from your library, comparing it against the existing dataset saved in Realm, and then creating a log of changes, additions, and deletions takes around 2.2 seconds on a library of 10000 songs2 and allows a full activity feed showing changes on a granular level:

From a technical point of view, there are 3 different ways in which Music Tracker can update depending on the options you choose during setup:

  1. If you enable push notifications, then a silent push notification3 will be sent to your device once an hour that wakes up the app in the background and checks for any changes. This typically lasts around 2 seconds on a standard library of 10000 songs and in my opinion is a pretty clever way of getting around the fact that you can’t schedule background tasks on iOS.

  2. If you don’t enable push notifications, the app will make use of Background App Refresh (limited to once per hour) to do an update in the background in a similar way to the silent push notifications. These typically fire when the phone is connected to WiFi and a power source but mileage will vary depending on what apps you have installed (and for that reason I recommend the silent push option).

  3. If you go into iPhone settings and disable Background App Refresh, then the only way to update the library is to open the app and pull to refresh (or use the 3D Touch Quick Action if you have an iPhone 6s / 6s Plus).

Before finishing the app, I added full 3D touch support (both quick actions and “Peek and Pop”) and a basic Apple Watch app that allows you to see how many songs are in your library, and how many songs have been added, changed, or deleted today (along with name and artist of those tracks). In addition, there is a glance providing this information in a single screen and text-based complications for the Utility, Modular, and Mickey Mouse faces with a quick summary of your library today.

This was the first project in which I used Fastlane for the provisioning profile, certificate generation, push notification setup, TestFlight, and iTunes Connect submission and I’d highly recommend it; so much simpler than doing those things manually! The TestFlight beta test was also well worth doing as with something like this I could only really test on a handful of devices but I needed to see load times on other devices and larger libraries - a big thank you to all of my beta testers. Once the app was submitted, I was honestly expecting the app to be rejected but it went straight through review without a problem4.

The final thing to mention is an issue of privacy. I’m very proud of the fact that no data leaves your device from this app5 and I have a simple and transparent Privacy Policy6. However, I do think it is bizarre that iOS does not require any permissions dialogue when accessing the music library. I wrote a post about this last week detailing this big privacy flaw and I’ve submitted a bug report to Apple (rdar://24168798) in the hope that a standard privacy alert will be added in iOS 10.

You can download Music Tracker on the App Store (priced at $0.99 / £0.79) and learn more about it on my Dodo Apps website. If you are interested in reviewing Music Tracker or writing an article surrounding the privacy issue, you may can download the media kit which contains more information along with screenshots, mockups, and app icons.

If you find Music Tracker useful, I’m always grateful for a review on the App Store. If you run into any issues or have feature requests, you can contact me directly.

  1. You can see how this looked by seeing the commit log at https://github.com/bendodson/music-library ↩︎

  2. Your mileage may vary depending on how many songs you have in your library and what device you are using; it’s obviously faster on an iPhone 6s than a 5s. The app requires a 64-bit processor due to this and so will not run on the iPhone 4s, 5, or 5c. ↩︎

  3. The key part here is “silent”. These notifications wake up your phone and do some processing but you don’t receive any alerts, sounds, or badge icon updates unless you specifically opt-in to the “Summary Notification” within the settings panel (and that sends a simple text alert once per day if your library changed on the previous day). ↩︎

  4. Although v1.0.1 was “In Review” for 3 days before approval. ↩︎

  5. There are no analytics or tracking of any kind. I did use Parse during the beta test in order to save a basic log of library sizes and processing times but that has all been removed for the App Store version and can be checked with a network debugger like Charles Proxy↩︎

  6. Summary: I really don’t want your data. ↩︎

Your music library is a security and privacy risk on iOS

UPDATE: Thanks to my raising this privacy concern, Apple have resolved this issue as of iOS 10. I’ve left the old post below for posterity.

Over the years Apple has put a lot of effort into making iOS secure and privacy focussed. You are prompted with dialogue boxes whenever an app tries to access your contacts, calendars, photos, or location and you need to confirm that you want to receive notifications. However, whilst developing Music Tracker1 I discovered that there is no privacy prompt when a developer tries to access your library. In fact, they can access all of your music data as simply as this:

let query = MPMediaQuery.songsQuery()
if let items = query.items {
    for item in items {
    	NSLog("Title: \(item.title)")
    }
}

That’s just a basic example that’ll output the title of every song in your library but there is a lot of danger in that. This process happens completely silently and in my tests I was able to loop through a library of 10000 songs, put all the metadata in a JSON file2, and upload it to a server in under 2 seconds!

But why is this a security or privacy risk? Off the top of my head, I can think of two massive risks:

  1. Your library says a lot about you3. If an advertising company was able to get a complete list of your music library (along with changes to it over time) then they could very easily target you with specific ads. Added a lot of Taylor Swift recently? Here are some ads relevant to that.

  2. When iOS first came out there was something called a UDID which basically identified your device uniquely. This was used by marketers to track you across multiple apps and build up a profile. This was stopped by Apple a few years back and replaced with an advertising identifier which you can turn off and which can only be used between apps from the same company (where they are probably already tracking you). However, with a full music library, it would be fairly easy to track someone across multiple apps as periodic snapshots could be compared on a server.

I’ve no idea if apps are already doing this in the background silently but it is something that shouldn’t be able to happen. To that end, I’ve filed a bug report with Apple (rdar://24168798) to ask that they implement the same privacy controls that they do for contacts, calendars, photos, and location; a prompt when an app tries to access this data and the ability to grant or reject that permission through the system wide settings. Hopefully this is something Apple will implement in iOS 10 – if you’d like to see this happen, please duplicate bug 24168798 in the Apple Bug Reporter as that is the best way to bring it to their attention.

Update, 20th Jan 2016: A few people have pointed out that the first beta of iOS 9.3 does have a new privacy setting for “Media Library”. However, this does not stop the above line of code and read-only access to your library; instead, it is part of a new feature that allows for apps to add songs to your iCloud Music Library but requires your permission to do so. Apps that use the MPMediaQuery above won’t even appear in the Media Library permissions page to disable so this is not the solution some think it is.

Update, 23rd Feb 2016: Several articles are now linking to this and picking up on my comments about iOS 9.3 above and horribly misunderstanding what those new APIs do. I’ve published a new article detailing exactly what the new APIs in iOS 9.3 add to the music library (and what they don’t add). As of iOS 9.3 beta 4, there are no privacy controls on scanning your music library and it still works exactly as I’ve described above.

Update, 25th March 2016: With the public release of iOS 9.3, this issue is not resolved as per my post last month.

Update, 13th June 2016: Thanks to my raising awareness of this issue, iOS 10 (released in beta for developers today) has added full privacy controls for read access to the local media library. I’ll write up a post in the future about how the new APIs work (done).

  1. Available on the App Store. Find out more at Dodo Apps↩︎

  2. I uploaded it to GitHub so you can get a feel for how big a file it generates in that small amount of time. ↩︎

  3. Let’s not read into what C’est La Vie by B*Witched means about me… ↩︎

Munchkin Report

I’m very pleased to announce that another client app I developed recently has gone live in the App Store; Munchkin Report for iPhone.

Munchkin Report is an online service that helps you track your child’s moments, big and small. From her first steps to yesterday’s nap schedule, Munchkin Report captures memories, keeps parents and caregivers in-sync, and helps you make informed decisions.

It was a real pleasure to work on this app as I was able to work in an incredibly efficient way. The client provided me with a complete API (including full documentation1) and some static wireframes; I was then left to my own devices for a couple of weeks and given creative freedom to build my own design and tweak the UX as I saw fit. In the end I settled on an iOS 7 style minimal design which puts the important information up front and uses bold colours for UI controls.

The design is optimised for all four sizes of iPhone from the tiny iPhone 4s to the massive iPhone 6s Plus. It was written in Swift 2.1 and runs on iOS 9.0 and greater.

I had just received my iPhone 6s when I started the project so as a little extra2 I added 3D touch quick actions so you can quickly get to the log actions from the home screen. There is also “Peek and Pop” integration throughout.

I’m really pleased with the way this app turned out and I think it’ll be a great resource for childcarers and parents. Munchkin Report is free but does require an account from munchkinreport.com (free trials are available). You can download Munchkin Report from the App Store or learn more on their website.

  1. You’d be surprised how rare that is! ↩︎

  2. One of the main reasons I do client work is so I can experiment with new APIs I wouldn’t necessarily use if I was just doing my own apps. I often add features for free to client apps to give me a bit more experience using a certain framework. ↩︎

Calm Radio for Apple TV

I’m very pleased to announce that my first tvOS app for a client has gone live in the Apple TV App Store; Calm Radio.

Calm Radio is an ubiquitous online radio service with over 150 channels dedicated to specific genres of music and relaxation such as meditation, piano, jazz, latin, and so on. It is free to listen to (with no account) but you can remove ads from the stream and get access to special features with a paid account.

With the Apple TV, I wanted to make the app fit in like a first class citizen of the platform and so I did all of the design and UX work myself with a focus on real time blurs and gradients. As you navigate around the huge array of channels, the background will subtley shift to softer versions of the key colours used in the artwork.

When you select a channel, you are shown a now playing page that has the title, artist, album, and artwork of the currently playing music. The background is a soft version of the channel artwork but you can choose one of 12 high definition videos to play in the background instead. These videos are looped and blended with the background gradient in order to keep the experience consistent and relaxing.

You can choose up to 3 atmospheres (such as wind, rain, waterfalls, crickets, etc) to mix with the currently playing channel and they appear underneath the artwork of the currently playing track. I designed an intuitive and simple UI for this so that listeners could change the volume of each individual atmosphere relative to the channel without using sliders1 or cluttering the interface.

Finally, I wanted to use as many tvOS features as possible and so I built in support for the “Top Shelf” allowing you to see and play various channels direct from the TV home screen.

This has been a great project to work on and I’ve learned a huge amount about the Apple TV and the ‘Focus Engine’ that powers it2. It’s been a lot of fun to do my own UX and design work and I think it’s turned out really well; the client was so pleased with it that I’ve been hired to rebuild their existing universal iPhone and iPad app to make it match this design!

You can download Calm Radio from the Apple TV App Store3 or learn more on their website.

  1. There is no UISlider in tvOS for the simple reason that a slider would be very difficult to navigate away from with the UIFocusEngine. ↩︎

  2. Along with a handy tip on how to use your Apple TV Siri Remote with the Xcode Simulator ↩︎

  3. That link will take you to the iOS app as there is no way to link to the tvOS App Store as far as I’m aware. You’ll need to search “calm radio” on your Apple TV App Store to download the app. ↩︎

The Divide #6 - The 'JJ Abrams' of game lists

This week we’re back on schedule and episode 6 of The Divide is now available. Chris, John, and myself discuss over 40 games that are being released this year and pick out a few of our favourites including Crackdown 3, Final Fantasy XV, Zelda, Mass Effect, Street Fighter V, and Yooka-Laylee. We also spend some time discussing the Oculus Rift pre-order and I have a bit of a rant about the rumoured removal of the audio headphone jack from the next iPhone1. Finally, Chris is still upset with JJ Abrams…

You can get The Divide from these fine outlets:

Don’t forget to leave a review on iTunes and follow us on Twitter via @PodcastDivide

  1. Short version: I’m cool with it being removed. ↩︎

Fixing emoji footnote arrow bug in Jekyll

I’ve been using Jekyll as my static blog generator for a few years now but noticed a minor annoyance a few days ago; whenever I use footnotes1, the return arrow (↩︎) is converted into an emoji (↩️) on iOS and in some RSS readers. Obviously this isn’t desirable and so after a bit of digging I was able to find a fix.

Firstly, this isn’t an issue with Jekyll but with kramdown which does the Markdown conversion. Thankfully, there is a config option in kramdown 1.8.0 and above2 that lets you specify the text you want to use for the footnote return link and you can set it as unicode to stop it being converted to emoji. Just add the following to your _config.yml file:

kramdown:
  	  footnote_backlink: "↩︎"

Regenerate your site and you should find that the emoji arrow is now back to a ↩︎.

  1. like this one! ↩︎

  2. You may need to run gem update kramdown if you installed Jekyll a while ago. ↩︎

« Older Entries Newer Entries »