Architecting a Shared Codebase from Browser and Desktop
Architecting a Shared Codebase from Browser and Desktop
By David Coletta
Maybe more hacking than Architecting. First time giving the talk so all feedback is welcome.
Goal: Build a browser application and an AIR application from a single shared codebase.
Four areas of concern: UI design (People have different expectations for a desktop based word processor versus a web based word processor), shared code packaging (giant pile of code delivered in two different forms, downloaded modules versus bundled with application), abstracting the AIR APIs (clipboard access is different in the two models), many other things including Singletons.
Primary UI differences: Browser version surrounded by browser chrome with AIR the application looks cleaner. Demo of Buzzword in browser and the AIR desktop version. Native menus in desktop menus versus flex based menus.
UI issues: Installation, automatic updates (Much improved in 1.5), menu bars (browser to native menu translation, native menu model is different between Mac and Windows, AIR APIs insulate from menu accelerators), multiple windows (on Mac you need to manually switch which menu is active based on the window, versus on Windows it is attached to the window), transition between the two (link to Buzzword opening in browser versus desktop if you have it installed, do runtime detection if AIR application is installed, if Application is running can use local connection), opening hyper-links, remember me (skipped talking about this), URL display (command that copies URL of document into clipboard), going to sleep and waking up, modal dialogs (in browser best you can be is window modal in AIR you can block the entire application), language preference.
Shared Code
Two modes: Browser SWFs loaded by AIR version, mostly SWCs linked in by two level application.
Went with loaded SWFs as browser version was already doing that, looser coupling meant faster builds, did require Ant to package it all together for development and production
In browser downloading latest version always happens. AIR application captures static version of modules. AIR does version checking at startup to see if it running the latest.
How much updating of an installed application will a user tolerate? Will things still work after the update? Old code running against new version of the server was already handled since people maybe using Buzzword in a browser during an upgrade, but its still an issue.
Abstract AIR APIs
Writing code like "if (isAIR) {} else {}" just won't work. Easy to forget its shared code. Errors when code is loaded and trying to run.
Common approach is to create an interface with two implementations. PlatformBroker with AIRPlatformBroker and FlexPlatformBroker as subclasses. As it for an interface and get that back. IPersistenceSecureToken is the interface with BrowserCookie (using ExternalInterface) and EncryptedLocalStorageCookie (using AIR facilities) implementations. Flex version is okay to live in AIR application, but not vice versa.
Singletons
Convenient but breaks when a single application is running with multiple windows on the desktop versus separate VM instance per window in browser. Solving the singleton issue for AIR required rewriting the browser version since the majority of the code was shared. Singleton was easier to get going but had issues when adding multiple window support.
Rich text support
Major problem for Buzzword. Needed to support copy and paste of rich text. Had to have hacks for browser support with hidden div. Very fragile. AIR has it's own issues since you only get raw HTML, not formatted, normalized, or parsed for validity. Ran it through HTMLLoader.
Other issues
Relaunching (browser errors just reload the page, no real way to do it in AIR, but can hack it with relaunch via air.swf but you have to be online), AIR update framework (much improved with AIR 1.5), Flex menus versus native menus from single model (created XML reader with factory methods), internationalization and localization (Buzzword currently has multiple versions, localized in SWF and loaded based on preference at runtime), Runtime CSS versus compiled CSS, idle tracking (rolled own for browser, AIR has API for idle tracking, used for autosaving and turning off server session).
99% of the code is shared between the browser and desktop applications.
Session is primarily serving XML, co-authoring shared batton is server based, does long polling (server holds client request until it has data to send to it).