iPhone apps come in all shapes and form. Some are really basic and doesn’t fill any other purpose than showing how much of a geek you are, others are just for laughs or passing time, some are really useful and practical. Personally I’m not much of geek app fan although you will find the Lightsaber app on my iPhone. Useful apps tend to have one thing in common: they depend on internet connections and communicate with a central server/back end. There are a few useful apps that don’t fall into this category, an example is the excellent FastContacts. From comments on this blog, emails and forums I get the impression that there are quite a few who struggle with their internet enabled apps. I want to share some ideas, tips and techniques that can simplify and improve your app.

Objective-C

I think the biggest problem for developers who want to build apps for the iPhone is the programming language itself. Before the iPhone I had never heard about Objective-C and that’s basically because Apple is the only major player who promote and use it. Even though Objective-C sits on top of C the syntax is not at all what I was used to and my C/C++ experience is more or less what we did at College. With the risk of being flamed I argue that no sane person build GUI applications in C/C++. The memory management is also quite different in Objective-C than C. If you are also new to Objective-C I would recommend that you pick up a book about it and read through the basics. Before I started developing I bought Cocoa Programming For MAC OS X by Aaron Hillegass, the first chapters do a great job of getting you up to speed on the basics of Objective-C.

Architecture for a server/client app

Chances are you are more familiar with languages such as C#/VB.NET/Java/Ruby etc. To ease the implementation of your app you should try to put as much functionality as possible in your service. You can save a lot of grief by processing the data before it’s sent to your app, making sure you don’t have to cast types or parse complex structures in a language you are not totally comfortable with. There are more advantages with keeping the logic outside the application, your app will be faster because you don’t have to process the data further and it’s also easier make changes to your service than releasing a new app. An example: you want to display a price in your app, instead of sending the price as a float to the app, you format it and send it as a string. Changes to the currency format can then be done in the service.

Keep it small
If the data you want to consume come from a service you don’t control, build your own service that pull the data from that service and format it in a way that suite your app. Chances are you can reduce the information sent to the app so it includes exactly the bits you need. This will improve your applications performance.

Make as few connections/requests as possible
Depending on how much data you’re sending and receiving in your app you should optimize the requests and data per request. Receiving data in one request is always faster than making 2 or more requests for the same data. Receiving too much data at once can make your app feel slow initially. A good technique is to load data lazily, meaning when you actually need it. At the same time it’s a good technique to load what the user sees right now but also what you expect them to see next. A good example of this is an image gallery in a scroll view. Loading all the images at once will make your app slow, instead load the image the user is watching right now as well as the next and previous image. That way, when the user scroll to see the next image, it’s already loaded and the app feels really fast.

Consuming XML

The easiest structured data format to consume is XML, of course. Apple has published a best practice app called XMLPerformance, it’s available at the iPhone developer portal. The fastest most effective way to parse XML is done using NSXMLParser, it is however a bit tedious to work with. I recommend that you design your XML structure to pass data as attributes when possible instead of elements. If you pass data inside elements you will have to read it through the foundCharacters event instead of accessing it directly in didStartElement. Here’s an example to explain this.

Bad XML structure

XML: <list><item>The item contains something interesting</item></list>

To parse this your will need a variable to hold text read from elements. This variable should be emptied/created in didStartElement. In foundCharacters you must append the read value to your variable. Finally in didEndElement you must assign the value of your temporary variable to the object where you want to store the consumed data.

Better XML structure

XML: <list><item info=”The item contains something interesting” /></list>

This requires less to parse. The didStartElement method takes a NSDictionary containing all attributes for that element so we can assign the value of info directly to our object by using the objectForKey method of the dictionary. I’ve implemented this technique in my CoreData example app.

While XML is an excellent markup for structured data it does provide quite a bit of overhead. If you’re passing lots of small pieces of information chances are the XML markup weighs more than the actual information. Try to keep your XML understandable but as short as possible by abbreviating element and attribute names.

Use REST not SOAP

There’s no reason to use SOAP when communicating with your service. The iPhone framework doesn’t support SOAP so don’t bother battling with it. There’s a common misconception that if you’re using .NET you have to use SOAP. This NOT true! By enabling HttpGet or HttpPost you can communicate with your ASMX service without SOAP and in .NET 3.5 WCF does support Get/Post as well. If you enable HttpGet you can call an ASMX web service like so: http://yourserver.com/service.asmx/FunctionName?parameter=somevalue.
The result will be plain problem free XML. .NET is an excellent back-end platform for your app, don’t believe the forum trolls.

Consuming images

Everyone loves images, right? Getting images from a server can be slow, especially if you’re on a slow GPRS connection. Make sure the images you send are optimized for your app. Images you consume are not larger than they need to be, don’t load 800×600 sized image.
Run compression tests on typical images that you display in you app. The screen is rather small and most times the image doesn’t have to be super detailed. Normally you can compress a jpeg to 40-50% and still find the image acceptable on the iPhone. This will reduce the size of your full quality image with more than 50%! Your application be faster and the end user will thank you, their cell carrier won’t.

If you have a large amount of images that change over time, perhaps users upload their own images. Consider adding resize and compression functionality on your server. There are libraries available, some for free, that can do the resize and quality reduction for you. If you’re using .NET WebSuperGoo has an excellent library called ImageGlue (not free), or you can find free libraries that use GDI+.
If you are consuming large images from other sources than your own you can still route them through your own server and let it resize their images for your app.

If you want super detailed high quality images a technique to improve the user experience is to first serve an image of very low quality, jpeg of 15% or so. It will load almost instantly. Then start downloading your high quality image and swap the low quality image when it’s done. This technique is used by Facebook in their gallery. On a slow connection the image first appear blurry and after a short while it is swapped to a crisp high quality image. Noone wants to watch a a loading screen for 10 seconds.

CoreData/SqLite

CoreData is new in iPhone OS 3.0, and it’s great! If you’re pulling lots of data from a server consider using CoreData to store it on the phone so you don’t have to go get it over and over. CoreData is so easy to use that except from the initial learning curve it won’t require a lot of code or add complexity. Another benefit with storing server data on the device is that it will be available even offline. Apple has a information on CoreData and you can check out my post (comes with example project) on CoreData.

Ads: Web site hosting , Server Colocation

Related posts