Ben Dodson

Freelance iPhone & iPad Developer

Dropping non-retina support in iOS 7

Wednesday, 16 October 2013

Back in June 2011, I posited that Apple should remove the 1x/2x toggle on iPhone apps running on the iPad and instead just use the retina versions at fullscreen. I’ve mainly been working on updating apps to be compatible with iOS 7 over the past month and I noticed that this change had been made and non-retina iPads (namely the iPad 2 and iPad Mini) now just use retina assets. The 1x/2x toggle is dead!

The previous behaviour for iPads was that they would run a 320x480px boxed version of your app in the center of the display. If you pressed the 2x button, the app would be enlarged to 640x960px but would still use the same assets leading to a fuzzy mess. The retina iPads had it slightly better as they would use the larger assets and retina font smoothing leading to a better experience. In iOS 7, retina iPads (currently the 3rd and 4th generation) still allow this same toggle but the non-retina iPads (only the iPad 2 and iPad Mini on iOS 7) are now locked at 2x using your retina assets and font smoothing.

This is fantastic news as it signals the end of non-retina device support. If you are making an iPhone app that is iOS 7 only (sensible if it’s a new app), you no longer have to worry about supporting non-retina devices as the iPads will use your retina assets. For developers, this has 3 key benefits:

  • You only need @2x files in your app bundle: This leads to smaller sizes for your app bundle and less hassle in creating all of your 1x assets in the first place.

  • Less complex code for images fetched over network as you only need one size: For example, in WallaBee I have a UIImageView subclass that fetches images for me based on the scale of the UIScreen. If the UIImageView is 100 points square, it would download a 200x200px image on retina devices and 100x100px image on non-retina devices. This is no longer necessary saving some complexity.

  • You can use finer design elements: for example, using 1px (rather than 1pt) dividing lines. You can also use images that have an odd number of pixels (previously a 99px image was generally forbidden as you’d need a 49.5px image for non-retina displays which wouldn’t work). Nearly every designer I’ve worked with has designed at retina resolution with odd numbered sizes for key elements so this is very welcome!

I’m really excited that we can now drop support for non-retina displays; it’ll definitely speed up some of my workflows. You will obviously still need to support non-retina devices if you are building a Universal or iPad only app though.

iTunes Artwork Finder

Tuesday, 19 February 2013

When I first got my Apple TV, the main issue I had was that my artwork looked crappy for some of the TV shows I’d downloaded from places other than iTunes. I’d been using a combination of Google Image Search and screenshotting and cropping the iTunes Store to get artwork and it looked awful on a big TV. To solve that, I wrote a small script to fetch TV Show artwork from the iTunes Search API. They only display 100px artwork but with some URL fudgery I was able to get 600x600px artwork.

The project became a lot more popular than I imagined and I was soon inundated with requests to add new features such as searching across international iTunes stores and adding movie artwork. More recently, I’ve been asked to add iBooks artwork.

I had a bit of spare time this morning so I’ve updated the project page and added a fair few new features.

  • Media Types - I’ve extended the iTunes Artwork Finder to now work with not only TV Shows and Movies, but also iBooks, Apps, and Music Albums.

  • Resolution - I discovered that I was able to get higher than 600x600px artwork in some instances. Movies can be upto 1800x2400px and I’ve seen some TV shows at 2400x2400px. Apps will always be at 512px square or 1024px square depending on when the app was released or last updated. iBooks, Movies, and Music Albums are a bit problematic as licensing issues often prevent the high resolution artwork being made visible. I’ve left the link there as it does work with some (seems to depend on the studio) but there is a caveat listeed as I don’t expect you’ll get good results.

  • Countries - There are now 5 iTunes Stores that can be searched across; UK, US, Germany, Sweden, and the Netherlands. If you want your country added, just get in touch.

I’m pretty pleased with the update, particularly now that I’ve managed to get album covers and iBooks worked out (and I think the app icon search could be useful). Give it a try and let me know how you get on!

Try out the iTunes Artwork Finder

‘CACurrentMediaTime()’

Tuesday, 29 January 2013

You may remember me extolling the virtues of CACurrentMediaTime() a few days ago in relation to keeping track of time on iOS (specifically in allowing me to sync up the WallaBee Store to the nearest second around the world).

This is a retraction of that.

The problem is that CACurrentMediaTime() has a fatal flaw. Whilst it’s designed to be a counter, it only actually works whilst the iPhone (or iPad) is active. Here is how it’s described by Apple in their documentation:

Returns the current absolute time, in seconds. A CFTimeInterval derived by calling mach_absolute_time() and converting the result to seconds.

Further inspection of mach_absolute_time() gives us very little (documentation is very sparse). On Mac OS X, mach_absolute_time() is based on the last time the device booted (it gives you the number of seconds since you turned your computer on) so it seems prudent that this would be similar on iOS. Apple give some cursory examples of how to convert mach_absolute_time() from nanoseconds into seconds and in doing so point out that “the function is CPU dependent” and needs to be converted by the system rather than by constants. There is no mention of how it all works but the general consensus seems to be that it’s uptime.

Apart from it’s not. Unfortunately for me, it took an App Store release for this bug to be noticed.

