Digital Magpie

Ooh, ooh, look - shiny things!

Leap Into the Future!

Leap Motion

This looks like a fascinating piece of technology provided it works as advertised. Check out the video on their, it looks pretty slick.

The company behind it make some pretty bold claims about the technology:

Just about the size of a flash drive, the Leap can distinguish your individual fingers and track your movements down to a 1/100th of a millimeter. … Setup is just as intuitive. Plug the LEAP into a USB port. Load the Leap Motion software. Do a quick wave to calibrate. That’s it.

Of course if you were to use it as a main input device I expect that you’d get tired pretty quickly, but for short sprints of use in specialist applications it looks neat.

And I’d love to see it paired with one the new sets of VR displays that are hitting the market right now.

Think About That

Good design. From eBay. Think about that.

Beautiful turn of phrase from John Gruber over at Daring Fireball.

Posted as part of my new effort to improve my writing.

RubyMotion and Interface Builder…

…sitting in a tree, K-I-S-S-I-N-G…

So, all of the cool kids have been talking about Laurent Sansonetti’s next project: RubyMotion, a port of MacRuby targeted at iOS. On the whole I’m pretty impressed with what you can already do with it. One of the issues that people having been mentioning though, is that you lose the ability to use Interface Builder with it, but this isn’t actually true!

Here I’m going to show you how to work with Interface Builder, I’ll base the project off the one used in the Pragmatic Studio screencast (the icon and background images come from there as well, by the way).

Update: the images don’t dome from there any more! The images used in the screencast are from iStockPhoto, so I’ve replaced the background image with a different one. Needless to say this doesn;t affect any of the code.

All of the code for this project can be found on GitHub.

Setting up a Project

Start off as normal: motion create MagicBallDemo. In the project folder create a new subfolder called interfaces, this is where all of the .xib files will be saved.

Next create a model class called MagicBall and a view controller called MagicViewController which extends UIViewController, also create a file to store some small helper methods called helpers.rb. Don’t worry about the contents of these files for now, I’ll come back to them, but you should have the following:

$ ls app
app_delegate.rb          magic_ball.rb
helpers.rb               magic_view_controller.rb
$ cat app/magic_view_controller.rb
class MagicViewController < UIViewController

The next thing to do is create the UI using interface builder.

Creating the User Interface

Open Xcode and hit ⌘-N to create a new file, select the Empty template and save the file into the folder you just created. Now add a View Controller from the object library and set the custom class to MagicViewController; you can’t edit this field directly but you can paste into it, so select the class name from app/magic_view_controller.rb.

The next step is to add the view to it’s controller, normally this would just mean dragging a UIImageView on top of the controller but that won’t work here. There is a problem with interface builder in that you can’t add subviews to UIImageViews, which is a pain in the ass. A simple workaround is described in this Stack Overflow question, and that’s what we’ll do here. So, add a UIView to the view controller and set it’s custom class to be UIImageView (which should be available in the pick-list). You can’t set the image here, that will need to be done in code.

Finally add the label and configure it as desired. Save your changes and close XCode.

You can compile this into a .nib using ibtool, this script will compile all of the interfaces in your project (just one in this case):

for i in interfaces/*.xib
  echo "compiling `basename $i`..."
  ibtool --compile resources/`basename -s .xib $i`.nib $i

Update: as of RubyMotion 1.3 this happens automatically, no need to compile your nibs by hand and more!

Connecting up the Code

The first thing we need to do is make sure our app delegate loads the interface from the nib that we’ve created, and we set our @window ivar from the loaded nib.

def application(application, didFinishLaunchingWithOptions:options)
  @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
  @window.rootViewController = NSBundle.mainBundle.loadNibNamed('MagicBallView', owner:self, options:nil).first
  @window.rootViewController.wantsFullScreenLayout = true

The nib loading process will create an instance of our view controllor for us, but we need to wire up a few connections add add some behaviour, here’s a simplified version of the code:

  def viewDidLoad
    @magicBall =
    @label = self.view.subviews.first

    view.image = UIImage.imageNamed('background.png')
    view.whenTapped do
        animations:lambda {
          @label.alpha = 0
          @label.transform = createTransform
        completion:lambda { |finished|
          @label.text = @magicBall.answer
          @label.transform = CGAffineTransformIdentity

I know that there is only 1 subview so it’s easy to grab a reference to the label and store it in an ivar, a more realisic example could select the label based on a tag.

As mentioned above, I need to explicitly set the image and this happens here as well.

Finally, set up the gesture recognizer. This is one place that Ruby shines, it’s trivial for us to add helper methods like this, have a look in app/helpers.rb for the code that enabled this.

Wrapping Up

It’s a good idea to add resources/*.nib to the .gitignore file as compiled resources don;t need to be committed to Git. I also add doc/app then I can use rocco to generate some documentation.

Take a look at the full project on GitHub and let me know what you think!

Update: clarified the wording around adding the UIImageView.

Apple Security Cock-Up

This doesn’t look good.

Apple’s approach to security in general is a bit worrying: one the one hand they seem to have the right approach to securing the OS with App Store entitlements (although these aren’t without issues) and Gatekeeper, but their timeliness in shipping security fixes leaves a lot to be desired. Note from the article that this flaw was pointed out to them 3 months ago!

Category Counts in Octopress

Here’s a quick shell script to get the number of posts in each category for an Octopress blog, just cat your source/_posts folder through the following one-liner:

sed -n '/^---/,/^---/p' |\
grep '^- ' |\
sort |\
uniq -s 2 -c - |\
sort -n

Here’s what each line does:

  1. extracts the Yaml front-matter from each file;
  2. extracts each top-level list entry, this assumes that the only top-level list is the category list, which is the default for Octopress posts;
  3. sort the lines;
  4. collapse identical lines, prepending a count of the number of lines collapsed; and finally
  5. sort numerically.

Maybe this will be useful to somebody out there…

Update: I’ve written a version that’s integrated with rake as well.