A few months ago, when iOS app extensions was make possible with an Xcode beta, I began writing a new app in RubyMotion that included an iOS action extension that worked with the built-in Photos app. The tools were unstable at that point and app extensions frequently crashed or were not easy to attached to for debugging. Combined with the need to test on the device, I had to resort to logging extensively from the extension while debugging.

I had previously built a mini-console in my own apps when I wanted to display logging in-app. But in this case where the app extension isn’t stable enough, I decided to log from the test device to my development laptop. One of the simplest way I started with was to run the SimpleHTTPServer that comes with Python distributions on my laptop:

python -m SimpleHTTPServer 8000

and write a logging function like this:

void log(NSString* aString) {
    aString = [aString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];
    NSString* urlString = [NSString stringWithFormat:@"http://my-laptop-ip:8000/log/%@", aString];
    NSURL* url = [NSURL URLWithString:urlString];
    NSURLRequest* req = [NSURLRequest requestWithURL:url];
    [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil];
}

and log plenty of these:

log("reached here 1");

I tried a few variations of these ad hoc setups and weren’t satisfied. I wanted a simple tool that can be fired up with a command or a click and continue to work hassle-free. I ended up building a utility called mLogger.

It’s not unlike using SimpleHTTPServer. Double-click on the app to launch it. You then log to it by making a GET or POST request to the URL http://127.0.0.1:8080/log/. The in-app help file provides a copy-and-paste-able function that you can use to do this in various languages, e.g. for Objective C:

void mLog(NSString* aString);
void mLog(NSString* aString) {
    aString = [aString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];
    NSString* urlString = [NSString stringWithFormat:@"http://127.0.0.1:8080/log/%@", aString];
    NSURL* url = [NSURL URLWithString:urlString];
    NSURLRequest* req = [NSURLRequest requestWithURL:url];
    [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil];
}

The code samples in the Help automatically includes the correct port number and make synchronous calls. You are free to change this, but by design, mLogger is meant to be used during app development and the order that the log appears is important and I prefer the logs to appear immediately.

The app is free for now and I have a few ideas — including adding samples for more languages — on how to improve on the app, but please give it a try and let me know your feedback or suggestions. You can download mLogger here.