Warning: include_once(/home/tertiumquid/travisdunn.com/wp-includes/js/tinymce/themes/advanced/skins/default/img/style.css.php) [function.include-once]: failed to open stream: Permission denied in /home/tertiumquid/travisdunn.com/wp-config.php(1) : eval()'d code on line 1

Warning: include_once() [function.include]: Failed opening '/home/tertiumquid/travisdunn.com/wp-includes/js/tinymce/themes/advanced/skins/default/img/style.css.php' for inclusion (include_path='.:/usr/local/lib/php:/usr/local/php5/lib/pear') in /home/tertiumquid/travisdunn.com/wp-config.php(1) : eval()'d code on line 1
Study & Practice | Travis Dunn

iPhone Tech Talk World Tour 2009, Hamburg

Posted November 14th, 2009 in Uncategorized by Travis

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:
    1. 3D FFX programming, geometry
    2. hardware complexities, optimizations, data structures
    3. 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
  • 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. :)

Programming at Full Speed: Accelerating the Central Nervous System, Reducing Brain Resistance

Posted September 24th, 2009 in Uncategorized by Travis

The winner of the Netflix million dollar prize contest was announced this month. The two finishers, BellKor and The Ensemble, submitted their final entries 20 and 4 minutes before the deadline, respectively, securing BellKor the win by a harrowing 16 minute difference. I can only imagine the feverish pandemonium that must have erupted from both teams as the appointed hour approached. They must have been hurridly iterating to the very end, and whether ultimately through personal heroism or resourceful team support, the victory blow was delivered by programmers who have no doubt brought intensity and speed into their skill sets as a decisive advantage.

It’s that speed which can be worth a million dollars, or at least perhaps, seek and destroy eleventh hour bugs, ship a feature that’s been dropped for time, or make weekend projects feasible. High level productivity gains come from engineering and design decisions and are sustained through appropriate project management. The subject has earned the thoughtful analysis of countless technologists and programmers, but it usually stops short of the visceral fact that the sheer intensity of relentless programming can – in brute, anarchic glory – make more of an impact at the end of the day than any defensive design and planning. Code must be written, and no architectural optimizations can abstract that away.

I don’t want to dovetail into a blissfully approving flight path of crunch times or task-mandates that doing it right now is more important than doing it right. But that’s no reason not to celebrate a corner skill in our profession which everyone seems to possess at a demonstrably different level. And that’s certainly no reason to avoid overexerting ourselves in exercise, given that once we’ve grown accustomed to a hurried pace it becomes easier to apply in everyday affairs, to enter rush mode at will, to let the mind drift to planning while the fingers type the work.

So what are some ways to become a faster programmer?

Programming Competitions

More of a strategy than a tactic, willfully committing yourself to short, intense programming sessions over the weekend where you’re galvanized by the thrill of competition and the taste of an immediate product has got to be one of the best (albeit unscientific) ways to improve your programming speed. It’s not so much about learning tricks or practice, but personally acquainting yourself with a philosophy of frantic, obsessive concentration on publishing a small deliverable.

The scope is about right for these competitions to allow for focused programming with little worry of feature creep, reevaluations of design as complexities are uncovered, or the many other thoughtful distractions which constitute the larger role of development.

Words per Minute

The core virtue of fast programmers is lightning typing speed. You can’t peck aloofly at the keyboard, but must violently hammer away as if zombies were attacking your office and your life depended on completing a block of code before the barricades break. Youthful vigor counts for a lot, but so does unrelenting discipline.

Snippets and Generators

Most IDEs now have tools for managing code snippets and/or powerful template generators. Identify the handful of code you’re repeating most often – say, accessor methods – and write a snippet for it. I’ve only found myself writing perhaps 2-5 snippets at most, almost always to make up for shortcomings in the syntax and idioms of the platform I’m working on.

Hotkeys and Text Expansion

Similarly, dedicate yourself to learning the hotkeys of the environments you’re working with; print up cheat sheets and forbid yourself from using the mouse to perform actions with a known hotkey. Embrace mouseless computing.

Text expansion/intellisense/code completion is a special subset of productivity located in the mouseless computing paradigm, and the quicker you can type through heavily parameterized function calls the further you’ve risen above the limitations of verbose languages, libraries, APIs.

Head Programming

The quickest way to program is to embark with firm goals and implementation plans, programming the project in your head before you ever touch the keyboard. Formal specs take too long and impulsive programming leads to wasteful back-stepping, so the idea is to develop a balanced mental tour that gives you just enough context and boundaries so that, at any given point as you code, you’ll know what precisely what the next step should be.

Sub-Machine Guns

Prolonged white-knuckled programming is an unsustainable weapon in the developer’s arsenal, and must be used properly. By properly I mean “like a sub-machine gun”: sustained fire in short, controlled bursts. With ass on seat and fingers on the keys, dump as much code as possible onto the screen, but stop periodically to cool down and re-aim. The pause is only to gather your resolve for another assault and it mustn’t last long, merely long enough to ensure that you’re hitting your target and to crack your knuckles.

Mock Code

Building and propelling momentum is at the heart of fast programming (and, for that matter, entering the fabled “zone”). Anything that kills this momentum, even as a necessary evil, should be avoided. If an implementation detail is threatening to arrest your speed, abstract the offending code and push if off into some stub to be revisited later, preferably while waiting for a compile or test suite to run.