See, the interesting thing about mach_absolute_time() is that it appears to be the ‘active’ time of the device, that is to say it’s the number of seconds that you iPhone has been active. However, it’s more sneaky than that as putting your device in standby mode will actually leave the device ‘active’ for a few minutes whilst core components are turned off. In effect, if you are relying on mach_absolute_time() and, by extension, CACurrentMediaTime(), you’ll find that the ticks suddenly pause when your iDevice has been in standby for a few minutes.

So how did this come to light? My game, WallaBee, required a way to count time accurately independent of the system clock (which can be changed by the user). I built a system which allowed me to get the time from my server, account for some lag, and then render elements from CoreData at specific times based on what I believed was a steady ticking in seconds. When the app was sent out to my testers, it seemed to work but occassionally putting the device to sleep and then resuming would lead to some odd behaviour; the clock was running slightly behind. I tried replicating this several times to no avail and eventually left it ‘as is’ since it seemed to be occurring very infrequently and there was no way to work out exactly was happening.

After the code made it into the App Store, there were a few more people commenting that the Store seemed to be running a few seconds behind (or in some cases, minutes behind). I again ran some builds and couldn’t find any errors and it was only after considering that my Xcode build and Testflight build (read “Ad Hoc”) could be different that I discovered the error; any build that wasn’t tethered to my laptop suffered from a slowing down of time. As the Store automatically corrects itself at ~8 minute intervals, and the bug only presented itself after a few minutes of standby, it was quite tricky to replicate exactly.

To test it, I built a very crude mockup app that would present a UIAlertView when you came back from standby mode with the number of seconds perceived by CACurrentMediaTime() and the number of seconds derived from deducting two NSDates (which we couldn’t do in the production app as changing the system clock alters that - it’s good for testing though). Sure enough, after leaving the app in the background whilst the device was on standby for a few minutes, it was apparent that CACurrentMediaTime() was pausing. I did another mockup including mach_absolute_time() and that returned the same result; a pausing of the clock when the device was in standby for a while.

After a lot of googling, I found a solution that was based on the device uptime rather than an arbitrary ‘absolute’ time:

- (time_t)uptime
{
    struct timeval boottime;
    int mib[2] = {CTL_KERN, KERN_BOOTTIME};
    size_t size = sizeof(boottime);
    time_t now;
    time_t uptime = -1;
    
    (void)time(&now);
    
    if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0)
    {
        uptime = now - boottime.tv_sec;
    }
    return uptime;
}

This returns a t_time (read int) of the number of seconds since the device was last powered up and so I was able to slot this into my old code in place of CACurrentMediaTime().

The moral of the story? Always test on an Ad Hoc build that isn’t tethered to Xcode. It’s a pain but the crucial thing in this was that the Xcode debugger was keeping the iPhone alive and that meant I was never able to see that CACurrentMediaTime() was pausing itself. The other thing to do is to read Apple documentation carefully. At no point do they specifically say that mach_absolute_time is based on uptime or that it counts up sequentially, but forum posts and other developers blogs had created that perception based on their own findings and those of the method on OS X. It always pays to be careful and understand fully the methods you are calling.

Fortunately (or not), there was a bug with iOS 5 in the version of WallaBee that was submitted to the App Store and so this fix was bundled in with an expedited review. Of course, that update has now been ‘In Review’ for over 24 hours so we’re not out of the woods yet but at least I’m now using a timer that actually counts up…

Syncing the WallaBee Store

Tuesday, 22 January 2013

Update: It turns out CACurrentMediaTime() has a significant bug in that it doesn’t count up when an iPhone is in standby mode. Check this update for a better solution.

If you’ve played WallaBee you’ll know that one of the key areas of the app is the Store, a place where you can buy items with the app currency you collect. The Store has a 3 x 4 grid of items with a timer under each; when the timer runs out, a new item is displayed for purchase. This all sounds straightforward, but when the WallaBee API started getting 3 million hits per day, the Store was one of the first areas to suffer. In this article, I want to run through a few of the problems I experienced when building it the first time, and go into details on the improvements I’ve just added in v1.1.5 of the app which will be available this week.

The WallaBee Store

The Original Plan

In my mind, the Store was going to be fairly simple. It had to be the same for everybody so I’d set up a CRON job that would populate a database table with the upcoming items. Every minute, a check would be performed and items would be added to make sure there was something in every spot until the next time the script ran. Every item had a start and end time that was fixed but had a random amount of seconds (between 10 and 45) so that each item would ‘run out’ at different times. Whenever a player visted the Store, an API call would retrieve the items at each position and do some basic math to work out how long it would be until the position needed to be restocked. Finally, there was an API call to reload just a single position which would be called when an item ran out and a new one was needed. Simple!

The problem with this is that WallaBee became popular and the database bore the brunt when a new item was released and the players descended on the Store. This meant that, when a position needed restocking, there could be thousands of requests in the same second all asking the database to tell them what that item should be. Those kinds of numbers don’t work well (it’s basically a denial of service attack) and so the Store would gradually become emptier and emptier as the network activity indicator struggled and the database slowly spat out what items should be where. Another issue was timing; there was a slight overlap between expiration and start times of items and so clever developers could look and work out when a new item was appearing in the Store upto 15 seconds before the item appeared (leading to an unfair advantage). In addition, if the network connection was slow, some players could be behind the live Store by 10 seconds or so meaning they would be at a disadvantage when something new appeared.

Clearly there was work to be done.

The Problems

