Friday, November 25, 2011

Command & Conquer, Distimo style

Just a quick post, reacting to a comment by Tijmen after tweeting about the cool Command & Conquer style competitor map by Distimo.

Data for the following map (click on it for a larger version) is from the last month. It uses colors to show which of the WP7 apps I designated as competitors for my Klout Tile app (which should be all of the Klout apps out there right now..) have the highest ranking within the Social category in that country:


Interesting, huh? Especially since the other newcomer (from France, and currently only biggest there) shows the most information from the Klout API at the moment. Really should push out v1.1 of my Klout Tile app soon: it shows more data, should be more stable and cuts back on the "review begging" that was a bit excessive in v1.0 (with a daily recurring reminder). At least my app is still the only one with a Live Tile for your score.

My goal: get the whole world blue. ;-)

Update: Since posting this, another Klout app started showing your score on a live tile. So the "blue earth" goal doesn't seem like it'll be happening soon, as I am currently busy on other WP7 apps (one of which actually has a fixed deadline).

Tuesday, November 8, 2011

The perfect way to ask for a WP7 App Review...?

Today I got a mention on Twitter I really liked about the way I implemented "review begging" in my latest Windows Phone 7 app. I do it using the following code:

using System;
using Microsoft.Phone.Scheduler;

/* ...part of AboutPage.asmx.cs... */

public static void ResetReviewReminder(KloutSettings settings)
{
  const string name = "ReviewReminder";
  Action removeReminder = () => {
    if (ScheduledActionService.Find(name) != null)
      ScheduledActionService.Remove(name);
  };
#if DEBUG
  removeReminder();
  settings.UsedReviewButton = false;
#endif
  if (settings.UsedReviewButton)
  {
    removeReminder();
  }
  else
  {
    ScheduledAction reminder = ScheduledActionService.Find(name);
    if (reminder == null)
    {
      reminder = new Reminder(name)
      {
        Title = "How do you like me so far?",
        Content = "Would you mind using the about dialog " +
        "(tap here if Klout Tile is not running) " +
        "and writing a review?",
        NavigationUri = new Uri("/AboutPage.xaml", UriKind.Relative),
        RecurrenceType = RecurrenceInterval.Weekly,
        ExpirationTime = DateTime.Now.AddMonths(1),
      };
      if (System.Diagnostics.Debugger.IsAttached)
      {
        reminder.BeginTime = DateTime.Now.AddMinutes(5);
      }
      else
      {
        DateTime x = DateTime.Now.AddDays(7);
        reminder.BeginTime = new DateTime(x.Year, x.Month, x.Day, 12, 0, 0);
      }
      ScheduledActionService.Add(reminder);
    }
  }
}

What does this do?

That's an easy question to answer: if the application settings object (which is persisted in isolated storage) flags that the user has already used the review ApplicationBar button (in Klout Tile that's the star button in the About page), then any review reminder that is found is silently deleted. If however, the user has not used the review button in the About page yet and no existing reminder is found, it creates a new review reminder.

This reminder asks the user what she thinks about the app and also includes a NavigationUri that points to the About page. It is set to recur weekly for a maximum of about a month, starting three days from now. I think this is a reasonable "beg" period and frequency. (You can adjust as you see fit, of course.)

How do I use it?

Each time the Klout Tile app is started, I call AboutPage.ResetReviewReminder() once. This means that, if this is the first time the user starts the app, the user will be reminded three days later to please go add a review.

Apart from this I have the following code in my About page to handle the user clicking review button:

private void ReviewButton_Click(object sender, EventArgs e)
{
  var settings = KloutSettings.Load();
  settings.UsedReviewButton = true;
  settings.Save();
  ResetReviewReminder(settings);
  var review = new Microsoft.Phone.Tasks.MarketplaceReviewTask();
  review.Show();
}

This makes sure that when the user does click on the review button, any reminder that exists will be deleted and no more reminders will ever be (re)created in the future.

Some of the advantages

A lot of Windows Phone apps ask the user for a review. Some have buttons, which the user can easily choose/forget to (n)ever tap. Some wait a bit and ask the user for a review using a MessageBox with Ok/Cancel buttons, but this can be annoying for the user, as there is no "Not right now." option. Also, if the user installs your app, runs it onces and never uses it again, the code to show this message box will never get executed.

Using a system reminder like the code above does gives the following advantages:

  • We are able to show the user a review reminder, even if they only start the app once and never come back to it again. (Unless they uninstall it, of course.)
  • The review reminder is stored with other system reminders (like the ones from the Calendar), so they can be shown at any time, even if when the app is not running.
  • You do not need to use a background task to get this behavior, so even if the user disables your background task (which they can) the reminder will pop up.
  • If the reminder pops up at a time that is not convenient for the user, she can just snooze it, like any other reminder.
  • The user still has a way to just dismiss the reminder, but as it is a daily repeating one, it should pop up the next day (for a maximum of two weeks after first start).
  • When the reminder pops up while the app is not running, tapping the reminder opens the correct page inside the app directly to easily let the user initiate a review scenario. (For bonus points, the URI and About page could be changed so that when the user enters by tapping the reminder, the Microsoft.Phone.Tasks.MarketplaceReviewTask is executed directly, eliminating one further step!)
  • Finally, when the user uses the review button in the About page on their own, the reminder (whether already shown before or not) is silently deleted so the user is not bothered with our "review begging" ever again.

So I think using a Reminder to do you "review begging" might be the perfect solution. What do you think?