I came up with this idea a couple of days ago for a simple clock where each digit is drawn as a series of lines that can then break up and reform to the next digit each second. The code is reasonable simple but the result is quite pretty.
I wrote this dumb script to print a list of all the Apple Developer services that are currently online.
Last week I published Keep 2.2 however there were a couple of odd bugs with in-app purchases that have now been resolved. I had the bug fixed on Sunday, however I was unfortunately unable to get an expedited review because of the extended Apple Developer site outage so the update wasn’t approved until today.
The latest version of Keep Calm has introduced a bug when attempting to restore previously purchased items in the store. Currently the code that restores the purchase my side is not being run (due to a really stupid faulty if statement) however if you have already purchased an item you can press the ‘Buy’ button again and it will automatically acknowledge that you have already purchased an item with no need to buy it again.
I’ve just finished a fix for this bug which I intend to send to Apple shortly, so hopefully the bug will be resolved within the next few days.
Today I updated Keep Calm to version 2.2. This new version adds the following new features:
- Completely new flat UI – this is an iOS 7 style UI as I haven’t decided yet whether I will require iOS 7 when it comes out
- The new UI makes it a lot faster to make posters – on average fewer taps are require to make a poster and it is now a lot clearer how one carries out basic tasks
- The app is faster – for those interested, I took out redundant Core Data and Core Graphics calls
- When you first launch the app you are welcomed with a new welcome screen. I’m particularly pleased with these because it provides quite a nice way of demoing some of the Pro features. Again, for those interested I use a UIScrollView and a single UIImageView that gets translated by the scroll offset
- Runs much better on the iPhone 5 – I had spent a lot of time focussing on designing the regular iPhone version (because posters seem less stretched) rather than the full iPhone 5 screen which meant that there were a few buttons that weren’t showing up in the right places. This version is a lot more solid
- Less code – this isn’t really a feature that my users need to care about, but I swear to god it makes my life a lot easier. By reducing the total number of delegates in the app (almost every single view controller – and some views/models too – declared a protocol) and making each view controller focused on the purpose of the app rather than being generic meant that I could write a lot less code. I also removed a lot of UIActionSheets because a) I don’t think they look very pretty and b) I really don’t like declaring them and writing UIActionSheetDelegate methods 😦
On the whole, users should find this update far more enjoyable and easy to use than previously as they upgrade over the course of the weekend.
- C# is a great language and it is rapidly becoming more popular across many platforms. All C# outside of Microsoft is based off of the Mono project and there are two commercial bindings for iOS. Xamarin allows you to write C# code that integrates with every single Cocoa Touch API (and they have day one updates for each new iOS version, although you can also join their beta programme to get new features at the same time as Apple’s betas, I believe). Unfortunately the free license limits the compiled size of your app but in my experience this isn’t too much of an issue. Being able to write C# proves to be a huge advantage however I’ve found that deploying to device can be quite slow, and the start up time for apps is often a few seconds slower (it is managed rather than native code) and that some patterns from Objective-C such as protocols/delegates don’t transfer over to C# as well – you have to create a subclass of UITableViewDataSource, for example, rather than a class that accepts UITableViewDataSource as a protocol. Alternatively, if you want to write games and don’t care about UIKit, Unity is a great tool that allows you to write your game in C# and deploy across several platforms. I’ve found, again, that the disadvantage of managed code does mean that Unity games tend to be a tiny bit slower than their Objective-C equivalents.
- Despite Apple’s allegiance to the language in the early OSX days, Java is not a viable option for iOS development however a few bindings do exist. Codename One converts Java Bytecode to native code across several platforms (iOS, Android and Windows Phone) with a native UI. Their site is unclear whether or not they are actually binding to UIKit or if they are creating a native style UI. Alternatively, Google’s J2ObjC converts Java code to Objective-C. This project is very appropriate if you need to use Java for model code rather than UI code and it seems like a sensible choice if you have business logic you need to run on iOS.
- I had initially expected that there would be very few options for running Python on iOS due to earlier limitations on interpreted languages however evidently the popularity of the language has lead to several options emerging. The first option, PyObjC provides bridging between Objective-C and Python and allows you to write apps that link with UIKit in Python but, like with C#, the differences between the two languages mean that the Python code feels a little clunky. Another option is PyMob, however I can’t find a public version of it to play around with. Finally, Kivy presents itself as a far more viable option for writing iOS games in Python; it makes no attempt to bind with UIKit which brings the benefit that it cross-platform with support for iOS, Android, OSX, Windows and even the Raspberry Pi! I’ve recently enjoyed Pythonista, which is an iOS app that allows you to write Python on your iPad or iPhone. I’ve been using it for about a month and I’ve really enjoyed it – the price tag is definitely worth it.
- I’ve never really played around with Ruby for a particularly large amount of time but it has always struck me as the interpreted equivalent of Objective-C, which brings the benefit that the syntax doesn’t feel broken when attempting to bind to Objective-C – the MVC style, as well as protocols/delegates is adopted by both languages. RubyMotion links directly with Cocoa/Cocoa Touch and compiles to native code. Unfortunately the license is $200, however compared to the other languages I’ve mentioned here that definitely seems worth it.
- If you have experience with Flash you would have been initially disappointed by the decision that Flash wouldn’t be available on the iPhone, however thanks to Adobe’s Flash platform with Flex it is now possible to deploy Flash apps to the App Store. This doesn’t strike me as a very good option, however, because there is absolutely no effort to work with the standard iOS frameworks – the aim seems to be to make it possible to deploy your Flash game onto iOS. Furthermore, you lose a lot in performance because the Flash runtime seems to be addicted to battery power, using nearly 100% CPU and every spare bit of RAM – these are some of the reasons, aside from lack of demand – that Flash was removed from Play Store on Android.
When writing this blog post I came across a very common pattern. Often a language will have several bindings available for it, however none of them will be able to maintain the feel of the language (Ruby was the only one that isn’t entirely true of this) because they have to adopt Objective-C idioms which they may not employ themselves. The two best examples of this are protocols/delegates and the way Objective-C functions are named compared to how they are in all other languages. Ultimately, I’ve come to the conclusion that it is probably easiest to build your next iOS app in Objective-C, regardless of how tempting another language may be:
- There is significantly more documentation available for Objective-C
- There are disadvantages to working in Objective-C and some things can be achieved in a lot less code in other languages, but otherwise it works perfectly well as a language. With a bit of experience, it really isn’t too challenging to write good re-usable code that runs quickly
- All the Cocoa Touch frameworks are built in Objective-C and are designed to be interacted with from Objective-C rather than another language with different idioms
Today I have released version 2.1 of Keep Calm on the App Store. This new version has the following new features:
- Pro users can now export images of any size they like (up to 4000px by 4000px) making it easier to create posters for print or the web; you could create a desktop wallpaper if you wished
- Pro users can now now also import backgrounds by pasting them from the clipboard rather than having to save them to their device first
- Pro and free users now get faster scrolling across the app (I’ve optimised all the UICollectionViews to use NSCache to reduce loading time)
- Pro users no longer see multiple menus appearing at once
- All users can delete all their posters at the press of a button to reduce space
- Cancel buttons now work in a more standardised way between the iPad and iPhone version
- The images used by the app (icons, backgrounds, etc) are now significantly smaller which has reduced the App Store size of the app by 40%
Head over to the App Store now to update to Keep Calm 2.1. I intend to appropriately update the Android versions however I’m in the process of migrating code over to Android Studio from Eclipse.
A few weeks ago I blogged about tactics you can use to reduce memory usage in your iOS app however I came across a neat class that can make your life a lot easier.
NSCache is a very simple class that is little more than an NSMutableDictionary except that it will automatically clear objects when memory usage becomes high or they haven’t been used recently. For an app heavy on file/network IO this is perfect.
Keep Calm’s main view is a grid of images. Usually these are loaded from a thumbnail that is automatically generated in the background every time the user updates their poster. This works fine, however it can take up to 10ms to load a picture, so when scrolling (especially on iPad where up to four pictures are presented in one row) to a new row there is a slight jitter even though the images are loaded asynchronously.
So then I added an NSCache to store all the thumbnails and suddenly scrolling became completely smooth because the thumbnails were only loaded when they needed to be (if it all, one would expect that a tablet with 1GB of RAM could handle ~30 images happily). Another benefit of NSCache is that you can limit the total ‘cost’ of all the items (the cost of an item is a relative number you can dictate).
Obviously it can be used for things other than just images, but if you are working on any kind of app that presents images in a grid you can save yourself a lot of time by using NSCache.
I’ve blogged previously about memory management with ARC in iOS but I thought I would cover some different aspects that aren’t related to retain/release cycles but focus on when stuff really needs to be kept in memory. I’ve split this post into a few different sections based on different areas of iOS development.
Core Data is really great (except if you’re using it with iCloud) as an ORM and I’ve found it to be a worthy replacement to SQLite on iOS, albiet with some limitations. I’ve generally found that it uses a little more memory than SQLite does for the same/similar tasks, but keeping a context and reusing it throughout your application (except in different threads) generally works quite well.
A major benefit of Core Data is NSFetchedResultsController. If you wanted to fetch an object from a Core Data store normally you might do something like the following:
NSFetchRequest *fetchRequest = [NSFetchRequest new]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:self.context]; [fetchRequest setEntity:entity]; NSArray * results = [self.context executeFetchRequest:fetchRequest error:nil];
If you’ve only got a few attributes on your object with few (if any) relationships and there are only going to be a small number of them, then this approach works fine. But what if they’re bigger than you think they are? What if each object has an image attached to it and there are 1000 objects? Your users may surprise you.
Keeping a huge number of objects in memory at any one time is never going to be a sensible idea, so thankfully Apple has provided us with an alternative. I shall not explain all the details of how NSFetchedResultsController works because Ray Wenderlich has a pretty good tutorial on it but it means that you only have to fetch an object when you actually need it, and after that it disappears, which can massively reduce memory load and massively increase table/collection view performance.
Apple generally encourages developers that they ought to use separate image files for iPad, iPhone, Retina and Non-Retina devices (although, based on normal release cycles, I suspect there will be no non-Retina devices available by the end of this year and no non-Retina devices receiving OS updates by the end of next year) and it is incredibly important that you only keep an image in memory that is the highest resolution that you need.
For example, say you are working on an app that does photo manipulation and users can load photos from their camera. On an iPhone, these images are going to be eight megapixels (it’s nearer 7.9 million pixels) however the iPhone screen only has 0.7 million pixels – less than a tenth. The full image doesn’t need to be kept in memory, so it be resized before being presented in the app. However, if the user needs to export their edited photo they may wish to do so at a higher resolution, so the the original photo should be saved to disk temporarily.
If you want some decent code that resizes UIImages accurately (and quickly) I recommend the UIImage categories described in this blog post. In general it is a lot quicker to use Quartz2D for a task like this because converting the image to a Core Image type can be slow, and converting it back can be slower.
Although not entirely related, always be wary of which format you are using for your images. Apple recommends PNGs everywhere, but JPEG often provides much better compression for photos.
Strings and big data from the web
I’ve found that storing large NSStrings (about a million characters large) to be generally stupid because a) it slows iOS devices down big time and b) some NSString functions become incredibly slow. It is therefore wise to read a file line by line if you are only processing a small chunk at a time, for example. Alternatively use SQLite if you can so that text can be split up.
Also be aware of loading data from the web. If you can absolutely guarantee its source and you know how big it is, the download it with NSData and keep it in memory. On the other hand, can you absolutely guarantee that what you are downloading is small and won’t fill up the RAM (which can be an issue on mobile devices, especially older ones)? Use other functions instead of loading it one go.
Today I was playing around a little with C# and I wrote a simple tool that will generate a color palette of the colors that make up an image. You can get the source on GitHub.
The code works by first loading the image and then counting the number of pixels for each value of hue and saturation. The mean number of pixels per color is then calculated and the results are plotted to a 255px by 360px image and the color is determined by how much greater than the mean it is. Below are some more samples of palettes that I produced: