iBeacon at the Arcade

A few years ago I got involved in pinball software development in a pretty big way. It’s faded over the past year, but it’s still one of my favorite cranial playgrounds for software ideas. I continue to be passively obsessed with contemplating new ways of writing pinball software (“Could you write good pinball software in Lua? What about Haskell? How would that look?”). Mercifully for my family they remain mental exercises.

There are two topics that tend to come up quite a bit in discussions about pinball technology, at least when I am involved. The first is that I should have a player profile on the pinball machine, like my iOS Game Center or Xbox Live account. This would allow for internet high score boards that go beyond initials, but also make it possible to change the open/closed nature of a pinball game. Suddenly my game could have persistent state (pinball RPG?). Stored power-ups for use in later games. Lots of really interesting possibilities here, both for home and location players.

Before I get to the second topic, there’s a problem to discuss. The problem with this player profile idea is that it’s hard for a player to sign into the game. Pinball machines do not have rich input devices. Usually it’s three buttons: flipper left, flipper right, and start. (“Was my password LLLRL-Start or LLLLRL-Start?”) For various reasons a touch screen is technologically hard or very awkward (it would get in the way of the flippers). RFID or mag stripe cards are an option but then you have to have some way of distributing the cards. I bet the Taco Mac bartender really wants to hand those out. (Jersey Jack tried something like this with ePlate. Something tells me it hasn’t taken off. Maybe it’s the part where I have to sign up for a credit card to participate.)

There’s a better option: quite a lot of us carry around very rich input devices in our pockets, of course, which brings us to the second topic: how can I connect my phone with a pinball machine? If your phone can communicate with the pinball machine then you suddenly have a very natural means of identifying yourself to the pinball machine. The trouble is that, until recently, doing this was also hard and awkward. The machine itself would need to be on wifi, maybe you’d have to join the same wifi network on your phone, or shoot a QR code to tell the app which game you’re standing next to… Like I said, awkward.

So what happened recently that changes this? Last summer Apple announced iBeacon as part of iOS 7. What’s fairly cool about it is that it isn’t just an iOS thing – Android phones support it too (it’s just Bluetooth Low Energy, BLE). iBeacon solves the problem of connecting your phone with the pinball machine by allowing the connection to take place over Bluetooth, without pairing. There’s proximity data and the devices can even exchange information.

The possibilities here are pretty interesting, even aside from the idea of signing in to your player profile. A pinball manufacturer could offer iOS and/or Android configuration utilities, making for a much richer management interface for owners and operators of these games. Technically you could even sidestep connecting the pinball machine to wifi at all, if you relied upon the player’s phone for relaying information up to a server. It would even allow co-located games to form a mesh network of sorts, for example for head-to-head play, although there are perhaps simpler ways of solving that problem.

iBeacon seems like a pretty natural fit for retail and vending machines. A lot of folks are excited about using it for payments, as an alternative to NFC. Imagine coining up a game using IAP on your phone. You could even take your credit balance with you when you get a great score. Free loyalty credits, social marketing possibilities (“Tweet this for five free credits” (yes, I hate myself a little for suggesting this)). Of course all of this can apply to video arcade games, jukeboxes and so forth.

As an aside, one of the great things about iBeacon is that it’s very accessible for experimentation. You can pick up beacons fairly cheaply (Estimote, Bleu), and you can also make your own device act as a beacon. The iOS APIs are pretty straightforward (Region Monitoring, CBPeripheralManager).

This is an interesting time for pinball. A number of new, smaller game makers have popped up, like Multimorphic and Dutch Pinball, just the kind of manufacturers that could be ready to try something like this. Here’s hoping.

Musings on Creating Immutable Collections Mutably

Sometimes we need to create an array whose length and members are not known at compile time. Oftentimes that looks something like this:

NSMutableArray *things = [NSMutableArray arrayWithCapacity:numThings];
for (int i = 0; i < numThings; i++)
{
    [things addObject: ... ];
}
// use 'things'...

If our collection is not to be changed later, and we’re feeling particularly pedantic, we might do something like this:

NSMutableArray *mutableThings = [NSMutableArray arrayWithCapacity:numThings];
for (int i = 0; i < numThings; i++)
{
    [mutableThings addObject: ... ];
}
NSArray *things = [mutableThings copy];
// use 'things'...

But mutableThings is still accessible. Best to tuck it away:

NSArray *things;
{
    NSMutableArray *mutableThings = [NSMutableArray arrayWithCapacity:numThings];
    for (int i = 0; i < numThings; i++)
    {
        [mutableThings addObject: ... ];
    }
    things = [mutableThings copy];
}
// use 'things'...

But that looks pretty unpleasant. How can we improve upon this?

One approach would be to use blocks in a simple fashion. The compiler’s inference of the return type can make the equivalent of the above a bit more graceful:

NSArray *things = ^{
    NSMutableArray *mutableThings = [NSMutableArray arrayWithCapacity:numThings];
    for (int i = 0; i < numThings; i++)
    {
        [mutableThings addObject: ... ];
    }
    return [mutableThings copy];
}();
// use 'things'...

I like this, but there’s a downside: we can’t use Step Over in the debugger to step through this code (we can still Step Into). You could also consider that an upside, depending on what you’re debugging.

We can take this a step further by creating a category on our favorite collections objects, and use it like this:

NSArray *things = [NSArray ap_arrayViaMutableArray:^(NSMutableArray *things){
    for (int i = 0; i < numThings; i++)
    {
        [things addObject: ... ];
    }
}];
// use 'things'...

A strong advantage here is that we’ve abstracted away all of the alloc, init and copy noise. Debugging may be a bit more cumbersome, since Step Into is going to step into the implementation of our category method before it gets to calling the block.

SwiftText 1.1.0

I’m pleased to announce that SwiftText 1.1.0 is now available! Here’s what’s new:

  • Retina support.
  • Font is customizable.
  • SwiftText may optionally be kept on top of all windows until it is dismissed.
  • Added “Append to SwiftText” Mac OS X service.
  • Sandboxed.
  • Improved status item behavior.

Another Octopress Blog

I made the transition from WordPress to Octopress. I’d been a WordPress user since sometime in 2003, when I started my 1128 blog. WordPress was incredible: the installation was remarkably painless and the features (admin interface, layouts, etc.) were top notch as well. Over the years WordPress has improved quite a bit, too. But WordPress has also grown somewhat notorious for performance issues (under heavy load, anyway), and there were occasional security problems as well.

Perhaps due to these challenges, static site generators like Octopress are becoming more popular. The advantage is that the code runs on your local machine and generates a bunch of HTML files. Then you upload (rsync, in my case) them. This makes your site faster – it doesn’t have to converse with a database server to get the posts – and a lot more secure. There’s no PHP script running on the server with bugs waiting to be compromised. The hosting account itself is still hackable, of course, but there’s only so much we can do about that.

So when my friend Robert emailed a couple months ago to let me know that my blog had some link spam in the footer (coded so that it didn’t when I visited the site), I decided it was time to say goodbye to WordPress. I blog rarely enough that it needs to be frictionless, and though it was interesting to track down where the spam was being injected, I doubted it would be as interesting in future occurrences. It was time to get serious about Octopress.

As an aside, I did spent some time trying out Hyde, because Python is higher on my list of preferred languages than Ruby (important if I ever wanted to tinker with the code) but Hyde is not (yet?) as much of an off-the-shelf blogging platform as Octopress is. Octopress won.

For the most part the switch was easy; I used Matt Gemmell’s post as a reference. Initially there were no comments, as it is A) fashionable these days and B) it’s a static site. However, this weekend I opted to setup Disqus, which is akin to off-shoring your comments.

I do miss WordPress to a certain degree. It was much easier to sign into the admin interface and compose a new post, write a little, and decide to save it as a draft (and forget about it). With Octopress it’s a more manual process.

  • rake new_post['Some Title']
  • Fire up TextMate 2 and open the .markdown file.
  • Write.
  • Don’t finish post for various reasons. Go to the Octopress docs to remind myself how to set a post as a draft (note to my future self: published: false).
  • rake preview / rake generate / rake deploy

The downside of this is that if you never finish a post (or decide not to post it) and never set it to be a draft, when you come around later and actually post something you could easily inadvertently post your not-intended-for-publication post. So some care is required. For now I’ve modified the Rakefile to include the published: false line in the new_post template.

You served well, WordPress, and you will be missed. My thanks to the many developers who made WordPress great.

Launch at Login Implementors Support Group

I’ve had a number of improvements in the pipeline for SwiftText 1.1.0 for quite some time, and finally submitted it to the Mac App Store tonight. One of the most difficult features to get right was Launch at Login. This was a feature that was in 1.0 and was fairly easy to implement at the time. However, in this brave new world of sandboxed apps, launch at login is a bit of a beast. If you’re thinking about adding it to your application, or perhaps you’re struggling to make it work, perhaps this post will help.

Sandboxed apps need to use a helper tool to do the actual launching for them. In short, the helper app is bundled under Contents/Library/LoginItems and its bundle identifier is passed to SMLoginItemSetEnabled(). delite studio has a very helpful post on this, but you’ll want to make sure to read Mike Cohen’s own post containing some key corrections. Your helper app will need to do some path acrobatics to concoct the path to your main application, which it launches with -[NSWorkspace launchApplication:], and then calls [NSApp terminate:nil].

If you follow the above, you should have a working launch at login feature. There was one more hurdle for me to overcome, however. My application passed the Validate step within Xcode, but when I uploaded the binary I was told my application had an “Invalid binary”:

Invalid Provisioning Profile Location - The provisioning profile for your Mac OS X app must be located in the Contents directory of the main app bundle. A provisioning profile is optional, but you cannot submit more than one.

What the iTunes Connect robot was trying to tell me was that my helper tool was, evidently, incorrectly signed. Using this Stack Overflow answer I was able to re-sign it in a Run Script build phase, which passed the robot’s muster. (One note about that answer: I found that copy-pasting the lines from the answer yielded a non-working script. By retyping the paths I was able to get it working. Bad characters in the mix, I presume.)

Why so much work to get such a simple feature working? The launch-at-login APIs were never developer-friendly: the old Launch Services method was a couple dozen lines, all told. Here we have less code, but many more obstacles to maneuver. Why the helper application, though? As far as I can tell the SMLoginItemSetEnabled() call (part of the Service Management Framwork) is not really intended for matters so trivial as launch at login. I suspect that it was simply the last man standing after the Launch Services method was knocked out by sandboxing. From a developer’s perspective this is a pretty unpleasant pattern. I see three possible explanations:

  • Apple didn’t have time to concoct a new sandbox-friendly API for this in time for 10.7/10.8.
  • Apple doesn’t see it as unpleasant, or not unpleasant enough.
  • My expectations are too high.

My money’s on the first. With the Service Management method, the user must use the application itself to toggle launch at login. Applications with this enabled don’t show up in the Users & Groups Login Items pane, nor do they show a checkbox in the ctrl-click menu on the dock. Not the best user experience. Perhaps there will be a better solution in 10.9. Now to write a bug in hopes that it will help that happen. Here’s what I’m thinking:

1
2
3
@interface NSApplication (LaunchAtLogin)
@property BOOL launchAtLogin;
@end

MTRandom: An Objective-C Random Number Generator

Most of the time when we need a random number, we use srandom() & random(), or perhaps arc4random(). In the old days we might have used srand() and rand(), until somebody told us that random() was better.

Sometimes we want a sequence of random numbers to be reproducible. Say we’re writing our own Minecraft and we want users to be able to share seeds for the landscapes they find. The above functions work fine for that, as long as we’re the only one using them. Unfortunately they’re not thread safe (see my test code to confirm). They manage a single state behind the scenes, so if we wanted to run, say, two landscape generation routines in parallel, we’d be out of luck.

That’s where MTRandom comes in. MTRandom is an Objective-C wrapper for Mersenne Twister, a pseudo-random number generator.

1
2
3
4
MTRandom *random = [[MTRandom alloc] initWithSeed:5];
uint32_t r = [random randomUInt32From:5 to:10];   // [5, 10]
double   s = [random randomDouble];               // [0.0, 1.0]
double   u = [random randomDoubleFrom:0 to:M_PI]; // [0, 3.14159...]

There are a few more examples in the README.markdown.

It also conforms to NSCoding and NSCopying, so you can archive it with game state, or make copies when searching a game tree. The repository includes a set of basic unit tests, and best of all it’s BSD licensed (even Mersenne Twister). It’s available on GitHub: github.com/preble/MTRandom.

