Category Archives: Mobile

Plotting Weekly Mobile Retention from the Localytics API using R and ggplot2

Part of building mobile web apps is understanding the myriad of mobile analytics and in part visualizing the data to shed light on trends that my otherwise be difficult to see in tabular data or even a colorful cohort table. I’ve been building a dashboard using R, RStudio, Shiny, and Shiny Dashboards aggregating data from MSSQL, Postgres, Google Analytics, and Localytics.

Within the Product section of the dashboard I’ve included a retention chart and found some great articles at R-Blogger like this one. The retention data comes from the Localytics API which I discussed previously though getting the data into the proper format took a few steps. Let’s start with the data, here’s an example of the REST response from Localytics looks like for a weekly retention cohort:

{
"results": [
{
"birth_week": "2014-09-08",
"users": 1,
"week": "2014-12-29"
},
{
"birth_week": "2014-09-29",
"users": 1640,
"week": "2014-12-29"
},
{
"birth_week": "2014-10-06",
"users": 2988,
"week": "2014-12-29"
},
{
"birth_week": "2014-10-13",
"users": 4747,
"week": "2014-12-29"
},
{
"birth_week": "2014-10-20",
"users": 2443,
"week": "2014-12-29"
},
…

Below is the main function to fetch the Localytics sample data and convert it into a data frame that’s suitable for plotting. Now, admittedly I’m not an R expert so there may well be better ways to slice this JSON response but this is a fairly straight forward approach. Essentially, this fetches the data, converts it from JSON to an R object, extracts the weeks, preallocates a matrix and then iterates over the data filling the matrix to build a data frame.

retentionDF <- function() {
  # Example data from: http://docs.localytics.com/dev/query-api.html#query-api-example-users-by-week-and-birth_week
  localyticsExampleJSON <- getURL('https://gist.githubusercontent.com/strefethen/180efcc1ecda6a02b1351418e95d0a29/raw/1ad93c22488e48b5e62b017dc5428765c5c3ba0f/localyticsexampledata.json')
  cohort <- fromJSON(localyticsExampleJSON)
  weeks <- unique(cohort$results$week)
  numweeks <- length(weeks)
  # Take the JSON response and convert it to a retention matrix (all numeric for easy conversion to a dataframe) like so:
  # Weekly.Cohort Users Week.1
  # 1    2014-12-29  7187   4558
  # 2    2015-01-05  5066     NA
  i <- 1
  # Create a matrix big enough to hold all of the data
  m <- matrix(nrow=numweeks, ncol=numweeks + 1)
  for (week in weeks) {
    # Get data for all weeks of this cohort
    d <- cohort$results[cohort$results$birth_week==week,][,2]
    lencohort <- length(d)
    for (n in 1:lencohort) {
      # Skip the first column using "+ 1" below which will be Weekly.Cohort (date)
      m[i,n + 1] <- d[n]
    }
    i <- i + 1
  }
  # Convert matrix to a dataframe
  df <- as.data.frame(m)
  # Set values of the first column to the cohort dates
  df$V1 <- weeks
  # Set the column names accordingly
  colnames(df) <- c("Weekly.Cohort", "Users", paste0("Week.", rep(1:(numweeks-1))))
  return(df)
}

To make things easy I put together a gist and if you’re using R you can runGist it yourself. It requires several other packages so be sure to check the sources in case you’re missing any.
Fair warning the Localytics API demo has very limited data so the chart, let’s just say simplistic however given many weeks worth of data it will fill out nicely (see example below).

> library(shiny)
> runGist("180efcc1ecda6a02b1351418e95d0a29")
Localytics Retention Plot Example
Retention Chart

ReactNativeJNI: Check failed: *m_isDestroyed JSCExecutor::destroy() must be called before its destructor

Short post to get this indexed as we didn’t find it elsewhere on the web.
While working to ship a new release of the Find&Save Android app we ran into a crash on launch which only occurred in our release build. The crash was in JSCExecutor.cpp which is part of React Native and left very few hints as to what was wrong with no call stack, Crashlytics logs etc. The only error we had was:
ReactNativeJNI: Check failed: *m_isDestroyed JSCExecutor::destroy() must be called before its destructor
Continue reading ReactNativeJNI: Check failed: *m_isDestroyed JSCExecutor::destroy() must be called before its destructor

Upgrading an iOS project from Xcode 6 to 7

At work I’m in the midst of upgrading Find&Save to Xcode 7 and in this post I thought I would capture the issues I ran into while migrating our app to the latest build tools. I decided to keep my Xcode 6 install by renaming it “Xcode 6” and installing Xcode 7 along side it and all that worked pretty seamlessly (though keep reading because the AppStore updates will bite you). Once installed I opened our project workspace and hit Project | Build and thus began the journey of our migration.
Continue reading Upgrading an iOS project from Xcode 6 to 7

Platform for Retailers Targeted Local Deals and Notifications

In November ’14 the Wanderful Media team launched a new feature within our Find&Save mobile apps called Cash Dash, a geographically targeted offer platform giving retailers the opportunity to reach consumers at key locations while out shopping. Using location aware features on iOS and Android the platform is able to suggest offers while users are out-and-about shopping. Leveraging our data on hundreds of retailers and hundreds of thousands of retailer locations as well as shopping malls all across the U.S. the platform provides retailers a rich ability to reach consumers at or near their stores with customized messaging and unique offers to help draw them in.
Continue reading Platform for Retailers Targeted Local Deals and Notifications

Error launching Google Chrome for React Native Debugging

Logged under “want to remember this for later” dept.:
Thanks to this thread for the tip.
I’ve ran into this error while trying to enable debugging via Chrome using React Native v0.4.3:

/Users/strefethen/github/iPhoneGeo/Pods/React/packager/launchChromeDevTools.applescript:686:689: script error: Expected class name but found property. (-2741)

Continue reading Error launching Google Chrome for React Native Debugging

Please make iOS lock screen camera access optional via Settings

My request to Apple on the camera icon on the iOS Lock Screen:

The camera icon on the iOS lock screen is to a child like a Fart Gun from Despicable Me 2 which is to say they can’t stop using it.
Please, make it an option.
If you have young children you can likely relate, if not you should really see the movie it’s quite funny.
But seriously. Can we get an option here?
I’d prefer not to repeatedly have dozens of blurry, pictures of the carpet, couch, floor, ceiling, siblings, goofy faces, all variety of inanimate objects and alas things which shall remain nameless streaming to all my other iDevices let alone getting shared on the big screen via Apple TV.
Seriously, an option. Please.

Shopping on the iPad with Find&Save's latest update

Wanderful has just released an updated version (v1.0.3) of our iPad Discovery Shopping App Find&Save for iPad on the App Store on iTunes.
Now for the bits interesting to the iOS dev crowd regarding the approval process.
Submitted Nov. 20, 2013
Reached review status 6 hours later on Nov. 11, 2013
Reached Process Status on Nov. 24, 2013 9:37pm
Available for download on Nov. 24, 2013 10:48pm
Means we got a 5 day turnaround time which is not bad headed into the Holiday week.
iPad Screenshot 1

Wanderful's Find&Save iOS Applications

My team at Wanderful Media has built two iOS applications for our Find&Save Discovery Shopping experience. Our iPad app is being featured in the AppStore and our iPhone just became available for dowload:
Find&Save iPad application         Find&Save iPhone App
If you don’t want to mess with an app install or are on an Android phone check out our latest Find&Save geo-local Mobile Web implementation.
Now that I have my blog moved I’m looking to post more about how we’re building a discovery shopping experience for over 400 of the nations newspapers which looks a little something like this:
Find&Save market coverage map