Working in different languages on iOS

The standard language for developing iOS apps is Objective-C and it is what the vast majority of tutorials and sample code for the platform are written in, however over the last year I’ve seen several languages become increasingly dominant on the iOS platform. In this post I’ve tried to review and list as many of the languages as possible. I’ve ignored C/C++ from his post because they are within the Cocoa Touch tool chain already. I’ve also ignored JavaScript and other web technologies because so many platforms and frameworks already exist for them – I’m more interested in compiled platforms.

  • 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
  • You are potentially going to be making huge performance sacrifices. In cases when you have an interpreted language like Python or JavaScript this will be an obvious issue but even the performance of C# is radically different on mobile devices to native code. The most simple reason for this is Garbage Collection. Objective-C isn’t GC (the feature was deprecated several years and has never been available on the iPhone) however it uses Automatic Reference Counting instead to manage memory. In some ways this is far more sensible because the “Garbage Collection” effectively happens once at compile time, saving CPU cycles later but on the other hand it may confuse programmers coming from other languages – but this has always been a “feature” of Objective-C :).

Lessons from iOS dev #2: Delegates are good, blocks are better

One of the core fundamentals of Objective-C is protocols and delegates. Almost every single Objective-C app is likely to use them in some way or another because for many years they have been the ubiquitous way to communicate universally between classes. Whilst they are highly useful and I use them pretty much everywhere, they aren’t always the best solution to the problem.

Keep Calm has two main view controllers (the grid and editing view) and each of them is a delegate for about forty odd different protocols. At least thirty of them are protocols I’ve written myself, rather than Apple ones such as UICollectionViewDataSource. I’ve done a reasonably good job at using #pragma – marks to organise the various methods in the delegates, but the classes are beginning to feel a little bloated.

The new alternative is to use blocks instead. Blocks are essentially an extension of C function pointers. The main benefit is that it massively reduces the amount of code you have to write complete a task:

With a protocol and delegate

@protocol MyClassDelegate

-(void)doSomethingInDelegate;

@end

@interface MyClass : NSObject

@property id<MyClassDelegate> delegate;

-(void)doSomething

@end

@implementation MyClass

-(void)doSomething
{
    [self.delegate doSomethingInDelegate];
}

@end

@interface MyOtherClass<MyClassDelegate> : NSObject
...
@end

@implementation MyOtherClass

-(void)doSomethingInDelegate
{
    NSLog(@"Doing something in delegate");
}

@end

With a block

@interface MyClass : NSObject

-(void)doSomething:(void (^)(void))block;

@end

@implementation MyClass

-(void)doSomething:(void (^)(void))block
{
    block();
}

@end

@implementation MyOtherClass

-(void)begin
{
    [self.myClass doSomething:^(){
        NSLog(@"Doing something in other class");
    }];
}

@end

Obviously the latter example is much shorter and the code is a little easier to read (once you get used to the syntax of blocks). Apple is beginning to use blocks across the Cocoa and Cocoa Touch frameworks for everything from fast iteration to sorting to completion handlers.

There are a lot of cases where blocks aren’t appropriate though – I wouldn’t make a table data source with blocks, for example, because the number of blocks would become ridiculous. In my mind they are best for short snippets of code where they are replacing a protocol that one uses a maximum of two functions. Another disadvantage is that blocks inside blocks produces ridiculously ugly code. Even with only three blocks inside one another my code is comfortably running off the screen in Xcode, which is a pain.

I’ve also got mixed views on how reusable the code produced by blocks is. You are effectively defining functions within functions, which makes it harder to take the source and use it elsewhere because you have to write the block syntax into regular Objective-C function syntax.

Blocks are very useful and its worth learning about them from Apple’s documentation. I’ve only touched on some of the things that you can do with them and I am sure that in the future Apple will carry on introducing them across Cocoa.

Reducing the size of images in iOS apps

For a surprisingly simple app, Keep Calm on iOS has required a reasonable amount of maintainence. Like many iOS apps it uses a lot of images to improve the user experience, and in the first version I had over 150 pictures because I allow users to change the crown. From the most recent version onwards there are over 1000 pictures as users can optionally purchase extras. This has pushed the app download size up from 2MB to around 20MB with around 19.5MB solely being images.

I decided that I wanted to be able to reduce the size and number of images in the app bundle but I didn’t want to reduce image quality or number.

The first option was to compress all of the PNGs using a tool like pngcrush however I’m only storing PNGs with one channel (alpha) so this had virtually no effect. I had also considered storing the original SVG files I had generated them from, but the addition of SVG rendering libraries, saving code and Core Image filters meant that I wouldn’t have seen any major reduction in the bundle size. I also had a look into zipping the files (and tarring them) however this reduced less than 1% because of pre-existing compression in the PNG files.

The next option I decided to investigate was putting all of the images in one single file, like a sprite sheet. This would mean PNG compression could help to reduce the amount of overhead on each file whilst maintaining the original quality.

I then wrote some ridiculously simple code for a Mac app that read in all of the files and drew them onto a Quartz 2D canvas (they’re all 300px by 300px at the most, so I just drew them in a square grid). This then produced a PNG file that was around 18MB, so I didn’t really gain anything.

Just to see if the NSImage compression code wasn’t great, I exported the image in GIMP but there was virtually no change. My images were basically one giant white PNG with an alpha channel, so in theory the file should have been a bit smaller (I was being optimistic, it is around 36 megapixels). I then added a black background to the image and exported it with GIMP without the alpha channel and magically the filesize reduced from 18MB to just under 4MB. This would keep my app size reasonably low and reduce the installation process because the iOS devices wouldn’t have to unpack over 1000 files, it would be less than 200.

The next problem was that I would now have to ‘unpack’ all of the extra icons when the user purchased them. It turns out that with a UIImage category you can pretty quickly (according to an Xcode log I managed 40 images/second on an old generation iPod Touch) crop the images out of the original and save them to disk. I had been concerned that it would not be able to load such a large image into memory, however I incredibly didn’t get any memory warnings when doing so.

The next problem I faced was that I didn’t need the black background in each image. The easy solution to fixing this is to use a Core Image filter called CIColorMatrix which multiplies each color value and adds a value onto it. I could then just multiply all RGB values by 0 and add on 1 to set them to alpha. The new alpha could then just be 1 multiplied by one of the original RGB values.

I then wrote some new code that loaded the image using UIImage and applied the filter using Core Image before running the same splitting routine. This worked perfectly (and at about the same speed) in the simulator but I couldn’t get it working on the device – the images would crop but they would be completely blank, which was useless. I was also getting memory warnings.

From what I can gather UIImage will keep the original compressed version of the image in memory, hence why it could load a 4MB 36 megapixel image on a device. Core Image, on the other hand, needs the raw image data and so uncompresses it, which meant holding 36 megapixels * 4 bytes per pixel = 144MB of data in RAM. Instead of feeding me back a useable image it just gave up and gave me a blank 36MP image, which was useless. My final solution is therefore either to split the large image into smaller images or just apply Core Image filters when the images get displayed.

In conclusion, if you’ve got a large number (probably less than 200) of small images in your app you could probably reduce the app size significantly by putting them all in one image and unpacking the individual images from that. On the other hand, if you have a small number of large images it is probably best to keep them in individual images so that your app doesn’t crash.