Marin's internet home

https://mar.in

RubyMotion - in the wild

There’s been lots of posts regarding RubyMotion. Most of them are written by Ruby programmers, that aren’t using Objective C on a daily basis.

This post is written by a full-time Objective C developer, taking over RubyMotion.

I’ve bought RubyMotion the second day it came out, and have watched the project evolving for these few months.
I’m one of creators/maintainers of the BubbleWrap iOS wrapper, and have written a couple of small apps using RubyMotion.

The upsides

The reasons I’ve bought RubyMotion

  • integrated TDD/BDD framework
  • integrated CocoaPods
  • the ability to write specs without worying is it an int or NSUInteger
  • command line tools
  • editor independency
  • the community
  • it has a REPL :)
  • wanted to support the project

The Xcode linker sucks so hard. Every time you add a more complex framework like Kiwi or something similar, there’s XCode linker yelling at you. Build fails. Y U NO WORK?

Writing tests in OCUnit is,…well, nobody writes them, that tells everything. It even complains if you’ve expected (int) 4 and got (NSUInteger) 4.

The Ruby community is a way nicer and bigger than the iOS one.

Support

I have to say that Laurent is super-fast with replying to all the user tickets. Usually you get the answer within a day, and the bug gets fixed/shipped in the next build.

The downsides

Exceptions - Lots of time there’s an exception without any stack trace. I’ve found this kind of anoying, especially when there’s a runtime bug that you can’t solve quickly. This makes debugging pretty hard.

Autocompletions - The ObjC APIs are really

[verboseWithLongMethod:names andNamed:parameter andOftenWith:secondParameter]

Its kind of nice when your IDE knows how to autocomplete the stuff based on the context.
That means, if you’re talking to a Person object, you should see only methods that belong to that object (and it’s superclasses).
Hopefully this problem will get solved one day by various wrappers and libraries.

Provisioning / App Store - I hope this will be more trivial later on. It’s kind of a pain to deal with all the profiles (especially if you have like 20 of them, and 3 dev accounts).
It would be great if this ends up as the Xcode integration.

Meta Programming and ‘Require’ - There is a way to hack in the define_method, and similar features, but the class_eval won’t work.
‘Require’ doesn’t work inside your classes. Because of these 2 impossibilities, you can’t do something like require 'active_record', what would be awesome :)

Nil - This is one of the biggest deal-breakers for me. Probably it will be for most of the Objective C developers. I’ve found that ObjectiveC, friendly nil, made me really spoiled.

The Objective-c way

[nil count]       // => 0
[nil length]      // => 0
[nil name]        // => nil
[nil doSomething] // => nothing happens

The Ruby Motion way

nil.count   # => NoMethodError
nil.length  # => NoMethodError
nil.name    # => NoMethodError

The fact is that ObjectiveC APIs are mostly tolerant to the nil input, so if you do a chained method call, like:

[[JSON parse:json][@"businesses"] each:^(Burrito *burritoDict) {
	[burritos addObject:[self createBurrito:burritoDict]];
}

and it’s enough to check the final product (burritos Array) if it’s empty or not.

However, in the Ruby way:

JSON.parse(json)[:businesses].each do |burrito_hash|
  @burritos << create_burrito(burrito_hash)
end

JSON.parse(nil) # Exception
nil[:businesses] # NoMethodError []
nil[:businesses].each # NoMethodError .each

Also, in the controller that’s expecting those burritos, we need more nil checks, and so on.

I hope you’ve got the point. The most of Ruby devs would laugh at this, but for me it was a pain in the butt.

Summary

For an hardcore - ObjectiveC developer, RubyMotion still takes me more time to build an app from scratch to the AppStore.
Hopefully this will change at some point, as the project and the community are growing constantly.