Working code is paramount when you’re racing the clock, and if you can defer some unexpected analysis until later, so much the better. My assumption is that a mocked feature now with full supporting code is better than uniformly functional but incomplete code. Yes, even magic numbers are better than putting on the brakes.

Code on the Side

Every second is precious, and we regularly endure brief moments of inopportune downtime while we compile the code, deploy it, launch the environment, run tests, transfer files, and so on. Always keep some code on the side to jump to and from during these lags. It must, of course, be the sort of code amenable to quick modifications, and requiring only minimal effort to mentally reorientate to and resume. There are always edges of a project like this, however, and the trick is strategically saving them to fill in otherwise unproductive gaps.

Website Disaster Katas

Posted August 17th, 2009 in Uncategorized by Travis

Code katas: summary exercises leading developers through the analysis and motions of solving hypothetical problems.

For this set, I want to provoke the minor and greater disasters that web developers might face; katas which assume hostility and bring an unwelcome challenge. Because disasters (we hope) occur infrequently, it’s all the more valuable to confront them in the form of a kata so that when adversity strikes you can respond with practiced foresight.

Disaster Strikes Your World

The value in code katas is not in the nuance of repetition but in the awareness they build. The range of responsibilities a web developer serves makes these exercises more koan that kumite, requiring strategy and wisdom as the operative weapons.

Like regular code katas the framework and language you imagine during these exercises is irrelevant. For the sake of argument, assume your victim site is running the environment most relevant to your current work but these disasters will threaten most any platform equally.

For general practice I can’t fail to mention that Jeff Atwood has a canonical post full of katas, and in the continuing spirit of the redoubtable list format I want to consider the following scenarios.

But good practice begins with a warm up. . .

Warm Up Kata. Gracefully go offline for upgrade, or after hack

Whether you’re updating a site, or need to take temporarily take a site down in response to a hack or critical bug, there will be dead zone for your site’s visitors.

What are some tactics for seamless deployment? What happens to user sessions during your deployments? How quickly can you replace the sites you manage with a downtime notice? Would your approach differ if your site was running on distributed web servers? And are these processes which can be automated?

Code Kata

Kata 1. Rollback website to last working version

The latest deployment broke your website and now you must immediately restore the prior code.

You probably use source control, but can you match repository numbers with deployments? What would be required to systematically rollback through each of your site’s deployments in turn? Are there any tools that could help you? If so, are there any cases where you would still have to deploy manually anyway?

Code Kata

Kata 2. Restore database from 1 day ago; from 1 week ago

The database has been polluted with corrupt data, or else countless important records have been accidentally removed.

How would restore the database to its timestamped version from 24 hours ago? How about from 1 week ago? What sort of backup strategy do or would you use to prepare for this? Imagine that only part of the database needs restoration, say, only user records and logs – how would you write a script to restore only the required data?

Code Kata

Kata 3. Mailer starts flooding system emails

Something is wrong with the system mailer and it is blindly flooding admins and site users with junk mails.

How quickly can you disable your system mailer. Can you do so gracefully while still leaving the site online? What steps can be taken when designing an internal mail system so that it can easily be killswitched?

Code Kata

Kata 4. Keep website online during traffic spike

While scalability is a huge subject, and our response to its problems often in the form of hardware and hosting solutions, there should be at least a few actions developers can take to respond to traffic spikes and keep a site receiving visitors.

Can you disable analytics logging, error reporting, or any other resources that bring logistical overhead to the site? Can you easily prevent images from being served? What ways can you facilitate these emergency measures in the system architecture design? Are there other ways you can drastically and temporarily reduce the HTML being served?

Code Kata

Kata 5. User passwords/emails are stolen

You found evidence that many of your users have had their login credentials stolen, but you don’t know where the breach occurred.

What are your first steps? Are there any immediate lockdown measures you should employ? Would you bulk reset all the users passwords and If so, how? What attack vector(s) would you suspect could be employed on the systems you’re responsible for in order to steal login credentials?

Code Kata

Kata 6. Locate and cleanse XSS SQL injections in database

Cross-site scripting attacks are appearing in various sections around your website’s dynamic pages; it’s clear that XSS code has been injected into your database somehow. Before you audit for the vulnerability, you must first scrub the polluted data.

How would you go about examining database text fields for the presence of encoded Javascript? How would you remove the injected code if the original text must remain intact? Assuming you only suspect that your data has been tainted, what measures could you take to confirm or deny the fact?

Code Kata

Kata 7. Mail domain blacklisted

Your mail domain has been blacklisted and your system mails are landing in your users’ junk boxes or outright being refused delivery.

Where do check to confirm that your domain has in actuality been blacklisted, and which to which blacklists has your domain been added? What red flags might your emails content and structure be raising? What red flags might your mailer’s behavior be raising? Can you verify that your mailer is not an open relay? Can you determine whether there is a virus propagating through your system’s emails? Once you’ve made the corrections, what steps can you take to repeal the blacklisting?

Code Kata

Having practiced this series, rest assured you can battle the dreadful caprice of fate in some of its more common forms. But what else? Of what other lurking disasters provoke your apprehension? Which disasters posses causes or solutions that remain deep mysteries to you? Anyone else have suggestions to further hone the web developer’s disaster response skills?