Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

Using Google Analytics in Titanium Mobile

This is an Answer not a Question! :)

I've wanted to use Google Analytics to track pages in my app, however implementing the Google Analytics SDK via a Titanium module was a pain!

So, I decided to replicate the SDK code direct into Titanium.

This also means I don't have to maintain and build a separate module, which is nice.

All the code is on github: https://github.com/rogchap/Titanium-Google-Analytics

It is currently setup for iOS, however it would be easy to change to Android by changing the user-agent string.

I hope some one out there finds this useful!?

Leave a comment if you use it.

— asked November 10th 2010 by Roger Chapman
  • mobile
16 Comments
  • Sweet! I actually started to track my apps by having a hidden webview which I redirected to a blank webpage on my website and used to standard js google analytics library. This is much better though! I will try it out… The country code thing actually solves another problem of mine so thanks for that aswell :)

    — commented November 10th 2010 by Magnus Ottosson
  • It would be great if we could add support for custom variables aswell… it should not be that hard to implement.

    — commented November 10th 2010 by Magnus Ottosson
  • The benefit of this solution over a hidden webview is that even if the application does not have a network connection events are stored in the database until a network connection is available. This will happen a lot on the iPad where most people only have the WiFi version. Your idea is clever though; would have never have thought to do that! :)

    I need to get tracking events finished off first, then I'll look into adding custom variables.

    — commented November 10th 2010 by Roger Chapman
  • Can you please post a sample user agent accepted by GA for Android?

    — commented November 17th 2010 by Mario Capocaccia
  • So awesome, thank you! Works like a charm.

    — commented February 11th 2011 by Philip Kaplan
  • SWEET ARCHITECTURE!
    I like that you used event listeners to make your analytic functions available from anywhere in the app.
    It is indeed the correct way to to this,
    Thanks a lot

    — commented April 18th 2011 by Luc Martin
  • I've to run sample in the provided link but it always give no results only the labels in the tabs! am i missing anything?

    — commented June 8th 2011 by Bandar Aljohani
  • I had tried every thing in this application but i think this code is of dam no use ….has any body got solution how to implement google analytics or can any body share code with me….

    — commented June 15th 2011 by Moiz Chhatriwala
  • not very useful,should provide some more example of Google Analytics implementation.

    — commented June 15th 2011 by Ashutosh Chaturvedi
  • Hi Roger,

    Firs of all, I'd like to thank you for this useful script.It works like a magic :) .

    Did you manage implementing the custom variables? we are having difficulties modifying your script to extend the functionalities of setCustomVariableAtIndex of Google Analytics. Thanks in advanced.

    — commented December 14th 2011 by Ryan Dizon
  • Hi Roger,
    We are using this in our app.Once doubt that I had in mind was Why are we using event listeners if we can declare a global function in App that in turn calls the methods trackPageview and trackEvent?

    — commented February 27th 2012 by Mukund Samant
  • Is the trackEvent function completed? It would be great to use this. Thanks

    — commented April 13th 2012 by Somme Sakounthong
  • Lovely work!!! :D

    — commented May 30th 2012 by George Marmaridis
  • Hi roger,

    I think the path for the httpclient isn't correct. You use Titanium.Platform.countrycode, but this gives 'undefined'. Have you any solution for this?

    — commented August 22nd 2012 by Jordy van der Heijden
  • Never mind! It works Fantastic! Thanks a lot!

    — commented August 22nd 2012 by Jordy van der Heijden
  • Hi roger tk you very much 4 the code. I try to find a solution to integrate the custum variables in your code but i dont succed. Is anyone or roger have done something before ? Tk u very much

    — commented November 3rd 2012 by gautier pialat

