My latest app - the Hyundai Equus iPad Owner ExperienceWell, my latest app is finally live on the App Store. Hyundai Equus iPad Owner Experience is the result of over four months of hard work and numerous sleepless nights. It is a great reference for Equus owners and a wonderful way to learn more about this amazing luxury vehicle.  This was easily the most challenging app I've developed for any platform in a while due to its complexity, the client's requirements, and the sheer number of moving parts.  Considering this, I'm pleased at how successful this project was.  Thanks to a visionary client, a talented design and development team, and the extraordinary dedication of all individuals involved, the Hyundai Equus iPad app is now in the hands of consumers.

Introduction

However, this post isn't intended to discuss how cool the app is (very) or how ambitious Hyundai's use of the iPad is (extremely)... This post is about sharing a few lessons I've learned throughout the life of this project and passing on a few tips I've developed.  I’m proud to say that despite the scale of this app, it passed Apple review without a hitch.  Hopefully this will help other developers in bringing their clients' visions to life on the iPad/iPhone.  So without further ado, here are a few tidbits of knowledge that may prove useful when working on large-scale iOS projects.

Wireframes and Storyboards are NOT Optional

Most seasoned developers know the importance of wireframing and storyboarding, but I can't stress how important it is on large projects to get them right before beginning development.  Wireframes and storyboards serve many vital purposes, especially when working with a remote client:

  • Wireframes help the client understand the structure and flow of your app design.  Your client needs to understand how the user will navigate and interact with the app so that changes during or after development are reduced.
  • Wireframes provide you with a map for creating your view hierarchy.  A well thought-through wireframe will tell you whether you need to account for deep, branching views or shallow, parallel views.  Use the wireframes to determine where you’ll need to subclass UIViewController and UIView.
  • Storyboards are essential for letting the client approve the visual presentation and branding of the app.  iOS development makes it pretty easy to swap graphics on the fly, but only if the size of those graphics and the layout of the view doesn’t change.  Get the client’s sign-off before you throw together a graphically-complex view in IB.

Do Not Rely on the Autorelease Pool

Although the autorelease pool works well in most instances, any project that contains a significant number of custom views may require a more manual memory management approach.  I've found that avoiding autorelease when practical is an easy way to reduce the amount of time spent hunting for memory leaks and app crashers later in the project.

PNGs vs. JPEGs

Some people may not realize that there is a difference in how PNGs and JPEGs are treated in iOS.  We all know that PNGs can contain an alpha channel, but what is not so obvious is that XCode actually treats PNGs and JPEGs differently when it builds your app.  Apple has its own PNG format that contains a pre-multiplied alpha (I highly recommend reading: http://www.modmyi.com/wiki/index.php/Iphone_PNG_images).

There are many reasons why this Apple PNG format is more efficient on the iPhone, but there is one thing in particular that isn’t well documented that developers should be aware of.  Larger images will require large mallocs at runtime when they are decoded and displayed.  This is also true of JPEGs, but the process is reported differently in Instruments.  Allocations may not show any increased memory consumption for PNGs (in certain formats), but Memory Monitor will let you watch the total real memory usage.  If you are getting low memory crashes when using large images, be sure to add Memory Monitor to your Instruments when analyzing your app.  Also, since PNGs are converted to the Apple format when XCode performs a build, using PNGs may increase your build time.  This can be mitigated via your build settings.

Using UIWebViews

Another undocumented issue that developers should be aware of is a potential memory leak when using UIWebViews.  While I’m hopeful that this is fixed in future SDK versions, using UIWebViews to display image and video content seems to result in numerous, small memory leaks.  Even forcing the cache to clear does not recover this leaked memory.  Like the PNG issue, you’ll have to use the Memory Monitor instrument to detect this.  As a result, avoid UIWebViews when possible for presenting non-web content.

The Power of Plists

Some projects have their scope fixed in stone.  If your project’s content and scope is unlikely to change, then hard-coding variables is usually fine.  However, few projects fall into this category.  Most projects change frequently as decisions are made by the client.  To accommodate this, I have learned to use plists whenever possible to define the behavior, content, and meta-data for each of my project’s discrete sections.  This method of abstraction keeps the app agile during (and after) development.  For example, a driving simulator may use a fixed acceleration rate, road and vehicle textures, and prop frequency (trees, buildings, etc).  However, you can save a lot of time by loading these variables from a plist when the simulator is loading.  This makes it easy to tweak the user experience and you’ll already have a data structure for saving user preferences.

Plists are also useful for attaching meta-data to your content.  Let’s say you have a large image gallery presented via a UIScrollView.  If you want to add search functionality to the images, you have to have some type of meta-data index to search.  If you already have a plist defining what images should be loaded into your gallery, its a simple step to add some keywords for each image!

Be Mindful of the Apple Design Principles

I want to emphasize that while it is helpful to use the pre-built iOS controls, it is more important to deliver a seamlessly branded experience to the user.  This sometimes means you need your UI to have a different look than what the standard UIKit controls can offer.  If (more likely, when) you decide to create your own custom UI controls, make sure that you are familiar with Apple’s design principles.  Adhering to them as much as possible will ensure a smoother app approval process.  If you have to break a rule or two, make sure you have a really good reason and that you can defend that reasoning.

Respond to Memory Warnings

This is a simple rule: Always respond to memory warning and release any non-essential items retained in memory.  Period.

Play Nice with Other Apps

Another simple one: When your app goes into the background or is suspended, release any non-essential items (saving to a persistent store if necessary).  If using OpenGL, reduce the render rate to the minimum.

Use the Analyzer and Instruments

Xcode has a beautiful feature called "Build and Analyze".  Before testing your app, be sure to use this feature (found in the build menu) to quickly identify any potential issues in your code.  This is great for finding potential memory leaks, so use it often.  Also, never submit an app to Apple without running Leaks and Allocations in Instruments to verify there are no memory leaks.

Conclusion

This lengthy post is by no means conclusive.  I plan to continue updating this and releasing more articles as time (and projects) go by.  iOS devices really are revolutionizing the way we get and share information and development always evolves.  I hope those of you who read this stay enthusiastic and share your experiences as well!