How you approach it will depend on how your app already handles internal navigation.
If you have a formal navigation object and are using deep linking (for example see the common/model/vo/NavigationVO in the original code for the Sea of Arrows site:
http://seaofarrows.com/srcview) you might already have a natural mechanism in place that just needs to be reworked a little.
In fact, I have Google Analytics on the site already, and have been thinking of adding internal tracking to it. Since the site uses deeplinking, There is only one URL and all the playlists and tracks are different html anchors. So as you go from track to track (automatically or by clicking), Google isn't notified, since its not another page load. So for this project, I will probably extend the existing navigation mechanism to make a call to Google's API with the info in the NavigationVO.
If you're using the StateMachine utility, it might be something that is triggered from the StateMachine.CHANGED notification, so that you can see people moving from state to state within the app. Another natural hook, but entirely tied to the implementation.
If you have no overall state management and are just wanting a generic hook into the user's interaction with the view, you could write an AbstractMediator class that extends Mediator and is the superclass for all other Mediators in your app. It would override onRegister to fetch a local reference to a TrackingProxy which exposes a track method. It would also add a protected track method that is then inherited by your Mediators.
In AbstractMediator:
protected var trackingProxy:TrackingProxy;
override public function onRegister():void
{
trackingProxy = facade.retrieveProxy(TrackingProxy.NAME);
}
protected function track(action:String):void
{
trackingProxy.track(action);
}
So then, in any Mediator
private function onSaveUpdatedProfile(event:Event):void
{
this.track(TrackingConstants.UPDATED_USER_PROFILE); // track the action
profileProxy.saveUpdatedProfile(profilePanel.profile); // do the actual work
}
Or, if you are mainly interested in tracking the flow of notifications within the system could always have your concrete Facade override the sendNotification method, causing a direct call to the trackingProxy.track method.
It would try to retrieve the TrackingProxy and if not null, call its tracking method. This is simple, but any notifications that are sent before the TrackingProxy is registered (i.e. STARTUP) just aren't tracked.
In ApplicationFacade:
override public function sendNotification( notificationName:String, body:Object=null, type:String=null ):void {
var trackingProxy:TrackingProxy = this.retrieveProxy(TrackingProxy.NAME);
if (trackingProxy != null) trackingProxy.track(notificationName);
super(notificationName,body,type);
}
-=Cliff>