I had three key problems to solve.

  1. The Store had to be synced for everybody. I wouldn’t accept more than a 500ms gap between players regardless of their connection speed.
  2. It had to be secure with no chance of seeing what item was coming in advance, even if you sniffed the network traffic with something like Charles.
  3. It needed to be fast. This meant no database calls and as few API calls as possible, especially during peak times.

In addition, the solution needed to be scalable as I would be adding multiple stores in the next major version of the app. The app would have to be able to display around 80 items at a time rather than 12.

The New Plan

My solution was that the server would generate a physical file every minute that showed all of the updates for the next 10 minutes. When a device requested the Store, it would download this file (no database calls) along with a synchronisation timestamp. This file would be unpacked on the device and each item would be stored locally so that the Store could continue on without making any network calls. At some random point before the 10 minutes was up, the device would request the next 10 minutes worth of data and unpack it silently in the background.

Whilst it sounded good on paper, it would require a lot of work to get everything working correctly. Each piece is inter-connected but I’ll try and explain the general timeline of how it works along with a bit of code.

Store Generation

The first thing that needs to happen is that the server has to generate 10 minutes worth of items. I created a new table that would hold the item objects and wrote a basic CRON job that went through each position and randomly chose an item1 along with a random shelf life between 45 seconds and 4 minutes. This runs every minute and ensures that there is always 10 minutes worth of items coming up. A separate CRON job then runs and compiles these items into a single JSON file which is then encrypted with a military grade cipher (more on that shortly). This file is stored locally and updated every minute. The end result is that you can request the file at any time and always be sure that you have the next 10 minutes worth of items.

Encryption

One of the key things I wanted to ensure was that the Store was secure as I wouldn’t want anybody to sniff the network traffic and see that a new item was coming out in 7 minutes time (it should always be a surprise). To that end, the file is encrypted using AES-256 before being encoded in Base64 for easy transporting. To do this in PHP is fairly simple:

$json = json_encode($output);
$offset = 16 - (strlen($json) % 16);
$key = ‘YOURPASSWORDHERE’ . str_repeat(chr(0x00), 16);
$data = $json . str_repeat(chr($offset), $offset);
$encryptedData = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, 'cbc'));

The thing that most people miss off is the padding as the data to encrypt has to be a multiple of 16 characters and the characters you use for the padding follow a specific rule; they use the character code of the number of characters you need to pad (for example, if you have to use 7 characters of padding, you’d do it with 7 x chr(7). Another key thing was to use ‘cbc’ as the mode as the default ‘ecb’ found on many tutorials doesn’t work well on the iPhone.

Speaking of iOS, decrypting this file is fairly simple using the NSData Category from the CommonCrypto section of aqtoolkit; it’ll be decoded into NSData which can then be turned into an NSString before using the native JSON library to convert it into an NSDictionary.

Time Synchronisation

The other key feature that needed to be implemented was that the iOS device should be synced to the server time so that all players would be shown the items at the correct times; we don’t want players to be behind or ahead even though the API would stop anybody from purchasing an item that isn’t released yet.

I looked into a number of options for time syncing but many of them use the built-in clock on the iPhone. This is no good as a player could simply advance their clock manually to see future items. Instead I opted to have the main Store file return a Unix timestamp of the time of the request. This is simple in PHP:

$_SERVER['REQUEST_TIME'];

The issue with this is that the time of the request will vary depending on how slow the uplink connection is on the device, and we need a way of accurately monitoring how long it took to download so we can add an offset.

I’ve been using MKNetworkKit for my iOS networking needs (although I’m planning on switching to AFNetworking in the next release) and it provides a useful block-based method on network operations called onUploadProgressChanged. This provides a double which tells you, as a percentage, how much of your upload is done. When it gets to 1.0, that means you have successfully ‘hit’ the API which should tally up to the $_SERVER‘REQUEST_TIME’ on the server side2.

Now we know exactly what time we hit the server, we need to start some form of timer so we can see how long it takes until the download completes. To do this, we use CACurrentMediaTime()3. This returns a CFTimeInterval which is roughly the amount of time since your device was rebooted; think of it as a UNIX timestamp that resets every time you start up your phone. I get the current media time upon the successful upload completion, and when the download is complete I get it again and subtract the difference (so I can see, for instance, that the download has taken 572.42ms). We then add this to the timestamp retrieved from the server to get the current server time; we’re now in sync!

Rendering the UI

We have the next 10 minutes worth of items stored locally and we know the exact server time, now we just need to render the UI. To do this, we’ll need a timer that runs continuously in the background to tell us what the current time is; we use this to get our items from our local store and render the progress bars underneath each shelf. The obvious choice is NSTimer, but there are a few gotchas. Firstly, if you create an NSTimer which is targetting ‘self’, you’ll create a retain loop; the view controller will never be released until the timer is invalidated4. Secondly, I’m using a UIScrollView with the store and any touches caused the NSTimer to pause (which may account for the time discrepency in older versions). To fix that, you need to add your timer to the main run loop as so:

if (_tickTimer) {
	[_tickTimer invalidate];
}
self.tickTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(tick) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:_tickTimer forMode:NSRunLoopCommonModes];