20 Answers

  • @Scott Miller

    In your app.js call the analytics.js
    set the params and the events.

    Then on each window/page/view you want to track, have an onFocus event set that calls his track page view function. The param it takes is the "page" that shows in your google analytics results.

    win1.addEventListener('focus', function(e){
        Titanium.App.Analytics.trackPageview('/win1');
    });
    

    So, if I have a window whose views show a RSS feed, i might call

    win1.addEventListener('focus', function(e){
        Titanium.App.Analytics.trackPageview('/rss');
    });
    

    After the user clicks one of the items in the list and views a window with the article in it, maybe call something like

    win1.addEventListener('focus', function(e){
        Titanium.App.Analytics.trackPageview('/win1/'+urlencode(rsstitle);
    });
    
    — answered August 6th 2011 by Stephen Feather
    permalink
    5 Comments
    • Hate the lack of an edit button:

      win1.addEventListener('focus', function(e){
          Titanium.App.Analytics.trackPageview('/rss/'+urlencode(rsstitle);
      });
      

      — commented August 6th 2011 by Stephen Feather
    • My Google Analytics account status does not change, it is as "Tracking not installed", this is normal?

      I did some tests but as the delay Analytics to show the report do not know if implemented correctly.

      — commented September 3rd 2011 by Micael Estrazulas
    • Couple of things:

      1. Our tracking is tied to a website/domain. So it might be represented off a subdirectory (/app) off the main site or as a sub domain. In either case, analytics has already been setup and verified by GA.

      2. As for the 'delay', you can select the current day even though it might not be highlighted or selected by default, and it will show you just shy of real time.

      — commented September 5th 2011 by Stephen Feather
    • As an update, using Roger's latest code, you can modify it to load as a commonJS module. This is required for use with TiShadow.

      In the analytics.js file change

      var Analytics = AnalyticsBase.extend({

      to

      exports.Analytics = AnalyticsBase.extend({

      You call in app.js now looks like this:

      // Configure our Google Analytics
      var Analytics = require('/lib/analytics').Analytics;
      var analytics = new Analytics(config.ganalytics);
      

      — commented May 30th 2012 by Stephen Feather
    • Here is a gist for easier download: https://gist.github.com/2859407

      — commented June 2nd 2012 by Stephen Feather
  • Roger, I'm getting an error (downloading the source and compiling without changes):

    "[ERROR] Script Error = Can't find variable: Class at analytics.js (line 78).

    [ERROR] Script Error = Result of expression 'Analytics' [undefined] is not a constructor. at app.js (line 6)."

    (I'm compiling with version 1.4.1.1 of the SDK, but that doesn't especially matter in this instance.)

    — answered November 10th 2010 by John Welch
    permalink
    2 Comments
    • My bad… "Class" at line 78 should be "AnalyticsBase". I'll update the source now.

      — commented November 10th 2010 by Roger Chapman
    • Thanks!… I was trying to figure it out but couldn't.

      — commented November 10th 2010 by John Welch
  • works like a charme. thanks Roger!

    — answered May 3rd 2011 by Sebastian Klaus
    permalink
    0 Comments
  • Hi,

    I'm getting the following warning message when calling 'Titanium.App.Analytics.trackPageview(my_url)' from other pages.

    [WARN] (null)->(null) [0]->not specified is being made in a thread not owned by <KrollContext: 0xc006200>
    

    Any ideas?

    — answered March 9th 2012 by John Paul Green
    permalink
    0 Comments
  • hi ?i used the analytics.js,but it does not work!

    1 Copy analytics.js to Resources
    2 Paste next code into app.js

    var googleAnalyTics_id = 'UA-37684090-1';
    
    /* analytics */  
    Titanium.include('analytics.js');  
    var analytics = new Analytics(googleAnalyTics_id);  
    analytics.reset();
    Titanium.App.addEventListener('analytics_trackPageview', function(e){  
        analytics.trackPageview('/iPad' + e.pageUrl);
    });  
    Titanium.App.addEventListener('analytics_trackEvent', function(e){  
        analytics.trackEvent(e.category, e.action, e.label, e.value);  
    });  
    Titanium.App.Analytics = {  
        trackPageview:function(pageUrl){  
            Titanium.App.fireEvent('analytics_trackPageview', {pageUrl:pageUrl});  
        },  
        trackEvent:function(category, action, label, value){  
            Titanium.App.fireEvent('analytics_trackEvent', {category:category, action:action, label:label, value:value});  
        }  
    }  
    analytics.start(10);  
    /* analytics end */  
    Titanium.App.addEventListener('close', function(e){
        analytics.stop();
    });
    

    3 Paste next code when a win open

    Titanium.App.Analytics.trackPageview('win-name');
    

    It is no error! but when i go to https://www.google.com/analytics/web/ ,there is no data.

    The url Analytics'client opened is
    http://www.google-analytics.com/utm.gif?utmwv=4.4mi&utmn=644932630&utmcs=UTF-8&utmsr=320x480&utmsc=24-bit&utmul=en-undefined&utmac=UA-37684090-1&utmt=event&utme=5(ButtonClicklogin)(4)&utmcc=utma=737325.-317559966.1358739378.1358739378.1358739378.1

    Was there something i missed?

    — answered January 21st 2013 by guo jianhua
    permalink
    6 Comments
    • most often, TIME.

      By default, today isn't shown immediately by default.
      You need to select today.

      — commented January 21st 2013 by Stephen Feather
    • i tested it four days ago?

      — commented January 21st 2013 by guo jianhua
    • i began to test it four days ago! And Continued two days! there was no data

      — commented January 21st 2013 by guo jianhua
    • Well, I know that its working for us.
      We converted Roger's code to commonJS format: https://gist.github.com/2859407

      — commented January 21st 2013 by Stephen Feather
    • HI, I replace UA-37684090-1 to an error accountID 'abcd'

      Titanium.include('analytics.js');  
      
      var analytics = new Analytics('abcd');
      
      this._httpClient.onerror = function(e) {
                          Ti.API.error('send google-analytics:'+e.error);
                      };
      
                      this._httpClient.onload = function(e) {
                          Ti.API.info('onload:'+e);
                      };
                      this._httpClient.open('GET', 'http://www.google-analytics.com' + path, false);
                      this._httpClient.setRequestHeader('User-Agent', this._USER_AGENT);
                      this._httpClient.send();
                      Ti.API.info(this._USER_AGENT);
                      eventsToDelete.push(event.event_id);
      

      there is also no error! is that normal ?

      — commented January 21st 2013 by guo jianhua
    • I am experiencing the same problem. I've been trying to get it working for 5 days and nothing appears on my Analytics Dashboard. I don't know what else to do!
      Should it work on simulators?
      Thanks!

      — commented February 26th 2013 by Douglas Alves
  • Hi Roger or anyone else that may have used this to publish an app.

    Does the app store allow the location data fed back to Google?

    It is probably not GPS but rather your ISP providing a location, but just wanted to know if it has caused anyone any issues?

    — answered September 30th 2013 by anx patel
    permalink
    0 Comments
  • BTW - you might want to check out Appsee for your mobile analytics, its way nicer than GA and gives you things like user video recordings and heat maps… They have an appcelerator plugin (www.appsee.com)

    — answered February 26th 2014 by Tal Sinay
    permalink
    0 Comments
  • Nice work Roger!

    — answered November 10th 2010 by John Welch
    permalink
    0 Comments
  • Any reason why data wouldn't show up in the GA interface?

    I'm seeing the info messages within titanium saying that a page has been reached…

    — answered November 11th 2010 by John Welch
    permalink
    3 Comments
    • The info messages are showing that the page views have been logged in the database. It will then dispatch to GA every 10 seconds (or what every time you set) if there is a network connection. The best way to see if the tracking code is being sent to Google is by using a web proxy like Charles Web Proxy. You should then see the GA __utm.gif being requested.
      Also GA interface is 24 hours behind, you just may need to wait (real pain when you are trying to debug!)

      — commented November 11th 2010 by Roger Chapman
    • The GA interface typically runs 3-4 hours behind… You just have to change the date that you are looking at. I'll use that web proxy to test. Thanks for the tip. Looks like I had the wrong tracking in the code.

      — commented November 11th 2010 by John Welch
    • Looks like it works. I'm seeing results in GA.

      — commented November 11th 2010 by John Welch
  • I'm not sure if GA doesn't completely report the data until hours later, but it appears the iPhone OS version is not available within GA. Any idea why? These user-agent strings look good:

    Here is the user-agent from your js file:
    User-Agent: GoogleAnalytics/1.0 (iPhone Simulator; U; CPU iPhone OS 4.1 like Mac OS X; en-undefined)

    Here is the user-agent from iPhone simulator on a website:
    User-Agent: Mozilla/5.0 (iPhone Simulator; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7

    — answered November 11th 2010 by John Welch
    permalink
    3 Comments
    • The en-undefined is occurring since I didn't edit the Titanium SDK I believe… But I didn't think this would be needed…

      — commented November 11th 2010 by John Welch
    • The user agent is a special user agent that is used by the official GA SDK. if you don't want to change the Titanium SDK, you could manually set the countryCode to US.

      — commented November 11th 2010 by Roger Chapman
    • I was mostly referring to the fact the OS version wasn't being displayed.

      — commented November 11th 2010 by John Welch
  • Thanks for sharing, I will be implementing this when my app nears completion

    — answered November 16th 2010 by Mark Beech
    permalink
    0 Comments
  • Roger,

    Have you checked the module against 1.5? I think some runtime errors are occurring.

    — answered December 14th 2010 by John Welch
    permalink
    1 Comment
    • I'm using 1.5.1 and it seems to work fine.

      — commented January 6th 2011 by Roger Chapman
  • Hello guys, i am new to titanium. Somebody could give a step by step on how to implement this module into an app?

    — answered December 22nd 2010 by pablo espinosa
    permalink
    1 Comment
    • You you have a look at the github repo link there is a sample application you can follow.

      — commented January 6th 2011 by Roger Chapman
  • I am getting an error when I include analytics.js

    "Result of expression 'Titanium.Database' [undefined] is not an object at analytics.js (line 107)

    Any clue?

    — answered February 14th 2011 by pablo espinosa
    permalink
    1 Comment
    • You'll need to delete everything in the build folder and try to launch it again.

      — commented April 3rd 2011 by Daniel Tome
  • Roger in your readme file you say "In the Titanium SDK add the following… iphone/Classes/PlatformModule.m

    -(NSString)countryCode
    {
    NSLocale
    locale = [NSLocale currentLocale];
    return [locale objectForKey:NSLocaleCountryCode];
    }

    iphone/Classes/PlatformModule.h

    @property(readonly,nonatomic) NSString *countryCode;
    "

    what is the file name of the file to update? There is a lot of files in the sdk folder.

    — answered April 18th 2011 by Luc Martin
    permalink
    1 Comment
    • iphone/Classes/PlatformModule.m ;)

      — commented May 3rd 2011 by Sebastian Klaus
  • i was trying to run the project file provided, unfortunately it cant be run in emulator (no "launch" button). anyone could help me?

    — answered June 27th 2011 by kaki lang
    permalink
    0 Comments
  • I've just started testing this out and it seems promising! However, from the example in app.js, do I need to put the code at the top on every page I want to track? Just curious as to how you all did it. I'm thinking maybe just using an include?

    — answered July 29th 2011 by Scott Millar
    permalink
    0 Comments
  • roger plz i want the explanation to this code…….can u do that for me

    — answered October 4th 2011 by nagina nagina
    permalink
    4 Comments
    • i have tried this code but i couldn't get my events tracked………plz help me out of this

      — commented October 4th 2011 by nagina nagina
    • I have the same issue.
      Followings are what I did to integrate GA into my titanium project.

      1. I'd created home site (http://sites.goole.com/testsite)
      2. activated google analytics account to get web property ID.
      3. put analytics.js into the folder where app.js is
      4. then copy and paste next code into app.js :

      > Titanium.include('analytics.js');
      > var analytics = new Analytics('UA-xxxxx-y'); // replaced to my web property id
      > Titanium.App.addEventListener('analytics_trackPageview', function(e){
      analytics.trackPageview('/iPad' + e.pageUrl);
      }); // replaced '/iPad' to '/folderName' that I want.

      > Titanium.App.addEventListener('analytics_trackEvent', function(e){
      analytics.trackEvent(e.category, e.action, e.label, e.value);
      });

      > Titanium.App.Analytics = {
      trackPageview:function(pageUrl){
      Titanium.App.fireEvent('analytics_trackPageview', {pageUrl:pageUrl});
      },
      trackEvent:function(category, action, label, value){
      > Titanium.App.fireEvent('analytics_trackEvent', {category:category, action:action, label:label, value:value});
      }
      }

      > analytics.start(10);

      > Titanium.App.addEventListener('close', function(e){
      analytics.stop();
      });

      1. added event to track at one of windows like :
        > winName.addEventListener('focus', function(e){
        Titanium.App.Analytics.trackPageview('/folderName');
        });

      google analytics pages still keeps saying to me 'Analytics is not installed yet'
      is there anything missing?
      some posts says roger chapman's code works great, but not to me yet :(
      show the the way please.

      — commented October 11th 2011 by jeeheon bak
    • hi …i am trying to implement google analytics in my app but i am getting this exception after analytics service started and nothing is getting displayed on the dashboard……… (Thread-20) [40439,67197] Error posting events: Connect to /107.21.236.169:443 timed out org.apache.http.conn.ConnectTimeoutException: Connect to /107.21.236.169:443 timed out at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121) at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:143) at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:653) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:627) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:616) at org.appcelerator.titanium.analytics.TiAnalyticsService$1.run(TiAnalyticsService.java:133) at java.lang.Thread.run(Thread.java:1096)

      — commented December 26th 2012 by raj kumar
    • Hi There,

      i have same issue. Please help

      Thanks,
      Saamy

      — commented April 19th 2013 by Saamy
  • I got it to work perfectly but I have one problem: when you're on a slow connection like edge or really slow 3g the app will stop functioning for a few seconds while uploading to google. Can you change the time limit or do anything else to make it work more smoothly?

    — answered January 2nd 2013 by Pontus Backlund
    permalink
    0 Comments
  • "I hope some one out there finds this useful!?"

    Ha Ha Ha!!!

    you sir are amazing! and i hope you will live for 1000 years!

    answer to your question: found it useful thanks :D

    — answered September 13th 2013 by anx patel
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.