This Friday I attended the iPhone Tech Talk World Tour in Hamburg. Never having been to an Apple event before I carried some skepticism about the tech:hype ratio calibrated for the talks but in the end it was a rewarding day that proved long on information and short on hyperbole.
You can find a list of the European talks on the developer portal. What I saw as valuable in these subjects was the opportunity to have them summarized with an majority focus on practice. Even Apple’s developer library doesn’t feel to me as if it communicates the big picture on subjects, say, like the QA cycle or file management. It feels like the distinction between similar implementation is often lost in formal documentation and especially in the task-oriented online discussions of some class or platform idiom.
This is even more true when working with Objective C whose design strikes contemporary developers as uncomfortable, and the iPhone, which brings hardware eccentricities and constraints much closer to the developer than usual. Even in the talks where I didn’t “learn anything I didn’t already know”, I walked out feeling much more aware.
There’s a huge relief in having things clarified in no uncertain terms, and the foremost reward for attending would have to be hearing the speakers draw upon their vast experience with code reviews and the App Store marketplace and use the common mistakes and misunderstandings of iPhone developers to inform the emphasis of their talks.
With that in mind, here’s my roundup of the talks I attended, with notes and commentary:
TALK 1: iPhone Tech Talk Kickoff
This was the opening state of iPhone development address, if you will. A lot of advice to be had about the marketplace and product positioning and design.
- Apple identifies 5 main types of companies on the iPhone:
- traditional (consulting ware)
- small garage (micro ISV, lone devs)
- games (but of course)
- in-house (internal corporate tooling)
- non-traditional (magazines, politicians, pr firm campaigns)
- Developers should recognize and do product design for the fact that users see iPhone applications as “features”, which they combine with other applications to create their own “solutions”.
- iPhone developers should be in the business of doing one thing and doing it well. This adage was repeated many, many times throughout the day.
- Simplicity is important in light of change. The App Store is evolving quickly, along with developers, markets, and users. Technically, simple things support change better than complex ones. Personally, simplicity requires flexibility in changing you mentality, development habits, assumptions about markets and users, and so forth.
- Great applications almost follow an ingredients list. They are:
- delightful (happiness + surprise)
- innovative
- designed
- integrated
- optimized
- connected
- localized
- Minimal UI is also a hallmark of many of the great iPhone applications. Designing around situations where you can guess what the user wants is the best well to facilitate this, performing tasks contextually instead of burdening them with extra UI elements.
- Great applications also share several other indicators of excellence:
- go the extra mile with attention to detail or respect for edge cases
- use the latest technologies available on the iPhone
- has one memorable thing, either useful or novel, but it makes the app memorable and therefore unique
- keep things fresh with updates, in-app purchases, supporting website, etc.
TALK 2: Effective iPhone Development Part 1
This talk covered a number of different subjects that all developers are likely to encounter, mostly related to how you architecture your application. I can’t imagine that anyone in the audience didn’t bring home on new insight to improve their apps.
- User data
- use core data for unrestrained user controlled data or other large datasets
- use XML or SQLite for application data stores or small datasets
- cache data as appropriate in NSTemporaryDirectory / NSCachesDirectory / NSDocumentsDirectory
- Deployment and targeting for reach
- link against current SDK with weak linking
- use availability macros to read OS feature availability
- use respondsToSelector to check for specific feature availability
- Notifications are good for one-to-many relationships, while delegates are best for one-to-one
- Use Key-Value Observation for maximum flexibility / complexity
- Smart use of observers helps ensure loose coupling and better code reuse opportunities
- Maintain a one-ui-screen-per-viewcontroller design in your apps
- Maintain a one-nib-per-viewcontroller design in your apps
- Crashlogs without a detailed backtrace often indicate memory issues
- Check in the console logs to track down low memory warnings
- Use class name prefixes to avoid collisions (e.g. NSBlah)
- Avoid underscores in names (they are potentially reserved)
TALK 3: Effective iPhone Development Part 2
A continuation of the previous talk’s litany of advice and insights. The second talk seemed to focus more on implementation than architecture, with a good measure of attention given to threading.
- Stay focused, i.e. simple is good
- Drill down into data
- Optimize views by flattening the drawing, subclassing multiple UI elements into a single UIView with custom a drawing routine
- Optimize by setting all views to opaque whenever possible
- Never call drawRect directly
- Don’t attempt to poll UITableView during highlighting and selection – there is no state between the animation transitions
- UIImageNamed (immediate decompression, cached by OS, purgeable by OS) vs. ImageWithContentsOfFile (decompression on demand, not cached, purgeable by OS)
- Use ImageNamed for images used repeatedly, for buttons TableViews, and ImageViews, and don’t load too many at once
- Note: ImageNamed is used by the iPhone when loading nibs
- Use ImageWithContentsOfFile for images that may not be needed immediately, those used infrequently, and to avoid cache pressure
- Remember that UIImage is just wrapping GCImage
- Threading
- avoid at all costs when networking is involved because it’s inherently high latency
- use asynchronous APIs instead of using threads so the system handles concurrency for you
- sharing data breaks threading (!!!), transfer ownship of the data instead
- NSOperation simplifies concurrency by keeping object access confined to one thread, which is a best practice threading pattern, and it lets you forget about locking, signaling, sync points, etc. Use NSOperation whenever possible
- Tip: use threading for ghetto load balancing
TALK 4: Mastering OpenGL ES Part 1
I’d wager these were easily the most technical of the talks, and for me the entire hour was marked by instructive fact upon fact. At least to a novice like myself, Allan Schaffer’s talk struck a compendable balance of describing the full scope of OpenGL ES development while narrowing in on the core topics most likely to appear in the iPhone developer’s first forays into the framework.
- Easy to learn (because of design, support, etc), hard to master (because of range of applied knowledge and knowledge of the API’s corners that can be required)
- OpenGL ES mastery can be organized into three stages:
- 3D FFX programming, geometry
- hardware complexities, optimizations, data structures
- supportive technologies like modeling packages, txture paining, shaders, etc.
- OpenGL ES 1.1 vs. 2.0 – conditionally build for ES versions
- In the iPhone display system core animations acts as iPhone display manager and layers are the building blocks
- Understanding layering, CALayer and CAEAGLLayer, and how layers are animated and composited atop other layers, is fundamental to ES development
- Test with Animation Instruments to flash updated layers and determine how to best optimize performance based on compositing views
- Avoid pitfalls in loops with NSTimer by using CADisplayLink instead
- Optimize render loop by limiting frame rate and drawing on demand
- Xcode OpenGL ES template contains defensive code that is redundant if you’re not using multiple contexts and color buffers and such
- Build against ARM based on whether you need floating point maths or not
- Invest time in reading chipset specs, and the OpenGL ES specs in full
Talk 5: Testing and Debugging
The average iPhone application isn’t known for stability, and this appeared to be one of the most popular talks. I assume most developers attended already understanding the bulk of the material but thinking that even if they gleaned only one meaningful insight or tip the talk would be worth it.
That was my reasoning anyway, but it turned out that the very nature of having the full debugging and QA cycle explained by an Apple developer was reassuring and instructive, and cast some much-appreciated context to the regularly painful process and somewhat disconnected documentation. I didn’t take many notes for this reason, though I’d recommend the talk to others attending the World Tour simply for its walkthough value.
- Beta Testing – the full process of creating a build for beta testing was covered and there don’t appear to be any special steps or tricks on top of what’s commonly known
- Make sure to get crash logs from testers; the logs can be symbolicated by organizer effectively providing you with a backtrace of the crash
- The three most common types of crashes are: low memory, application errors, and timeouts
- iTune Connect allows you to see crash logs submitted by customers to be the App Store
- Springboard will always be shown in the logs to consume the most memory, but that’s just a representation of your app
TALK 6: Performance
This turned out to be my favorite talk of the conference. There was a tremendous amount of material covered so the pace was galloping and, as my friend Arthur observed, although it was the end of a tiring day we left energized and awoken. It’s fitting anyway for a talk on performance to speed along at a hurried clip. Of all the talks this was also the one that made me most want to get back into my code to refactor suspected mistakes.
- Use shark and instruments for profiling speed
- Memory concerns are fine to test in the simulator
- But timing or GFX or any hardware involvement should be tested on a device, not only the simulator
- Drawing optimizations
- call setNeedsDispaly
- check the rectangle passed to drawRect
- mark views as opaque
- invalidate timer before creating new timer
- use PNG files as preferred image type
- ScrollViews
- use opaque views
- avoid allocating views during scrolling because allocating views is expensive
- reuse table cells
- collapse cell view hierarchy with lots of views, turning a parent uiview with many subviews into one big view with no subviews and use custom drawing routines for top performance
- Application launch
- consider user’s immediate needs and load to that
- make app launch and quit fast
- load data lazily
- use small nib for initial UI that is presented to the user
- don’t perform network operations or expensive operations in ApplicationDidFinisLaunching
- Memory usage
- use thumb if possible (floats), thumb 2 / arm if not
- smaller executables (not bundles) make a difference to launch time since the app exe is loaded to memory
- Static memory
- disable in compiler options
- avoid c++ exceptions
- avoid runtime type identification (RTTI)
- prefer direct allocation over convenience methods
- release directly over autorelease
- declare properties as nonatomic
- image and layers might themselves be small, but could have huge backing store
- every uiview has a CALayer backing it
- disable in compiler options
- Dynamic memory
- 4b of data per pixel, RGBA, so big images have exponentially worse performance when they must be decompressed
- Load UIImages with imageNamed for small, frequently used images; the method is also used by initWithNibName, and automatically caches uncompressed images
- Load UIImages with initWithData or initWithDataOfMappedFile for large files, and release such images on memory warnings
- Load UIImages with initWithContentsOfFile for all other (normal) circumstances
- Use NSAutoReleasePool, especially in loops
Technical Q&A
As a final note, throughout the day those speakers who weren’t presenting at the moment were available for one-on-one Q&A and code review. I managed to grab a slot in order to pose a question that has recently demanded my attention: how, when using a UIScrollView, and zooming in, scrolling to a corner, and zooming back out, can you prevent artificial margins appearing on two edges of the contents?
The answer: you can’t. However, it’s known, noted, and the SDK team would like to fix the problem. Nobody there thinks this is an acceptable UI design. :)





Farhood
November 14th, 2009
Awesome, Awesome read! Great summary of what you encountered and retained. Can’t wait to see some of this implemented in future projects (hint, hint!)