We now have a timer that ticks every second but I found it important to use our old friend CACurrentMediaTime() again rather than incrementing a timestamp. The reason for this is that the user may switch tabs, receive a phone call, or leave the app. In those situations, you need to be ready to resume when they come back and, presuming that they’re within the window of how much data you have loaded, you can just kick off without reloading everything. The problem is, if you increment the timer every tick, you’ll start deviating from the start time if you jump back and forth between tabs as the timestamp is always rounded. By storing the CACurrentMediaTime() and the original timestamp when you start your first timer, you can be 100% accurate on your times by working out the number of seconds between now and the original CACurrentMediaTime() and adding them to your timestamp.

With every ‘tick’ we need to update the UI. This is fairly straightforward and is a case of looking at each position, working out the percentage remaining, and applying that to the progress bar. When an item is due to run out, simply fade it out a second before it expires and on the next tick fade it back in. This leads to seamless animations where before there was a fade out, network request, then gradual fade in. The results were so stark in comparison that I had to slow down the change animation as, without the network lag, it was too quick!

One final improvement I made was that the ‘ticks’ only happen when you are viewing the Store. Previously, the Store would continuously update in the background (including network requests) leading to a waste of CPU and battery life and making the rest of the app feel sluggish. Now, as soon as you navigate away, the timer is invalidated and nothing is updated. When you come back, the UI is refreshed and the timer is restarted (accurately as mentioned above).

The only thing we need to remember to do periodically is update our local store. When the Store is first loaded, I choose a random time between 6 and 9 minutes to perform an update. This is to try and spread out the number of requests to the Store file as typically we get 50x more users online when a new item comes out. If they all reloaded the Store at the exact same times we’d have hundreds of API requests in the same second still (admittedly it’s less of an issue as they aren’t hitting the database but it pays to spread the load). If the network connection fails or there is a server problem, the Store will try and reload after 5 seconds until such a time that it gets data. Crucially, the Store will keep going until it runs out of items at which point it stays bare until it gets back on track. To account for any deviations, the time sync is also performed on these updates.

Conclusion

The new Store is far superior to the old one in every way. The server is more stable, the data is more secure, and the UI is much snappier. With the changes to the way the Store UI was rendered, the rest of the app feels faster as well and load on the server during peak times should be substantially reduced. Crucially, an issue that has been present for a while with crashes when switching between apps has finally been resolved now that the NSTimer code has been rewritten.

It’s been quite a journey getting to this point but I’ve enjoyed learning about time syncing, encryption, and keeping time on iOS. As with many things, this is a progressive update and is a reminder that there is always more to learn.


  1. Ok, when I say “randomly chose an item” it’s a bit more complex than that. Items are weighted based on release time, set, pricing, and so on and there are a number of custom overrides (i.e. Christmas is weighted down so you hardly see those items whilst the One Set To Rule Them All is weighted up as it is a huge collection and takes people longer to complete). In future versions, there will be multiple stores that each have their own rules (i.e. there might be a Store which only has items that are over 6 months old or only items from a particular series of sets).

  2. It’s not exact but it’s within ~200ms which is accurate enough for this.

  3. CACurrentMediaTime() is specifically designed for gaming where you need to have time independent of the system clock and that doesn’t need to be reconciled with an actual world time. For example, the early versions of Tiny Tower had a bug in which you could move your system clock forward in order to get around things like “wait 3 hours for restocking”. They now start a CACurrentMediaTime() when you open the app and this is used to track time.. every second, it is checked and the overall time spent is worked out so it knows when 3 hours has passed, not when the timezone says 3 hours has passed.

  4. I hadn’t realised this in the previous version and I had an NSTimer for each position of the Store! This lead to a large number of unexplained crashes as memory ran out. Lesson learned.

Freelance availability

Tuesday, 08 January 2013

I’ve been neglecting this website of late as I’ve been working fulltime on WallaBee for the past few months. However, I’m currently available for a short (< 3 month) freelance iOS contract or project ideally on a remote basis although I can obviously travel for key meetings, etc. If you have something you think may be of interest, then please get in touch.

I’ll be getting around to updating this website more fully at some point but you can always follow me on App.net or Twitter or read my personal blog at bendodson.com.

Passwords and Encryption

Sunday, 06 January 2013

I’d been thinking for a while that my password setup wasn’t particularly secure; a fairly basic 10 character password with a mixture of uppercase, lowercase, and some digits that I used on every website and rarely changed (maybe once a year). I’d been reading about 1Password but could never really be bothered to make the switch. I had some spare time over the Christmas holidays so I finally got around to changing over to a much more secure system. This entry is a roundup of the process I went through.

Using a password manager

The first thing to do was switch to a system of having a different password for every website. The reason for this is that a single breach of one account will lead to vulnerabilities in the others (and there are a lot of websites and apps out there that store your password in an unencrypted form). Each password should also be very secure.

To do this, you really need a password manager; an app that will store all of your passwords for you. After a bit of research, I found 1Password to be the most suitable for my needs. As well as storing passwords, it can also generate secure passwords (easily variable by length and number of digits and symbols) and store items such as license keys and credit card numbers. There is also a companion iOS app (very important) with cloud syncing and you can even open the database securely on other machines as the file itself has a web version of the app built in! The main thing though is that it is incredibly secure. I have a lot of trust for a company that is willing to publish exactly how they store passwords and can reliabily demonstrate how difficult it would be to crack (not impossible, but incredibly difficult).

