 So, my name's Alex Rothenberg, I'm going to be talking about how not to let the Cocoa API crush your Ruby code and really what I think of it as is, you know, how to make Ruby and Cocoa play nice together. So just a little about me, you know, I work for McKinsey Digital Labs, a consulting company, you find me on Twitter, email, GitHub, all the usual places. But basically, I'm a Rubyist, you know, I came into this space from the Ruby side of the world. And I've been thinking a lot about what it is that I love about Ruby. And really, you know, I think it's in Ruby, we care not just about, you know, getting things to work, but about, you know, making our code clean, easy to deal with, easy to go back to months or years later and, you know, really just having clean code that we can understand and deal with. And so, you know, I follow that and I try to do that as I'm writing web applications. And I, you know, I think, you know, with Rails and with, you know, a lot of stuff in the Ruby community, it's fairly easy to do that in the web space. But then, of course, right a couple of years ago, the iPhone came out. And the iPhone was cool and the iPhone was sexy. And, you know, I really wanted to learn how to write iPhone apps. So I had this very silly idea, you know, iBraid. Just a bunch of strings that you could, you know, pull back and forth and weave something together. So, you know, I got Xcode, I got, you know, all sorts of guidelines for, you know, for how to build iOS apps. And, you know, I set out to build this. And I got something that, you know, sort of kind of mostly worked. But behind the scenes, you know, it was a big ball of mess. You know, it was a disaster back there. And, you know, really what it was was, you know, there were all these different things that I knew nothing about and was trying to learn all of them at once. You know, Objective-C, a new language, Cocoa, you know, massive API. And, of course, Xcode, you know, the IDE that, you know, just did not work with me the way my brain worked. So I was fighting it all the way. So basically I put that aside, went back to building web apps for a while. And then all of a sudden, you know, Laurent came along and Ruby Motion came out. And, you know, in the world suddenly, you know, it seemed possible again to go into this iOS space. So, right, we could use Ruby, use the editor I wanted, not the one Apple, you know, forced on me. And I still had to deal with Cocoa, but I figured I could do that, right? It was just one thing to get into, even though it has these crazy long method names that we all have to fight. So really, this is what I want to talk about today. You know, my journey of how to write, you know, Ruby and Cocoa together and how to, you know, get them to play nice together. And what I learned, you know, as I started, was, you know, my apps started to feel like Cocoa apps that happened to be written in Ruby, which was not really where I wanted to go and what I wanted to do, right? That was back to a big ball of mess. I wanted to get much more, where I was writing Ruby apps that happened to be using the Cocoa API. So the app I'm going to talk about today was, is really serving an address book app that we were building. We didn't make the built-in contact app, but, you know, it was a corporate address book, had our own database of people, and had some other functionality that we wanted to do custom. So, right, so the first thing, you know, I learned about Cocoa. It's just an MVC framework, right? In spite of all those extra letters Colin was adding yesterday, it's really just an MVC framework. So, right, we've all, you know, seen this, right? View controller, lays out views. And you can start, when you first start, right, this is very simple. You can read this, you can see what's going on. Just setting a screen with a white background. And again, right, you know, coming at it from the outside, right, this is what, where the iPhone was cool and sexy, right? I had a big white screen up. You know, silly as the sounds, this is super exciting on day one. So then I started to read, you know, learn a little more about how you lay out different apps and how you stick views on there. And most of the guidelines were taking me down to the interface builder road, you know, back into Xcode where I didn't want to go. There's a small set of guides that talked about, you know, you could lay out views and code. So that's the road I went down, right? I found a nice tutorial. I found a nice tutorial I was going to follow. Right, it's not that hard to lay out views and code. You just stick a UI label on the screen, give it some text, and boom, right now I got my name up on the screen. So just continuing down this road, you know, I wanted to add my title, right? You could add a title. Not too hard, just another UI view. I wanted to add an email, right? You keep going down this road. You can see it's beginning to get a little bit more messy. I had to shrink the font down to fit it on the screen. And now there's, you know, big blocks of code, kind of hard to figure out what's going on. So, you know, following this tutorial, not a problem, just add some comments, right? Say what each block is doing. So I'm going down this road. I keep going down this road, right? I wanted to add phone number, address. Now the UI is a little messy, right? There's a lot going on there. I need to add some labels, see what's going on. And at this point, you can see, right, this is too small to read up here. And it's too small to read when it's on my screen, right? It's too small to see what's going on. There's just too much going on here. Now, this is really a mess. Something had to stop. So, at this point, I realized I had to take a step back and go back to sort of, you know, first principles. What is it about Ruby? How do we write good Ruby code? So for this, I know Sandy Metz, you know, her name came up a couple times yesterday, but the Putter book is a great book. It just talks about, you know, some very basic ideas. How to write good object-oriented software. And, you know, she sort of guides you through, you know, when should you write subclasses, when should you delegate, when should you encapsulate? Just, you know, good ideas. So if you guys don't have this book or haven't heard of this book, you should go out and buy it. It's a great book. And one of the things she, you know, talked about and this, you know, came up yesterday was these rules that, you know, I think she talked about this after writing the book, but the basic idea, right, that your classes should be less than 100 lines, methods should be less than five lines, and try not to have any more than four parameters in a method. And these numbers, right, they aren't magic numbers. You know, there's no huge difference, really, if we think about it, between 99 lines and 101 lines. But just sort of the limiting factor of having a number and trying to keep things small just helps, right? Just to have some number that you try and keep things smaller then, helps you keep your code small and focused and easier to read, easier to maintain, cleaner code. So if we just go back to our example, you know, obviously this is not the five-line method here, right? This is something huge and crazy. So luckily, you know, we have a way to deal with this. You know, we have refactoring. So we can just extract method, refactor, to pull a bunch of that code out into methods. So we can, you know, extract, you know, a whole bunch of methods out and wind up with, you know, a view to load that looks more like this. And so to me, this is just, you know, this code's beginning to speak to me. You know, just looking at it, I can see, you know, first I'm going to add the name, then I'm going to add the title, and so on and so on. And, you know, it has the added benefit of the code is really self-documenting now, right? I don't need those comments which saying, you know, add the name now, add the title, because the names of the methods are really doing that same job. Now, of course, you know, with this, you know, we haven't gotten rid of any of that mess. We've just moved stuff around a bit. So we still do have, you know, all that mess and things like add name. And we'll get to that in a second. But we're sort of beginning down the road of, you know, cleaning up the mess that we just created a couple seconds ago, a couple minutes ago. So sort of following the let's get small idea, you know, we can dig into this method and figure out what's going on. So there was a lot going on in there, and it was hard to see at a glance what was going on. But if we really think about it, there were really, you know, two things we're doing. We're just adding the caption, which is that bold text on the left, followed by adding some text. So really, you know, the add name method that we wish we had, you know, would look more like this, you know. It would say, you know, add the caption and then add the text. And now, again, right, this code's beginning to speak to us and tell us what it's doing. And we don't really have to think when we look at it. We just sort of, you know, we see it and we immediately can parse what's going on there. So what is this row view thing we created? And again, it's sort of back to just, you know, basic object-oriented ideas. So, you know, in this case, you know, Coco helps us with this, right? So Coco and in Objective-C, you know, lots of people create custom subclasses of UI View. You know, at least for me, coming into it from, you know, from the Rails side where everything was far in, all of a sudden, you know, I forgot, you know, this basic idea, right? You know, create subclasses that do exactly what you want. So the row view is really just the UI View subclass. And its job really is just to encapsulate the fact that it's got two labels inside of it. And the labels just sort of live somewhere on the screen and the caption just, you know, a little bit of styling applied to it. But the real magic of this row view is the fact that it encapsulates the concept of having a caption and having a text. So it sort of, it exposes these two properties to us and hides the fact that really, you know, when you set the caption, you're setting a text property on a label. You know, it lets us from the outside world just think of setting a caption and that detail is all hidden away. So it really lets us get back to, you know, in the viewDidLoad, that really simple, you know, couple lines that speak to us. And then each of the submethods we create, again, a couple simple lines. You know, in this case, we meet our, you know, the arbitrary five lines per method goal. And we have something small that's easy to read and tell what's going on. So for me, the revelation here was just remembering that, you know, as Rubyists, right, we value clarity and we value, you know, keeping our code small and easy to read. And that, you know, even coming into this, you know, what was for me a new world of iOS development and Cocoa to remember these principles and to keep, you know, to keep following these principles. So I think the next thing I realized as I was going through Cocoa is that large part, right, Cocoa was built for Objective-C and Objective-C actually is a super set of C. So there's parts of Cocoa that are nice and object-oriented, like the UI view and, you know, view controller you can deal with in a fairly natural way from Ruby Motion. But there are also big parts that really expose a lot of the underlying C-ness of Cocoa. And, you know, really, you know, the first place that I hit this and, you know, I hit this the most was dealing with, you know, frames, which are really just CG-rex, which is just a C data structure. And the way you're supposed to create them is with the CG-rex-make function. And I think, you know, I imagine, you know, it felt unnatural enough and painful enough as Laurent was building the first versions of Ruby Motion that he gave us this nice, you know, convenience where you can just pass lists of lists into a view when you're setting its frame. And that works fantastic. But the problem is once it's set in the frame you have to actually go into the C data structure to access, to query, you know, what's the, you know, top of the view? You have to say view.frame.origin.y. And the same with, you know, left, tight width, all those things, where really, you know, what I wanted to do, you know, was not have these little mini train-rex scattered throughout my code, but just, you know, ask the view, what's your top, what's your left? Something simple like that. So this was sort of my next revelation to do this, that in Ruby, you know, classes are always open. So we could just monkey patch UI view to, you know, if we want a top method we can just give ourselves a top method. Something nice and easy to work with. And the same applies, you know, even, you know, it becomes even more important when you're dealing with assignments. So let's say we want to just move the view all the way to the left side of the screen. You know, you would think the way, you know, I thought the way to do it was I want to just assign the view.frame.argin.x to zero. You know, unfortunately this never worked for me, so I actually had to reassign the entire frame. And, you know, I don't know about you guys. When I look at this, I have absolutely no idea what this code is doing, right? There's just a huge amount of noise and a huge amount of stuff going on. You know, in reality it's just that one zero there that matters. You know, we're changing the x property to zero. Everything else is, you know, stay the same as you were before. So of course, right, we can do the same trick. Right, monkey patch, we can give ourselves a left equals method if we want that hides all that inside. So now this is one of the first things I do when I start a new RubyMotion project is I have this file of, you know, the UIView monkey patches that I copy into my project that gives me all these nice convenience methods. And, you know, it even, you know, starts letting me think about, you know, extra methods like, you know, bottom and right, which involve more computation, so I do that. And now outside of this one place, I can think in terms of, you know, view.top, view.left, and start, you know, having a clean application at the cost of writing this one monkey patch file. And at least for me, you know, because that monkey patch file is inside my application, you know, monkey patching a core class is a trade-off I'm willing to make in order to have, you know, clean code through the rest of my application. The lesson sort of I learned from this was that as Rubyists, we love DSLs, and that if something is ugly or clunky or hard to use, you know, we can extend it, right? We don't have to use a hard-to-use clumsy interface. We can give ourselves a nicer, cleaner interface to work with. So I think the, you know, the last big challenge we had in our project was, you know, we're building a separate address book application, and that worked great, right? We could have exactly the functionality we wanted, exactly the database of people we wanted, but when my phone rang, you know, Apple's caller ID knew nothing about this, right? So I just got a random phone number. I didn't know who was calling me. So we wanted to be able to, you know, not keep everyone in sync, but just, you know, the people you interacted with frequently, you know, some people synchronized between our list of people and the built-in address, you know, the Apple address book list of people. So I looked through the documentation, and, you know, there's this great A-B address book class, you know, a nice object-oriented interface to deal with address books and people, and I was really happy, right? This was going to be nice and easy, but then I, you know, read the next line down and it turned out, right, that's only available on OSX. On iOS, I was stuck back at this, you know, A-B address book framework, which took me a while to figure out, you know, that it was different. They're both called A-B address book, but this one is much more of a C-style API. So instead of having a nice object-oriented interface, you know, for example, if you have a person and want to get their first name, you have to call this crazy method, you know. A-B record copy value with a person, with K A-B person first name property. So again, right, these long, crazy, cocoa things, you know, long names, and that thing even gives you back, you know, it's a CF type ref. I forget how you take that and turn it into an actual string, but this was crazy, you know, this was killing me when I started putting this in my code, right? I just, I had the person, I just wanted to ask, you know, give me your first name, that's it. So what to do about this? Well, this is where I think, you know, as a community, right, we've come up with a solution for this, and the answer is right, there's a wrap for that. You know, lots of people have hit, you know, these corners of cocoa there's hard to work with, maybe unnatural from RubyMotion, and we're wrapping them, right? We're coming up with new cleaner interfaces to get at them, they're just easier to work with. So this is my, you know, little contribution to that space, the motion address book gem. So right, so now there's a gem out there that lets us interact with this, you know, much more object-oriented, much more natural interface to deal with address books and people, and so if you want to get a person, you can, you know, just get the system address book, you know, ask it for an array of all the people, and then you want to get someone's first name, just ask them for their first name. You want to change their first name, just assign it, you want to save them, just call save, right? It's a much easier to work with interface. So not only that, but, you know, sort of back to, you know, thinking about Jack's talk that he just gave, you know, it was a great open source experience for me. So I put this gem out there, and all of a sudden people I didn't know, you know, started contributing to it. So this person, Jason May, who I've never met, who I don't think is here, but he, you know, he found it a little bit useful and started expanding on it and, you know, contributing to it. And I'd say at this point he's probably written more of the code in there than I have. So it was just, you know, a great experience of putting something out there and having someone else out on the internet find it useful. And so everyone should do that. Everyone should put code out and just let other people find it useful, and it really is a great feeling. So to really, you know, by doing these couple things, you know, now when I'm writing the code, it feels much more like I am writing a Ruby application that happens to use Coco, right? You know, we're remembering what it is that we care about with Ruby and what it is we care about with, you know, the code that we're writing with Ruby. And doing that, not letting Coco dominate our applications, you know, putting Coco, you know, essentially putting it in its place which is, you know, helping us write the applications we want and doing the things it does, you know, super well, super well. So I think what I've, you know, essentially realized, sort of, over this experience of writing, you know, several Ruby motion apps is that Coco is fantastic. You know, it's, I think, Apple's secret sauce of why so many people can write so many, you know, interactive applications. You know, it's got all these controls, animations. You know, it's got, it's super powerful, you know, but it's also hard to use. You know, the API itself is clunky. And that, you know, with Ruby motion, you know, we as Ruby, let's now have the power to tap into Coco and tap into iOS development and write Ruby, you know, write iOS applications and, you know, coming soon Android applications. It's fantastic. But it's really, you know, essentially up to all of us to figure out how to make that work. That there are, you know, lots of challenges and lots of, you know, struggles that we, you know, we need to figure out how to make it work. And it's amazing to me that over only, you know, the last two years of Ruby motion being out, you know, there's been so much innovation coming out of this group, you know, both in this room and everyone else who's not in this room. You know, innovating and coming up with clever ways, you know, new metaphors, you know, RMQ, you know, promotion, motion, everything. It's, you know, it's astounding to me and I'm really excited to, you know, to be a part of it and to see where, you know, with Android, you know, where we take it next, figure out, you know, how to do the same stuff with Android, how to think about applications that, you know, maybe work cross-platform. Who knows? So, thank you guys.