Archive for March, 2009

Charles v3.4b1 featuring SSL improvements

Monday, March 30th, 2009

Charles v3.4 is in the works. I haven’t settled on a final feature list for this yet; my focus is intended to be UI improvements, but I couldn’t resist releasing some new SSL features. So this isn’t really a beta, but I’m calling it 3.4b1.

Charles now supports client-side SSL certificates, so you can authenticate with servers that require them. You must configure Charles to use your P12 file for each site that requires it using the Client SSL Certificates option in the Proxy menu. Charles will ask for your password when it needs it, and it doesn’t remember it beyond the session for your security. Please let me know how this works for you!

You can now list SSL sites that should not be proxied / decrypted by Charles. In the process I also renamed “Decrypt SSL” to “SSL Proxying” as it wasn’t the right terminology. So if you have software that accesses specific sites and doesn’t like Charles’s certificates you can add them here; by default it has PayPal and Kagi in there to ward off the emails I get about those sites having invalid certificates! For myself I’ve added *.getdropbox.com as it doesn’t like the SSL certificates it sees even with Charles’s CA certificate trusted by the system – that’s good security.

Finally, the SSL certificates that Charles generates for sites are now cached. This means when you say “permanently trust this certificate” in your browser, it will actually work!

Download the beta.

RomanNumeralFormat

Sunday, March 15th, 2009

Several years ago I wrote this RomanNumeralFormat class which extends java.text.NumberFormat but parses and formats Roman numerals. I just stumbled across it and thought it belonged here. This sort of thing should definitely be included in Java 7, then it will truly rule over Perl 6.

import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;

public class RomanNumeralFormat extends NumberFormat {

  private static char[] roman_alpha = new char[] { 'M', 'D', 'C',
    'L', 'X', 'V', 'I' };
  private static int[] roman_num = new int[] { 1000, 500, 100, 50,
    10, 5, 1 };

  public StringBuffer format(double number, StringBuffer toAppendTo,
    FieldPosition pos) {
    // Too lazy
    return null;
  }

  public StringBuffer format(long l, StringBuffer toAppendTo,
    FieldPosition pos) {
    StringBuffer buf = new StringBuffer(20);

    while (l > 0) {
      for (int i = 0; i < roman_num.length; i++) {
        if (l >= roman_num[i]) {
          buf.append(roman_alpha[i]);
          l -= roman_num[i];
          break;
        } else {
          int peek = i + 2 - (i % 2);
          if (peek < roman_num.length) {
            int j = roman_num[i] - roman_num[peek];
            if (l >= j && j > 0) {
              buf.append(roman_alpha[peek]);
              buf.append(roman_alpha[i]);
              l -= j;
              break;
            }
          }
        }
      }
    }

    return buf;
  }

  public Number parse(String source, ParsePosition parsePosition) {
    long l = 0;
    int max = 0;

    source = source.toUpperCase();

    for (int i = source.length() - 1; i >= 0; i--) {
      char c = source.charAt(i);
      boolean validChar = false;
      for (int j = 0; j < roman_alpha.length; j++) {
        if (roman_alpha[j] == c) {
          int k = roman_num[j];
          if (k >= max) {
            l += k;
            max = k;
          } else {
            l -= k;
          }
          validChar = true;
          break;
        }
      }
      if (!validChar) {
        parsePosition.setErrorIndex(i);
        return null;
      }
    }

    parsePosition.setIndex(source.length());
    return new Long(l);
  }
}

I was obviously pretty concerned about getting some large roman numerals through here – using a long rather than an int. Built to last.

iTunes App Store promotion

Monday, March 2nd, 2009

Half a year on from the launch of the iTunes App Store, one of the biggest difficulties for developers is getting noticed amongst the 10,000+ apps. We’ve talked about traditional marketing; we’re trying new forms of marketing (twitter, social networking), but mostly agree that promotion within the App Store itself is the golden ticket. I’ve had this idea rolling around for some time; today I’m appeasing my Things todo list by blogging about it.

Promotion within the App Store is available in two areas; the masses purchase apps creating the Top 10 / 25 / 50 / 100 lists, and Apple chooses apps to feature in the New and What’s Hot lists (and some others). Promotion within the App Store is at the whim of Apple and the masses.

The problems with the Top lists has been the topic of much discussion; most recently its penchant for passing wind has been fouling the air. The Top lists create a feedback loop where sales drive sales; it’s great when an app is in the loop, but increasingly developers are finding development unsustainable if it’s not.

My assumption is that there are many apps of quality and utility that deserve to hit the big time, and that without promotion their growth is stunted. Apple can’t promote every app at once, but maybe the promotion can work better.

I am thinking of a system where potentially successful apps are identified in a way that is independent of sales volume and recommendations. Apps are then randomly promoted with a weighting towards those that are more potentially successful. A feedback loop analyses the effect of promotion on sales and increases or decreases promotion to maximise revenue. In this case “success” is defined as sales, that is making money for Apple and for the developers.

How to identify potentially successful apps? If Apple tracks which apps people view and and which apps they buy, then an app with a strong view-buy ratio likely matches consumer needs and has reasonable quality (bonus points for including data on how long the app stays installed; if the user removes it immediately with a 1 star review that counts against). Identifying apps in this way is independent of popularity; in fact popularity will worsen the view-buy ratio as it attracts more views, so this (and a minimum number of views on the other end of the scale) may need to be taken into account. The potential to tailor featured apps to individual users is obvious, but I think one-step-at-a-time is more likely!

Potentially successful apps are then randomly featured on the App Store with a weighting towards apps with a high view-buy ratio. Being featured will increase the number of views, so if an app is successful it should also increase the sales. The feedback loop continually measures the view-buy ratio and adjusts the promotion weighting. Variance in the weighting algorithm would enhance the approach by stepping back slightly from maximising revenue (ie. for Apple) and sharing it amongst a larger group of apps (ie. developers), and allowing new entrants; like mutation in a genetic algorithm.

I think this approach may solve the problem of apps which should have more sales but don’t have the promotion required. It should mean that promoted apps are the apps that are more likely to sell, which means that overall App Store revenue should increase. Good for Apple, good for developers. Remember that this doesn’t replace the existing Top list mechanism, it sits alongside it. I’m not sure what other problems and exploits it creates! It isn’t a complete picture. I hope it’s an interesting one.