I downloaded the 30 day trial of the Mac app and came across my first decision; what to use for a master password? The core database is secure from automated attacks so the weakest link is going to be the password I choose for it. Obviously I shouldn’t use a basic password as I had before but it needs to be something I can remember (but not be directly related to me - after all, you’re most likely to be hacked by people that know you). Enter an excellent password generation system called Diceware, a completely random way of creating a password. It works by giving you a list of words with a 5-digit code next to each one. You roll 5 six-sided dice and the result is your first word (i.e. if you rolled 1,6,3,2,2 then you’d look up 16322 in the Diceware wordlist and come up with ‘celia’. You repeat this process until you have a string of random words such that you get a password like ‘celia autumn well stern romeo veil’. As they are based on real words, you can remember them quite easily by linking them as a sentence or story. For additional security, you can mix it with your own system of punctuation or spacing so you end up with a possibility such as ‘Celia Autumn. well stern. Romeo:veil’ which would be a difficult password to crack but not too bad to remember. If you don’t like the idea of using a list such as Diceware, you could choose random words from a book with dice to choose the page number, line number, and word. For more ideas and an indepth look at generating a secure master password, read “Toward Better Master Passwords” from the AgileBits blog (I’d also recommend this xkcd comic on password strength).

With a master password chosen, I found it beneficial to type it out 50 times to get my fingers used to it. I had no problem remembering my password after that so I never had to write it down anywhere, something which may be a good idea for helping you to remember for the first few days but just seems a bit lax to me. Next, I went through the websites I used most often and updated their passwords with newly generated ones. I’m still stumbling across websites that I haven’t updated so I just make sure to create a new password for any website when I next use it.

Finally, I purchased the iOS app and set up syncing via Dropbox. This ensures that I can always access the core database i.e. from another machine. The iOS app works very well and whilst it can be a pain to have to type in my mammoth password and then copy / paste whenever I want to do something such as purchasing an app, I deem it a worthwhile inconvenience.

After 2 weeks of using 1Password, I’ve found it to be an incredibly useful solution. I assumed that the hassle of typing in my master password to get to my other passwords would be a hassle but overall I’m actually faster at accessing sites than before. This is mainly because I have different email addresses or usernames for each website or account. That information is now stored along with the password so I never enter the wrong details (or have to go through the time consuming ‘recover password’ options). I tried using the Safari extension for a while (which enables automatic form population) but ultimately found this to be distracting (prompting when I didn’t want it to) so uninstalled it.

Encrypting insecure apps

Whilst I was on a security warpath, I decided to try and do something about securing apps that have very poor or no built-in security. The main two offenders for me are Day One and Money both of which store their (sensitive) data in a completely accessible format. Whilst Day One does provide a password option, that is just for the app; you can read the XML files directly from the hard drive. As I store both of these databases in Dropbox (for easy syncing and backup), I wanted something a bit more secure.

That’s when I found Knox which happens to be made by AgileBits, the same people behind 1Password. Knox is an encryption utility that allows you to create secure ‘vaults’. These vaults are secured by password and when unlocked take the form of a mounted disk image. You can put anything you want in them, and when you eject them they become a single encrypted file.

In my setup, I created a new vault for each app, secured it with a ridiculously secure password (stored in 1Password), and then moved the database for each app into the mounted vault. Whenever I want to use the app, I unlock the appropriate vault and then launch the app from the vault itself. Once I’ve added my diary entry or transactions, I quit the app, and then close down Knox. The advantage to this is that if you open up either app without the vault unlocked, it can’t find the database so it creates a new one (meaning anyone trying to look at my transactions will just get a blank app).

The only issue I had with this set up is that I didn’t want to store the raw database files in iCloud or Dropbox (I do keep the Knox vault files in Dropbox though). This means that I lose the option to sync with a companion device so I can’t update Day One or Money via their companion iOS apps. This is more frustrating for Money (as I’m more likely to want to add a transaction at the point of purchase) but isn’t a dealbreaker for my usage. I’d rather have my transaction history secure and accessible on one machine than insecure and synced on all my devices.

Locking down my laptop

The next thing for me to do was to increase the security on my MacBook which I use as my main machine. OS X has a lot of built-in security options that aren’t enabled by default. The first one I enabled was ‘FileVault’ which automatically encrypts your hard drive. The issue with it is that if you forget your main OS X password then there is no recovery for the files on the machine unless you have a special code that you are given at the time of enabling. I stored this in 1Password for extra security but as everything important in my machine is backed up on Dropbox (and also via Time Machine which you can also encrypt) I don’t feel it’s a big issue for the extra security it affords.

The other setting I enabled was ‘Empty Trash Securely’ which you can enable in ‘Finder Preferences’. This basically performs a government style wipe on files as they are deleted from Trash meaning they are effectively shredded rather than just deleted. Emptying the Trash takes longer as a result but, again, it’s a worthwhile trade off.

Finally, 1Password obviously can’t store my MacBook login (as you can only access it when logged in unless you visually copied it from an iOS device each time) so I needed to choose a new secure password for that. In my opinion, the password should be different to the 1Password master password but just as secure so Diceware combined with personal alterations is a good choice.

Conclusion

This new set up is obviously much more secure than what I was doing previously but I was struck by one fairly big problem; password resets. For instance, my Amazon password is very secure (so secure I don’t even know what it is) but it can be reset by answering security questions which are usually of the order of date of birth and Mother’s maiden name. By their very nature, a security question is a very personal thing (“what was your first pets name?”) so anybody that knows me (or can do a basic Google search) would be able to reset my accounts. That is partly how Mat Honan of Wired was successfully hacked last August.

The best defence (in my opinion) against something like that is to fudge the security questions. If you accept the premise that your 1Password account is secure, then you don’t have need for the security questions (as you’ll never lose the password) so you should just fill them in with rubbish. Alternatively, create lies that you store in your 1Password account. If a website forces you to store something like “first pets name” then choose a random word from the Diceware list (i.e. ‘Celia’) and note that down against the account in 1Password. This is particularly useful for over-the-phone accounts (i.e. trying to reset iCloud) as anybody trying to breach your account will think they know the correct answer (my first pet was called ‘Chip’ to save you searching) but you’ve outsmarted them with a lie. When you need to verify yourself, you can simply look up the ‘correct’ answer from your secure 1Password database. As AgileBits point out ‘there are more ways to lie than to tell the truth’.

Nothing is ever going to be 100% secure, but these new changes should significantly reduce the chances of having my data or identity stolen. Hopefully the steps I’ve outlined above will make you think about how you are securing your information and help make you a bit more secure this year.

iPhone apps on the new iPad

Friday, 16 March 2012

I received a new iPad today (along with a 1080p Apple TV) and whilst I don’t want to review it in detail (there are plenty of other reviews) I will say that the screen is absolutely incredible. Whilst most 3rd party apps are not retina-ready yet, those that are look stunning. I actually used my iPad to answer my emails today as it looked so much crisper than my iMac!

Anyway, one of the things that has interested me is how iPhone apps would look on the new iPad. Bearing in mind that there are 4x as many pixels, I assumed that Apple would use retina versions of iPhone apps scaled up. As you might recall, the original iPad and iPad 2 would use regular iPhone apps and scale them rather than using the retina equivelants (something I’ve written about before). I could understand this for imagery but the keyboard and text looked horrible when scaled making any app that wasn’t a game pretty much unusable at 2x mode on an iPad.

Fortunately this has changed with the new iPad. Apps are stills scaled, but the fonts are much crisper as is the keyboard.

To demonstrate, I’ve tested a couple of apps on iOS 5.1 on both the iPad 2 and new iPad and listed some screenshots below. These have been scaled down to fit the page so you will need to click / tap each one to load up the fullsize versions. You won’t notice the difference (aside from some colour improvements) unless you view at fullsize as they look pretty similar when scaled down.

The new iPad is on the left - iPad 2 is on the right.

WallaBee

Spotify

Foursquare

Path

iOS 5.1 Location Services Bug

Wednesday, 14 March 2012

Whilst using the public version of iOS 5.1 I’ve noticed an interesting bug with one of my apps. WallaBee uses Location Services but as all good apps should it makes a point of stopping location monitoring after a certain amount of inactivity (to save battery) and also when the app goes into the background. Location monitoring starts up again as soon as you go back to the foreground or navigate to a page that will require more precise location monitoring.

On iOS 5.0.*, closing the app would lead to the Location Services indicator disappearing immediately. On iOS 5.1, Location Services stays active for ~10 seconds after it’s been told explicitly to stop monitoring. Initially I thought this might be a problem with the code I’d written but, after some testing on multiple devices and with multiple apps, it turns out this is an issue that affects all location based apps on iOS 5.1.

It isn’t really a big issue but it is fairly annoying, particularly as some apps do keep monitoring your location in the background so you end up trying to work out what is still running only to realise it’s the OS not giving up when it should do. It’s particularly annoying as an app developer - v1.0.3 of WallaBee came out on the day iOS 5.1 was released and I’ve now had 3 enquries as to why Location Services is less efficient in the new version (whereas it’s actually much more efficient in the app).

In terms of why iOS 5.1 is doing this, I can only assume that Location Services is told to turn off after the full amount of background task allowance has been used. If an app doesn’t ask to run in the background, it has around 10 seconds after being closed to do any tidying up (i.e. saving documents, closing network connections) before the OS forcably terminates it. This seems to be the case with Location Services as if you close the app and then force quit, the service is stopped (suggesting ownership is with the app, not the OS).

It’s probably an oversight on Apple’s part (as I can’t think of a good reason why this would be built-in) but I thought I’d put up a post on the issue for any other developers who run into the problem and for anyone using my apps and wondering why Location Services is still active once the app is closed.

The curious case of "the new iPad"

Tuesday, 13 March 2012

The strangest thing that happened at the iPad announcement last week turned out not to be the lack of Siri, presence of a home button, or uninteresting iOS 5.1 update, but instead the name; “the new iPad” rather than the universally predicted “iPad 3” (or late runner “iPad HD”). Based on this news, most people seem to think that there is a convergence with other product names in that everything will end up as just “iPad”, “MacBook Air”, “iPod Nano”, etc. In particular, people are predicting that the iPhone 5 (which would actually be the iPhone 6 - drives me crazy!) will now be launched as “the new iPhone”.

I don’t think this is correct.

I’ve tried explaining it on Twitter but 140 characters ain’t a lot of room to play with so I thought I’d lay some thoughts out on Apple’s naming conventions in this post. I’ll also try and second guess some of Apple’s future product announcements based purely on naming.

iPod

The iPod is the pure example of the new iPad naming philosophy as they have always just been known as individual products. i.e. iPod, iPod Nano, iPod Shuffle, etc. Every year (pretty much) a new device is launched that immediately replaces the old ones. If you look at something like the iPod Nano, there have now been six of them (all in various shapes and sizes) but you can only ever buy the latest version. In support documents, they are simply referred to by generation i.e. this case will work with “iPod Nano (6th generation)”.

Mac

The Mac lineup is slightly different to the iPod lineup in that there are more customisations that can be made. You can change processors, RAM, hard drives, screen sizes, etc but fundamentally there is only one product per line. When a new product is released, the old one is immediately unavailable. The naming is also slightly different - rather than referring to the latest Mac mini as “Mac mini (10th Generation)” it is referred to by date making the latest one “Mac mini (Mid 2011)”. This works because the Mac line can be updated multiple times per year with processor bumps, etc, so it makes sense to refer to its launch date rather than its generation. This is the same naming convention that a lot of Apple’s software uses such as iWork ‘09. Whilst iTunes isn’t named after a year (it’s just a version) you could add “20” in front to make them year based as they have been annual since v8.0 came out in 2008.

As regards the future of the Mac lineup, there are currently 5 products; MacBook Air, MacBook Pro, Mac mini, iMac, and Mac Pro. I believe that convergence is going to happen on the MacBook Air / Pro lineup as it makes sense that Apple will make the Pro thinner, lighter, and will remove the optical drive. This is further evidenced by the fact that the MacBook itself was removed a while ago leaving the name free. In future, if you want an Apple laptop, you’ll just get “MacBook” - it could be any size from 11”-17” with various configurations but it will be one line. It’s also fairly likely that the Mac Pro will be removed for a slightly beefier iMac leading to just 3 lines; MacBook, Mac mini, iMac. That’s just pure speculation but it makes complete sense to me. If you want portable computing, you choose iPad or MacBook but you choose Mac mini or iMac for desktop computing.

iPad

The iPad lineup should have been simple - a single product that gets updated yearly and will always be known as “iPad”. However, Apple threw a spanner in the works by calling the second generation the “iPad 2”. There was no need to do this when the iPad 2 was the same price as the iPad and completely replaced it as per the iPod lineup but now they are stuck with it. By naming the iPad 3 “the new iPad”, it looks like they are trying to go back to that model but there is a big issue with that; the iPad 2 is still available for sale at a $100 discount. In Apple’s defence they’ve done a pretty good job of making this work with the structure of their website showing only “iPad” and then the “iPad 2” is a small button at the bottom. There is also a comparison chart which very quickly shows that “the new iPad” is newer than the “iPad 2”. It’s hardly an ideal situation though.

So why have they done it? Whilst the iPad 2 could have been completely removed and replaced by the new iPad (which would make the naming all work out nicely) they wanted to keep selling the iPad 2 at a discount as it beats the competition quite nicely. The only real competitor to the iPad has been the Kindle Fire so by making the entry-level iPad slightly cheaper they can appeal to some of the people that might have been stuck choosing between the two. They couldn’t retroactively rename the iPad 2 so they were stuck with the name.

My feeling on this is that the iPad 2 is going to be removed from sale before the end of 2012 and replaced by a smaller form factor (say 8”) and given a new line; “iPad Nano” or “iPad Mini”. This will get Apple to a good place where they have a cheaper iPad and the premium iPad and two simple lines that can be updated in the same way as the iPod lineup. I say this as if the iPad 2 was going to stick around for a full year I think the new iPad would have been called “iPad 2 Pro” as that’s essentially what it is - same form factor, better screen.

iPhone

This is the real issue - what will the new iPhone be called. Based on my tweet yesterday, most people think it will be called “the new iPhone” to follow the iPad example. I highly doubt it. The difference with the iPhone to all of Apple’s other products is that they keep selling the old models for up to 2 years. Just look at the lineup now; “iPhone 3GS”, “iPhone 4”, “iPhone 4S”. If the next iPhone is referred to simply as “the new iPhone” then you’ll end up with “iPhone 4”, “iPhone 4S”, “iPhone”. That might work, but in 2013 you’d have “iPhone 4S”, “iPhone”, “iPhone” and that’s where it falls apart.

This is a tricky one for Apple and I don’t really have the answer. Let’s take a look at possible names for the next generation iPhone:

  • iPhone 5 - it’s the 6th generation iPhone so that won’t work.
  • iPhone 6 - Original, 3G, 3GS, 4, 4S, 6. Doesn’t really work as a numbering system but I wouldn’t rule it out.
  • iPhone 4G - yesterday I thought this was a pretty good idea. Then I remembered that iOS 5.1 now refers to HSDPA+ as “4G” so I don’t think this can be used anymore.
  • iPhone LTE - it’ll definitely have LTE integrated and iPhone’s have been named after their wireless tech before. However, LTE isn’t available around the world like 3G was so I don’t think they’ll go for this.
  • iPhone HD - no. Just no.
  • the new iPhone - I don’t think they can pull that trick twice.
  • iPhone 2012 - maybe.

It’s a difficult situation and there is no obvious choice. I can see it going a number of ways though:

  1. The long rumoured “iPhone Nano” makes an appearance leading Apple to create just two lines; iPhone and iPhone Nano. iPhone 4/4S won’t be sold at a discount (they’ll just disappear) meaning that Apple can refer to the iPhone 6 as just “iPhone”. I don’t think they can do this if they continue selling the 4/4S though.
  2. iPhone changes to a year numbering system much like the Mac lineup - whilst you would just have “2012” instead of “mid 2012” it might work and allows you to distinguish between multiple versions easily. Not the tidiest of solutions though - “iPhone ‘12” or “iPhone 2012” doesn’t have the same simplicity as “iPhone 6” or “iPhone”
  3. Apple name it “iPhone LTE” - it might not be available everywhere but at least it distinguishes. Might have an issue in 2013 though - LTES won’t work and there won’t be another wireless technology to use.
  4. Apple choose something that isn’t in that list perhaps naming it after a design element with something like “iPhone Curve” (though obviously not “Curve” - RIM would have a fit if they’re still around)

Summary

Whilst nearly all of the Apple product line has converged to yearly updates that replace the previous model, the iPad 2 has caused a problem in that it’s still hanging around at a discount. I’m fairly sure this is going to be replaced by a mini or a nano at some point in the near future thus ending this particular story.

The iPhone, however, is a completely different story and I’m confident that Apple won’t name the next model “the new iPhone” unless they stop selling 3 versions of iPhone at the same time. That is doable (if a new line appears in the way I expect it to for the iPad) but I think it more likely that they will name the next iPhone after something about the device that we don’t know about yet; design, haptic touch, etc.

As usual, time will tell. Apple have a habit of choosing things that you wouldn’t expect.

Analyzing the iPad 3 invite

Saturday, 03 March 2012

A lot has been made in the Apple press recently about the invite to the Apple Media Event on 7th March which is widely expected to introduce the iPad 3. Specifically, the invite appears to show an iPad with an improved screen and no home button:

iPad 3 Invite

Obviously there will be a “Retina Display” in the iPad 3 (I’ll eat my iPad 2 if there isn’t) but the lack of a home button is something that has floated around before, mainly due to the gestures built into iOS 5 that allow you to close apps with a 4/5 finger grab. I only ever use the gestures to get around on my iPad but I don’t really think the home button would be completely removed. For a start it has too many purposes:

  • Closes apps (can be done with a gesture)
  • Lets you access the multi-tasking tray (can also be done with a gesture)
  • Allows screenshots to be taken (press at the same time as the power button)
  • Access to Siri (on the iPhone 4S at least - one assumes the same will happen in the iPad 3)
  • Accessibility shortcuts (triple tap to invert colours for example)
  • Force restart the device (hold at the same time as the power button for a while)

Whilst some of these things could be done in other ways, I just don’t buy the idea that they would remove it - doing things with gestures is great but they are more like keyboard shortcuts for power users than an intuitive way to navigate.

With the above in mind, it was obvious to me that the invite was showing an iPad 3 in landscape and I set out to prove this with some judicious screenshotting (thanks home button) and photoshopping. However, it didn’t quite work out as I expected…

As Apple have very helpfully used the “bubble” background on the iPad in their invite, it should be quite trivial to work out the placement of the icons by mapping them to the unique bubble clusters in the image. For example. there is a unique cluster next to the calendar icon:

iPad 3 Invite Bubble Cluster

From the invite, we know that there are at least 3 icons showing in the “dock” – Maps, Calendar, and Keynote – and you can only have a maximum of 6 icons. I screenshotted the iPad in both orientations with all the possible combinations of 3, 4, 5, and 6 icons and only one came out close to the bubble layout of the invite:

iPad 3 Invite Mockup - Portrait

Hmm, that scuppered my landscape theory. Let’s take a closer look at the calendar icon when it’s in this formation:

iPad 3 Invite Mockup - Portrait

I’ve also done some basic distortion in photoshop to change the angles so that it matches (roughly) the perspective of the Apple invite:

iPad 3 Invite Mockup - Portrait

I’m pretty confident of the location as it’s one of the only possibilities that causes the page control (the little dots and the search icon) to be cut off when photographed at that angle.

If you look at the two side by side, we can see that the bubble cluster is a pretty good match, but it isn’t exact:

iPad 3 Invite Bubble Cluster iPad 3 Invite Mockup Bubble Cluster

The icons in the invite are actually slightly bigger than those on the iPad 2.

So what does this all mean? I have a number of theories:

  1. The iPad 3 has no home button and its icon layout is slightly different
  2. This isn’t the iPad 3 - it’s a different device (i.e. a 7 inch iPad hence the slightly different icon arrangement)
  3. It’s a photoshopped invite and means nothing - there won’t be any big surprises

If I was a betting man I’d go with option 3. Whilst it’s intriguing to disect these invites to see if they have any deeper meaning, the reality is that it’s probably been photoshopped together with a few mistakes (the bubbles not matching) and something to get the blogosphere worked up (no home button). I highly doubt that the iPad 3 will lose the home button and I have my reservations that a smaller form factor will be announced (despite the fact that I’d prefer a smaller iPad).

In terms of the announcement, my predictions are:

  • iPad 3 with “Retina Display” that is 2048x1536 with the same @2x syntax for developers to make their apps compatible. It will be slightly more expensive than the iPad 2 (say an extra $50-70) but the iPad 2 will see a price drop to something like $399 or $429.
  • Apple TV with 1080p output (the invite says “something to see” and “something to touch” - Apple TV and iPad 3)
  • Updated iTunes content to accomodate a 1080p Appple TV and an iPad that is beyond 1080p.
  • iOS 5.1 with 3rd party Siri APIs.

I guess we’ll see on March 7th!

« Older Posts