00:00:15.759
Okay, good morning, good late morning to everybody. Thanks for coming! My name is Ray Hightower, and I'm here to talk to you about building iOS apps with RubyMotion. Before we do anything, what a wonderful place to have a conference! We're in Hawaii, in Honolulu. Let's give a hand to the organizers for putting this together. Lunch yesterday was great, and lunch today is going to be awesome as well. Thank you for that; I know you put a lot of work into what we're doing here.
00:00:27.039
I'm going to talk to you about building iOS apps with RubyMotion. That's me, and I'll throw that slide up at the end. Bottom line is I run a user group called Chicago Ruby and a software company called Wisdom Group. We build Rails and iOS apps. Thank you for having me here! Here's our agenda for today: we're going to go through what, why, how, and then have a Q&A. Specifically, we will cover what RubyMotion is, why we care about it, how to do something productive with it, and then we'll have some questions and answers.
00:01:03.719
I think we'll spend more time on the why and how than on the other parts today because that's where the meat of the talk is going to be — where we'll be able to answer some questions for you. So, what is RubyMotion? RubyMotion lets you, as a Ruby developer, write iOS apps. The apps that you're writing with RubyMotion are compiled into LLVM bytecode. These are compiled apps; they're not interpreted. In order to run RubyMotion, you need to have a Mac.
00:01:30.560
Someone asked me earlier if I can do RubyMotion without a Mac. You actually need a Mac running OS X and Xcode. You buy RubyMotion for $200 at rubymotion.com. You also need an editor — I use Vim, but you can use TextMate, Sublime, Emacs, or any other editor you prefer.
00:01:42.720
Now, why RubyMotion? Why not just write apps in Objective-C on Xcode? Why bother doing it in Ruby? Well, there are a couple of reasons why you might consider doing that. If you need an MVP right now and you know Ruby, then RubyMotion is probably the way for you to go. Let me talk about MVPs for a second. MVP stands for Minimum Viable Product, as defined by Steve Blank in his book 'The Four Steps to the Epiphany.' I hear many people attacking an MVP by trying to throw feature after feature into it before getting it out the door.
00:02:09.280
The main idea behind the MVP is that you want something small with the minimum number of features necessary for your clients to consider purchasing it. You put that in front of your clients and determine if they're willing to buy it. It's not an opportunity to cram a bunch of features into something and get it out there. You want to have a product that is both minimum and viable at the same time so you can determine if they want to buy the product. If you already know Ruby and you're building an MVP on iOS, RubyMotion is a great way to go.
00:02:33.800
Another reason to learn RubyMotion is if you want to learn Ruby better. I discovered a side effect that I did not predict: as I dove further into RubyMotion, I began to learn Ruby better. I understand more about mixins, inheritance, and modules than I ever did before. Before I came to Ruby, I predominantly came to Ruby from Rails. How many people here came to Ruby from Rails? The rest of you were probably pure Ruby beforehand? Well, to me, coming to Ruby from Rails meant that a lot of the things happening in the background felt like magic.
00:03:10.760
If you dive into Ruby via RubyMotion, you'll understand why a lot of these things are happening. Ruby is truly a very beautiful and effective language. But why not RubyMotion? There are some good reasons not to use it. If you already know Objective-C, then you probably don't need it and might not want to go that route. I did meet a guy who is an Objective-C developer wanting to learn Ruby so that he can build backend APIs for his Objective-C apps, and he sees RubyMotion as a gateway to Ruby, just as some may see RubyMotion as a gateway to Objective-C.
00:03:40.319
So the bridge can be a two-way street. Another reason you might hesitate to use RubyMotion is if you're concerned about what Apple is going to do with Ruby in the future. What if Apple intentionally or unintentionally breaks RubyMotion? We don't know what's going to happen there. Worst-case scenario, though, you'll know a lot more about Ruby and object-oriented design and programming. In that case, it's really not a losing proposition.
00:04:01.480
Now let's jump into how this all works. You've heard me talk enough. I’m going to show you a demo of creating a RubyMotion app. RubyMotion is handled at the command line. Can the people in the back see that all right, or do I need to zoom in a bit? Should I zoom in? Okay, here we go. We’ll start with 'motion create Hello.' For example, when you create a Hello app, a bunch of files get created. It almost looks like you're doing something with Rails.
00:04:51.039
I'm going to go into another directory for a Hello app that I created earlier. If you run the tree command, you’ll see the files that were created. There's a Rakefile; those of us who use Ruby are quite familiar with Rake. Rake is RubyMake. The app directory is where we define our app delegate. The app delegate is the entry point for the application. Now let's go ahead and run it; to run your RubyMotion application, you just run rake. It looks in the Rakefile, and here we go: 'Hello, oh, Magic Ruby!'
00:05:18.639
I better fix that! What you can do is hold down your Command key and mouse over the object right here. You’ll notice that right here at the command prompt, this changes as you hover over an object. Mouse over it and click it; you can grab that object by typing 'self.' See that self.text says 'Hello, Magic Ruby?' We don’t want it to say that; instead, let’s change it to 'Aloha' because we’re at Aloha Ruby. How about we add two exclamation points? There it is! So while the app is running live, you can actually change the attributes of the app live right there in the middle of running the app. Let’s get back to the slides.
00:05:56.640
Okay, so that’s how it works. I just showed you this; you never know when you’re doing something live if it’s going to fail or what have you. So, we want to ensure we have everything in the slides, too. Rake compiles and here’s the directory structure. The name of the app is 'Hello Ruby,' and here’s the structure using the Unix tree command. You can see our Rakefile from which we specify things like the app name. The resources directory is where you drop in your images or your audio files, should you have any.
00:06:24.560
It’s also where you would drop in your Interface Builder files. Yes, for those coming to RubyMotion from Objective-C, if you want to know if you can use Interface Builder with RubyMotion, yes, you can, and I’ll show you that later in this presentation. The spec directory is where you put your specs, which look just like RSpec. RubyMotion uses an RSpec clone called MacBacon. You put your specs — your automated tests — in this spec directory, and they all end with an underscore spec.
00:07:02.880
The main spec would, of course, be one of those tests. The app delegate.rb is the entry point for the application. Let's take a closer look at that. Now, what I did with these slides is we have code at the bottom, and I’m highlighting a line of code with a red rectangle. If you can’t see that, the line I'm focusing on is at the top. So, app delegate is the entry point for the application; this is what iOS looks for when it starts running your app.
00:07:30.400
Here’s where you're defining the actual entry point with the application didFinishLaunchingWithOptions method. What a long method name! This certainly does not look like a Ruby method; it looks more like an Objective-C method, and it is. In RubyMotion, some methods will look more like Objective-C methods. There’s a gem called BubbleWrap that wraps a lot of these Objective-C methods and makes them look more Ruby-like. I'll show that in the demonstration as well.
00:08:03.840
Here we go: didFinishLaunchingWithOptions. Here’s where we define the window. Essentially, we are telling it to create a window — alloc, which is kind of like new. You would allocate in C; in Objective-C, you use alloc. We’re telling it to take up the whole screen. 'Occupy bounds' means to take up the whole screen. We’re assigning a root view controller, which in this case we’re calling 'HomeController.' We're making it key and visible; key means this window will receive user input, and visible means we’ll make it visible.
00:08:29.919
Here’s where we're coloring the background. We can change all of that! The HomeController is an instance of something called UIViewController. Objective-C and RubyMotion both use the Model-View-Controller paradigm. A view controller is what we in Rails would consider a controller. There are models, there are views, and there are view controllers.
00:09:00.840
What we would consider a controller in Rails is a view controller. In RubyMotion, 'UIView' shows what it's inheriting from. It’s an instance of UIView. 'ViewDidLoad' is executed when the view is loaded. We're creating a label now. The way labels are done in RubyMotion is that '15, 100' are the x and y coordinates. Your origin (0,0) is in your upper left corner, x goes from left to right along the top, and y goes from top to bottom along the edge.
00:09:36.440
What about user experience? I have to tell you a quick story. Within Wisdom Group, I’m fortunate to work with people who are much stronger with Rails and design than I am. One of them is our chief designer. From time to time, I’ll give him mockups of what I think something should look like for a client we’re working on a website or an app for. I’ll give him these and he’ll come back and make them very functional because he’s a user experience professional.
00:10:13.320
I was looking over his shoulder while he was working on some wireframes for a client, and I noticed he has a directory on his machine called 'Ray playing designer,' which was a clear mockery of my design skills — kind of funny. I don’t play designer; I just create some mockups and pass them to a designer. But if you’re going to do user experience, there are two things you need.
00:10:36.480
First, you need a designer who really understands design, and that designer needs to work with Apple’s Human Interface Guidelines (HIG). You’ll hear people in the Apple world refer to the HIG — they’re guidelines that Apple has developed to help us create more effective designs and apps. Here’s UI Kit, which is a set of classes. I’m not going to ask you to read all of this. We’re only going to focus on six of the UI Kit classes: we have views, view controllers, windows, labels, and table views. We’ll use these as we go through our next demonstration.
00:11:21.440
How many of you are familiar with FizzBuzz? Maybe you’ve done this in a technical interview. FizzBuzz is when the interviewer asks you to write a code block that counts integers from one to 100 or up to a thousand, however high you want to go. When you hit an integer that's a multiple of three, print 'Fizz.' If it's a multiple of five, print 'Buzz.' A multiple of fifteen would print 'FizzBuzz.' For our next demonstration, we will look at a FizzBuzz app.
00:11:55.440
Let me close out the simulator and show you what it looks like. Back to the simulator, and it’s starting up. This is a FizzBuzz app, very simple. We have a label, we have an increment button, and a decrement button. When I increment, and when I go to nine, I should get 'Fizz.' Ten should be 'Buzz,' and what should I get at fifteen? I should get 'FizzBuzz.' There’s an increment button and a decrement button.
00:12:37.440
I also have a reset button. While debugging the reset button, I thought, 'Oh, wouldn’t it be neat if the reset button did something cool, like change the background?' That’s another reason why you definitely want to work with a designer — because that is pretty ridiculous and ugly! But anyway, that’s increment, decrement, and reset, which resets the counter all together.
00:13:18.360
If we take a look at this and close the simulator again, let's go back to our command line. Actually, I have that open in Vim here. Here’s the view controller. FizzBuzzViewController is what I called it. When we load the view, we’re telling it to pull in a file called FBI that we created using Interface Builder. Let me show you Interface Builder.
00:14:10.240
Interface Builder is a GUI for creating GUIs. It's part of Xcode, and if you've done anything with drag-and-drop GUI, you can use Interface Builder. Essentially, what I did was create the interface using Interface Builder. You assign each element a tag number. I assigned '1, 2, 3, 4' to the label and buttons, as you can see in the display. You take the Interface Builder file, a .xib file, and drop it into the resources directory.
00:14:57.120
By the way, in the resources, you’ll see that we also have the icon for this app. The FBI.xib is the Interface Builder file; it's actually XML, if you open it up you can take a look at it. The compiled Interface Builder file is .nib. There's other images you can store here as well. This is called FBI, and here’s the line of code in the loadView method where we want to use this Interface Builder file.
00:15:36.920
In the FizzBuzz demonstration, I also use that to demonstrate TDD. As I mentioned before, your specs for TDD go in the spec directory. Let me show you that live because it’s one thing to show you in the slides, but I’ll show you what it actually looks like. Let's look at that in Vim; in the lower pane, we actually have these specs. This is FizzBuzzViewControllerSpec.rb, and if you look at this, it looks just like RSpec.
00:16:06.720
If you want to run this, just use rake spec, and it will go through and run the specs. You can use Guard with this as well, so if you want to go back and forth – red, green, refactor – you can do that using Guard. Guard is cool because it watches your files, and anytime a file changes, it runs your test for you.
00:16:46.760
Now, I'm going to create a failing test just so you can see it. Guard is watching that. Let's go back to the console. It's running the test, and just like with RSpec, you perform your red-green cycle. Now that this test is red, we can fix it because I'm not 100% sure, but I think that eight is not equal to thirty-eight. So here we go; Guard is going through and running the test again.
00:17:19.920
One challenge I faced with RubyMotion is that when I'm running tests, it compiles everything before executing the test. I need to find a faster way to run tests since in the Ruby world we could run tests almost instantaneously. That's something I need to dig into further. You already saw the HomeController spec, where we failed.
00:18:05.360
There are some very cool gems you can use with RubyMotion. Just because you're compiling an app for iOS doesn't mean you can't use gems. The gems we utilize are specifically designed for iOS. One such gem is called 'Formotion,' which allows you to create forms that run in iOS. Let me show you a Formotion demo.
00:19:03.360
First, we’ll take a look at the form and see what it does. This is an iOS form, and from what iOS developers tell me, it's quite time-consuming to create a form like this. However, using the Formotion gem in RubyMotion makes it look almost like CSS. This is it — we’re specifying the title of the different fields, and as I scroll down, these are the titles of the fields along with the switch button.
00:19:48.640
Let’s go back to the simulator. Imagine you’re using this iOS app you’ve just put out. You've got a new subscriber named Ray Hightower, who is very security-conscious, so his password is 'password' — because no one would ever think of that! He logs in. Note: normally, you wouldn’t store passwords in clear text. This is just for demonstration purposes to show that it can collect data.
00:20:38.080
Alright, this is Formotion. To use it, you go into your Rakefile and specify that you're requiring the Formotion gem. This is straightforward and simple, almost like CSS. We just showed you that BubbleWrap gem; I mentioned it earlier.
00:21:20.960
The creator of BubbleWrap, Matt Imonti, is here at the conference, so if you want to talk to him, just go up and say hi. Thanks for creating BubbleWrap! It’s a gem that helps RubyMotion code look more Ruby-like. Here’s an example — this is a chunk of code in Objective-C, and here’s what it looks like in RubyMotion. If you want to delve into more details about what’s happening behind the scenes, check out U Clay Alsup's blog.
00:22:07.440
In fact, he's now contributing a lot to BubbleWrap and Formotion, so he’s putting a lot of effort into the RubyMotion community. Is there a good reason to use RubyMotion instead of Objective-C? I’m not sure that’s the case. Some people say they want to use RubyMotion because they’ll do less typing, but the fact is, we’re all using an IDE with code completion anyway — so is less typing really a good reason?
00:22:54.480
I don't think so! A good reason to consider RubyMotion is if you have a background in Ruby and want to build iOS apps. When using BubbleWrap, you have to go into the Rakefile of your app and require BubbleWrap, as shown here. Here’s an example that comes from NS Screencast. Ben Sherman created a screencast that highlights BubbleWrap, showing how it enhances RubyMotion code.
00:23:37.680
Let me show you an application written using BubbleWrap. It looks more like what you would expect if you’re following the Human Interface Guidelines. Ben has created an app that goes out to his website and pulls up what screencasts are coming up.
00:24:40.880
This is what it looks like in iOS. Here’s his API client. I’ll include this in the slides as well. In the Rakefile, you need to specify that you’re using BubbleWrap and BubbleWrap HTTP so that you can leverage its capabilities to make HTTP requests.
00:25:04.960
One of my favorite Ruby tools is RVM. Some people use RBV or other tools, but I started with RVM and am very comfortable with it. I understand you can also use RBV with RubyMotion. I like it because I often perform destructive testing when learning something new, and when you do such testing, it’s always good to know you can wipe everything out and start fresh.
00:25:50.000
Cupertino is a gem that helps you handle provisioning profiles from the command line. How many people have dealt with provisioning profiles in iOS? How many of you enjoy it? I don’t enjoy it at all! If you gem install Cupertino, then you can manage your provisioning profiles from the command line, and in this case, I'm taking a look at the iOS profiles I have on my local machine. The App IDs are not actual; I changed those for privacy, but that gives you an idea of what Cupertino can do.
00:26:36.360
Auto Layout is a new feature in Xcode that allows you to specify your layouts for your iOS devices in a relative manner. They behave similarly to frameworks like Twitter Bootstrap. Auto Layout works with RubyMotion, too. ARC, or Automatic Reference Counting, is another feature of Xcode, meaning we no longer need to manage memory when writing apps in Objective-C. RubyMotion uses something very similar to ARC, which eliminates the need for explicit memory management.
00:27:17.840
Finally, we reach the end of the talk. Does it make sense to use RubyMotion or Objective-C if you're writing iOS apps? I met a gentleman a few weeks ago who asked a thought-provoking question: if you were a VC and spending your own money on a developer to write an iOS app, would you hire a developer to use RubyMotion or Objective-C? I think if you already have Ruby skills or your team has Ruby skills, I would recommend RubyMotion. You can get the MVP up and running quickly.
00:28:03.000
If that MVP takes off, and you're generating revenue, then you will have the resources to pay for more developers—be they RubyMotion or Objective-C developers. If you have an Objective-C background, consider RubyMotion because, as discussed before, it could be a gateway drug—a bridge to Ruby, since you’ll likely want to use backend web technologies.
00:28:36.840
Here are a bunch of resources you might want to check out. I know the type is small for those of you in the room, but I’ve made these slides available on my website so you can refer to the additional resources. Thank you very much!
00:29:08.840
The question is: how do you perform segues between multiple view controllers in RubyMotion? In Objective-C, your view controllers are part of an array, so when you specify which one you’re using, you’re specifying its index in that array. I believe that’s how it's done in RubyMotion as well.
00:29:41.600
The question is: have I encountered anything in RubyMotion that I wish I could do, but couldn't? I haven't yet. Most of the apps we're working on aren't really groundbreaking in terms of pushing the boundaries of RubyMotion. I think the apps that will really stretch RubyMotion, or Objective-C, will be games — where performance matters. Business apps may not seem that exciting, but often they generate the most revenue.
00:30:20.360
No, the question is whether there are any key features of iOS that are not accessible through RubyMotion. You can access the accelerometer, the camera, and all of the device’s features. What happens with RubyMotion is you’re writing Ruby code that compiles for iOS. Unlike some other tools—without naming them—you’re producing the bytecode that runs on the iOS device.
00:30:45.400
Yes, the question was whether RubyMotion translates to Objective-C. RubyMotion compiles to LLVM bytecode; the LLVM stands for Low-Level Virtual Machine. It includes the virtual machines, compiler, and debugger. The value proposition of LLVM is portability; you write a compiler that targets multiple platforms. In the case of RubyMotion, the targets are x86 (for simulator) and ARM (the chip in iOS devices).
00:31:10.240
Would we want to continue using RubyMotion for a full-blown solution? I think it can work well for full solutions too, but I come from a Ruby background. If we were more Objective-C oriented, we might see things differently. That said, there's always the risk that RubyMotion could break if Apple decides to change something.
00:31:48.480
The short answer is I believe you can certainly do it, but some may choose to stick with Objective-C for final products. And yes, it has its benefits for MVPs and could be used for everything depending on the team.
00:32:29.200
The question is whether anyone is extending RubyMotion for writing macOS apps. The creator of RubyMotion, Lauren Cinnati, is also behind MacRuby, so it’s already there to some extent. I'm not sure if Lauren has learned anything from RubyMotion that he will incorporate back into MacRuby, or if it becomes a two-way street.
00:33:14.160
If you want to learn more about RubyMotion, a good place to start is with the MacRuby book written by Eddy, who is running around this conference.
00:33:44.360
Can you use storyboards? Yes, you can use Interface Builder. Interface Builder works with RubyMotion, but I haven’t tried storyboards personally. I understand that storyboards use Interface Builder, and if Interface Builder applies to RubyMotion, it can also use storyboards.
00:34:10.160
The question is whether you can use packages written for CocoaPods in RubyMotion. Yes, you can leverage that. You would use the resources directory. I haven’t dug deep into that yet, but I've seen some examples and blog articles where they’ve successfully done that. If you have an Objective-C library or even better a C library, you can integrate that with RubyMotion.
00:34:53.960
Any more questions? Let’s go play with RubyMotion! Thank you very much for having me.