----
Within a recent MvvmCross project, we used www.flurry.com for our analytics.
Basically what we did was log all important events from the ViewModel using an IAnalytics interface, and then each platform supplied an implementation of IAnalytics like:
WP7:
public class FlurryAnalytics : IAnalytics
{
public const string ApiKeyValue = "--- your key ---";
public void StartSession()
{
FlurryWP7SDK.Api.StartSession(ApiKeyValue);
}
public void LogEvent(string eventName)
{
FlurryWP7SDK.Api.LogEvent(eventName);
}
}
Touch (used with bindings like https://github.com/kevinmcmahon/monotouch-libs/blob/master/FlurryAnalytics/flurry.cs):
public class FlurryAnalytics : IAnalytics
{
public const string ApiKeyValue = "37SHD8L8VATPBS88AMHU";
public void StartSession()
{
FlurryAPI.StartSession (ApiKeyValue);
}
public void LogEvent(string eventName)
{
FlurryAPI.LogEvent(eventName);
}
}
Android (a bit more complicated - it needs a hook from every start/stop of an activity):
public class FlurryAnalytics : IAnalytics, IAndroidActivityTracker
{
public const string ApiKeyValue = "--- your key ---";
private readonly IntPtr _flurryClass;
private readonly IntPtr _flurryOnStartSession;
private readonly IntPtr _flurryOnEndSession;
private readonly IntPtr _flurryLogEvent;
public FlurryAnalytics()
{
_flurryClass = JNIEnv.FindClass("com/flurry/android/FlurryAgent");
_flurryOnStartSession = JNIEnv.GetStaticMethodID(_flurryClass, "onStartSession",
"(Landroid/content/Context;Ljava/lang/String;)V");
_flurryOnEndSession = JNIEnv.GetStaticMethodID(_flurryClass, "onEndSession", "(Landroid/content/Context;)V");
_flurryLogEvent = JNIEnv.GetStaticMethodID(_flurryClass, "logEvent", "(Ljava/lang/String;)V");
}
public void StartSession()
{
// not used in Android - Android relies on Activity tracking instead
}
public void LogEvent(string eventName)
{
ExceptionSafe(() => JNIEnv.CallStaticVoidMethod(_flurryClass, _flurryLogEvent, new JValue(new Java.Lang.String(eventName))));
}
private static void ExceptionSafe(Action action)
{
try
{
action();
}
catch (ThreadAbortException)
{
throw;
}
catch (Exception exception)
{
UITrace.Trace("Exception seen in calling Flurry through JNI " + exception.ToLongString());
}
}
public void OnStartActivity(Activity activity)
{
ExceptionSafe(() => JNIEnv.CallStaticVoidMethod(_flurryClass, _flurryOnStartSession, new JValue(activity), new JValue(new Java.Lang.String(ApiKeyValue))));
}
public void OnStopActivity(Activity activity)
{
ExceptionSafe(() => JNIEnv.CallStaticVoidMethod(_flurryClass, _flurryOnEndSession, new JValue(activity)));
}
}
Each of these platforms simply injected their implementation into IoC during setup - .i.e:
Among the messages recorded were the creation of every ViewModel - which gave us an easy to see picture of which pages were being used in our app. We did this through a BaseViewModel implementation which logged its type name on creation - simple, quick and clean:this.RegisterServiceInstance
(new FlurryAnalytics());
public abstract class BaseViewModel
: MvxViewModel
, IMvxServiceConsumer
{
#region Protected API
protected BaseViewModel()
{
Analytics.LogEvent("ViewModelCreate:" + GetType().Name);
}
protected IAnalytics Analytics
{
get { return this.GetService(); }
}
}
Hi. I was wondering if you could provide guidelines to add these functions?
ReplyDelete* logEvent (String eventId, Map parameters)
* logEvent (String eventId, boolean timed)
* endTimedEvent (String eventId)
Probably best to ask that question on forums.xamarin.com - just link back to the code here (or cut and paste) and someone who knows the native binding will help
ReplyDeleteTrust me I did. They helped you build this thing?
ReplyDeleteCould you provide your Android project source with JARs? thanks.
ReplyDeleteI think you have to get the jars from flurry - and the above code is all I have that's not in client specific code. Sorry
ReplyDeleteI updated it to cover the following functions (Android JNI):
ReplyDelete* setContinueSessionMillis
* logEvent(string eventName, bool timed)
* logEvent(string eventName, Map params)
* logEvent(string eventName, Map params, bool timed)
* endTimedEvent(string eventName)
* setUserId(string userId)
* setAge(int age)
* setGender(byte gender)
* setReportLocation(bool enabled)
* setLogEnabled(bool enabled)
* onError(string errorId, string message, string errorClass)
Let me know if you want to update your source. Also, I am assuming the events are going out; how long do they take before they show up on Flurry's dashboard? And besides adding the "jar" as putting it to "JavaLibrary", is there anything else to do? Thanks.
yes please! Please post the code as a http://gist.github.com and I'll make sure it gets publicised as best I can :)
ReplyDeleteGenerally it used to take between 3 and 12 hours for the data to show up in the flurry website.
https://gist.github.com/4069294
ReplyDeletethanks!
Thanks "Unknown" - publicised here http://slodge.blogspot.co.uk/2012/11/updated-flurry-analytics-in-monodroid.html
Delete