Xcode Snippets

Xcode’s snippets feature is rather handy. It’s what drives many of the autocomplete templates. For instance, if you type init on a new line and hit return, Xcode will create a template for an -init method.

Until recently I haven’t bothered to create my own snippets, which can be done in three easy steps:

  • Selecting a block of text you wish to make a snippet.
  • Drag it onto the Code Snippet Library, which is part of the Utility Area (lower right hand side).
  • Customize by entering the Completion Shortcut, or wrapping tokens in <#token#> so that you can tab between them after the snippet has been inserted.

I do a fair amount of Quartz development, so today I created a a snippet which has already proven useful. I’ve set its completion shortcut to cgbitmapcontextcreate:

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(<#data#>, <#width#>, <#height#>,
                                         8, <#width#> * 4, colorSpace, 
                                         kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);

I’ve made a separate one just for color spaces, cgcolorspace, as for some reason the repetitiveness of creating and releasing RGB CGColorSpaceRefs has lost its luster.

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
<#code#>
CGColorSpaceRelease(colorSpace);

Thankfully you can stomp all over the symbol names that will be otherwise provided by autocomplete, so when I’m about to create yet another CGColorSpaceRef, perhaps forgetting my snippet, Xcode will show me the snippet as the first autocomplete option in addition to the usual bunch.

A pleasant side effect of this is that you can fix some of Xcode’s annoying autocompletes, due to how snippets take priority over other autocomplete suggestions. For instance, when I type NSStri in Xcode, the default autocompletion is NSStrikethroughStyleAttributeName. Probably not what I wanted. I can use snippets to fix this by creating an NSString snippet with the very same completion shortcut, and voila, autocomplete gives me just what I want when I next start typing NSString.

Briefly on Sparrow Et Al.

Beautifully designed 3rd party apps are part of what makes the Mac platform such a great platform. We can be fairly emotional about our beloved Mac ecosystem. So it’s natural to feel injured when we learn that one such app has suddenly become encased in ice. Matt Gemmell is right, however, when he says:

People try to dress their reaction up as a principled stance or a community cause, but that’s at best wrong-headed thinking, and at worst wilfully egocentric bullshit.

Don’t worry; he’s not going to sugar-coat it any more than that.

APLevelDB: An Objective-C Wrapper for LevelDB

TL;DR: I made an Objective-C wrapper for LevelDB, called APLevelDB.

I’ve been enjoying tinkering with Redis lately, which has left me wanting something similar for Mac and iOS projects. Tokyo Cabinet seems to be the big name in speedy key-value stores, but its LGPL license leaves much to be desired. I finally settled on LevelDB, a similar offering from Google with a much friendlier license (New BSD).

LevelDB’s C++ API is pretty reasonable, but since I don’t like naming all of my files .mm, and stylish Objective-C APIs are part of what make developing in Cocoa/iOS so much fun, I decided to write my own. I hope you’ll agree that it’s quite pleasant to use; it’s called APLevelDB. It has a few opinions, but leaves the big decisions to you. You can find usage examples in the readme.

A Raindrop for Acorn

CloudApp is one of my favorite tools for sharing images quickly, and I also use Acorn quite a bit for quick image editing tasks. I’ve been wanting a quick way to upload a snapshot of what I’ve got in Acorn using CloudApp, so tonight I wrote AcornRaindrop.

AcornRaindrop exports the active document in Acorn as a PNG and uploads it using CloudApp. It’s a Raindrop, which is a plugin for CloudApp. You can download it, or peruse the source on GitHub. It is made available under the MIT License.

Note that testing at this point has been ridiculously limited. It works for me; hopefully it will work for you too!

The implementation is rather simplistic: it uses osascript to instruct Acorn to export the active document, then passes the result along to CloudApp. My first attempt was using NSAppleScript, but for reasons I don’t fully understand it blocked for about 30 seconds while running the script, but only under CloudApp. Something to do with loading frameworks, perhaps? At any rate it runs quite quickly with osascript.

Happy CloudApp+Acorning!

v1.0.1, 1/18/2012: Gus Mueller was kind enough to contribute some changes demonstrating how to connect directly to Acorn using NSConnection, so the osascript call is now history. This allows AcornRaindrop to base the filename uploaded to CloudApp on the filename of the exported document.