 My name is Jayman Holm, one of the authors of Pro Motion, which is a fairly popular Ruby motion gem. I am from Vancouver, Washington. It's over by Portland, just right across the Columbia River. And I'm the owner of ClearSight Studio, where I have small development, both web and mobile applications, mostly Ruby Rails, as well as Ruby Motion. You can follow me on Twitter at Jayman Holmgren. Mostly, I just tweet about Ruby stuff, so if you're interested in that, then go ahead and follow me. Today, my talk is titled Going Pro. From prototype to production with Pro Motion. Pro Motion is a Ruby Motion library, and I'm going to demonstrate to you what it is that makes Pro Motion I think useful for a lot of people's workflows who are Ruby Motion developers. The first thing I'm going to talk about, hopefully you guys can see this. I did kind of a dark background theme here, but I'm going to talk about the Cocoa Touchway. So when I started Ruby Motion, I started Ruby Motion in the summer of 2012. This was not long after HipBike came out with Ruby Motion. And I was new to iPhone development. I had done probably about, I don't know, 80 hours of Objective-C research, demo apps, things like that. I came from a Rails background, a PHP background, as many of you also have. So this was new to me, strong typing, a lot of things that were just different about Objective-C. And not only Objective-C, but Cocoa Touch. Of course, Cocoa Touch is the framework that exposes APIs to us as iPhone developers and allows us to actually make our apps. The big thing to me that was a real drawback was I felt like I was writing a lot of boilerplate code. I don't know if any of you have dealt with this before, but even looking at, for example, some of the Ruby Motion sample repos that you find out there, you see something like this. I don't know if you can see that, but a lot of you have written these lines before. This is nothing new to you. Application did finish launching with options. And then you're creating a window, you're assigning a root view controller and initializing that. And you are setting some other things up, make key invisible, return true. All these things you have to do in order to actually pull a new screen up on your device. In this amount of code here, there's really only one thing that I'm interested in, and that's the main controller. That's what I want to launch. That's what I want to put up on the screen. So for me, when I was a new Ruby Motion developer, I'm thinking like, what's all this other crap? I don't know, why do I have to do this? So I had an app that I needed to build for clients. We do mainly console work. And we started writing the app in Ruby Motion, and we started realizing my employee, Silas Mattson, and we looked at the amount of code we were generating. There's got to be a better way. There has to be a better way. We looked around, I think, Ruby Motion Rappers by Clay Alsop. I don't know if that had been launched yet, or maybe it was brand new with almost nothing on it. And there just wasn't anything out there in the framework to work with them that reduced the amount of boilerplate. Brian Kernigan, who some of you may know the name, I believe worked on Unix. He's a big name, really, in the programming world. He said, controlling complexity is the essence of computer programming. And I really believe that. When I look at the previous code, I see complexity. That probably was a pretty simple example, but let me show you something a little more complex. You can't really see it, but I really wouldn't do any good if you did. It's just a lot of code. Sorry, Laurent, I know you wrote this code, but it's a lot of duplication. It's a lot of information. This is really what this is. It's a table view will display or self-erode index path method. And as you can see, there's a lot of duplication. There's a lot of... And with Ruby, yeah, we can go in there and we can clean it up a bit. But again, you're dealing with a whole lot of boilerplate code. And to me, boilerplate hides bugs. If debugging is the process of removing software bugs and programming, it must be the process of putting them in. And I want to do as little of that as possible. So in order to reduce the amount of bugs that I'm introducing, maybe you guys are better programmers than me but I'm doing typos and just boneheaded stuff all the time, then I want to do less programming. I want to do just what is really relevant to my application. Let's talk a little bit about UIKit tables. Of course, UIKit is the library that allows you to interact with the user interface in an iPhone app. One is the UITableView data source. These are the methods that you need to implement. TableView, self-erow at index path, number of sections in TableView. I won't read the rest. There's also UITableView delegate. This is just to display a table on your screen. I didn't even put the methods there. There's just a lot of them. You have to go look at the documentation. I'm sure many of you have done this before. But to me as a beginning programmer, I looked at that and thought, I come from Rails. You go into a template file. You do a little each loop and you output some rows. It's very simple. It's very small. This is what we were having to do. It's a whole different paradigm. It's the whole delegate thing. It's just a different way of looking at things. To me, it's just ugly. I look at that and the code is just... It's not what I want to see. It's not something that I would look forward to coming into work. I'm the owner of the company, but I still do some coding and I have programmers who work for me. I want them to come to work and actually enjoy what they're doing. To me, I didn't enjoy that. I enjoy Ruby, but I did not enjoy that part of the Cocoa Touch API. We are Ruby developers now. Even you formally Objective-C people. You come to Ruby Motion and it allows a lot of the workflow things. For me, I'm not looking for Objective-C things in Ruby syntax. I want Ruby things in Ruby syntax. Then the Objective-C stuff, I want to keep it as far out of sight as possible while not causing issues. Obviously, there's a cost to any kind of abstraction that you introduce with a gem. I know that there's a lot of talk about if you really want to introduce another gem that creates a DSL that you have to learn and maybe introduces its own bugs or if you have a problem and how do you debug it, that sort of thing. To me, though, Ruby is beautiful. Ruby is beautiful just like you. This is a screenshot of an app that we just released recently for our customer. Most of the time, our apps, you're not going to see them on the app store. This particular one is. Walker Tracker. It's an incubated startup in Portland, Oregon. This is the competition select screen. You can't really see that. I cut it off a little bit there. This is a sneak peek at Promotion. You can see that it's an expressive API. It's refreshable. You can set a title. We have a will appear and will disappear and onload, set nav bar button right. You can read all of that and probably know a little bit about what it's doing. If you come from a Ruby on Rails background or if you come from an Objective-C background, it's very expressive. When I look at something like table view section for section index title at index, I'm not impressed. Some of you have probably implemented this method. I have. It says what it does in book form. To me, Cocoa Touch is verbose. It's hard to remember. It's not easy to remember. I'm always in the documentation. I'm always looking things up. You can have an app like Dash or you can have really good IntelliSense or whatever. I'd rather have things come easily to mind. I don't have to go look them up. It hides bugs. It looks hideous. This is my opinion. You may want to go a different direction, but for me, this is what I was experiencing when I was a new iOS developer, mainly using Ruby Motion. Let's talk about the library that I created called Promotion. We started building this app, Silas and I, and we split into two paths. I started working on the gem and Silas was working on the actual application. He would need an API. He would build it. He would implement it. We would make it work. Along the way, we acquired a test suite. I didn't know how to test originally in Ruby Motion, but Matt Brewer came along and helped add a test suite. Had some other contributors come in as well, including Mark Rickert, who was able to come in and add some new features, add tests, things like that. For me, Promotion is great for prototyping. You can go out and do a prototype in another tool. There are other tools out there that you can build prototypes, but if you're not building in the final language, you're going to tear it all down. You're going to build it up again in another language. If you were to start with, for example, I'm trying to think of a blueprint. There's an app out there called Blueprint that you can actually design an app on your device, but still, all you have is the UI. You're not going to be able to then build upon that and actually create an actual app out of it. What does Promotion give you? Well, first off, Promotion gives you the Promotion delegate. So, instead of on the left here, again, it's probably hard for you to see. I'm sorry about that. But this says class app delegate. Again, this is something that many of you have written. Application did finish launching with options. It's all cut off on the right side because it's so long. You're creating a window. You're creating a home controller, a nav controller, and you're doing other stuff in there. This does the exact same thing. It's actually pretty much the same code, almost, behind the scenes, behind a DSL. App delegate, and you inherit from Promotion. PM is just Promotion. Delegate. And you have status bar true, animation colon none. That's very expressive. You know what it's doing right off the bat. Excuse me. Then you have an unload method, so much smaller method, and then you open your first screen and you assign it. You give it a navigation bar. That's it. That's your delegate. So let's go look at this screen and see, you know, how much different really is a Promotion screen from a view controller, a UI view controller? Well, first off, it is a UI view controller. It's a subclass. So you really aren't giving up anything. We're just giving you more. Excuse me. Alias is common methods. It kills a boilerplate. So anywhere that we found that we were doing a lot of boilerplate, we would create helper methods that would do it for you. And again, it's just doing what you would have already done, but it's giving you a little DSL for that. So here's a Promotion screen. On the right-hand side, you can see the result of this. It's not very impressive, but it's a welcome screen. I'm including a module for some styles. Really, all that is is just a bunch of methods that give you hashes. It allows you to set a title, title home. Onload, it gives you, it lets you set the navigation bar buttons on the left and the right side with a title and an action. So if somebody taps it, it'll actually call that method on your screen. It has a will appear and a build view. And there's other methods that you can implement as well. Building the view, you have some helpers, set attributes. You have add. And within those methods, you can pass in the name of a method that it will call to get a hash, and it will iterate through those and apply your styles for you. This is a very basic styling system. It's a way to get you off the ground quickly. So that's kind of cool, but there's also another one called Promotion Table Screen. This is, for me, one of the more exciting parts of Promotion. Again, it's a UITableView controller subclass, so you're not giving up anything. You can implement your section for title and section, title, whatever method if you want. But we do it for you. You just provided an array of hashes, which I'll show you in a second here. And then we handle the rest. We will go through, pull out your data at the right times, give it back to your application when things are called. And display the right thing. We also handle little subtle bugs. There are little things, not bugs, but just gotchas along the way that a beginning developer might run into. And let me talk a little bit more about that. When you start off and you have this learning curve that's really steep at the beginning, like it was for me, it's really easy to lose momentum. It's really easy to kind of, even if, let's say, you've implemented a couple of apps in the past, it's still kind of a steep learning curve to get over the first amount of boiler play. I just want a table, and it just has to have, like, five things on it. I have to implement all of these methods and kind of figure out my own way of building a data source or something like that. Instead, you can do something like this. So on the right-hand side, you can see the result. It's a group table screen in this case, a PM group table screen. There's not much difference between the two, table screen and group table screen. But on the right-hand side, you have my profile Facebook. This is something I actually pulled out of a production app that we built. On the left is the code. Again, apologize for the... It's hard to read here, but setting screen, set the title again, and then give it a table data method. And then you have an array of hashes, and I'll actually highlight here on the left, here's a section. On the right, there's a section. You go in there, you want to change my profile. You just change my profile to something else. And then you give it actions, and it will call the actions in your screen. So this is extremely simple. It's something that, once people start using it, they kind of look at you sideways if you're actually implementing your own table view controller unless you're doing something really crazy. Table screen doesn't just give you that. It also gives you some other really cool helpers. One's called searchable, and one's called refreshable, and they do exactly what you would think they do. You say searchable, and then, as you can see on the top one there, it gives you a search bar. Type in something. It actually filters down. Works exactly how you would think it should be. You can give it a placeholder if you want, things like that. Refreshable, when you pull down, it'll use the built-in iOS 7 refreshable control. And then call on refresh method for you. So you can go in there and do your asynchronous call to parse.com, you know, cloud database, or whatever you need to do, and when you get the data back, then you say stop refreshing. It will slide back up and update your table data. It's very cool. We also have a promotion web screen and promotion map screen. These are really pretty simple screens, but if you need to show just some HTML, which could be in your resources folder. So if you want to build a view in HTML, just to get it up there quickly, do it, implement it in a web screen. I'm not going to show you some code here, but you can go look on our GitHub. It's extremely simple. Very easy to just give it the name of a file. You can also give it a URL, or you can just go to the website, which is web-server-worth-apple.com. Map screen, you can add annotations. You can zoom to a certain point. It's just got a great DSL, great API, that allows you to do these things in a very expressive way. Even a beginning programmer can come in and immediately know what's happening. So promotion is easy. It has a memorable API. We do a lot of work making sure that the API is memorable. I mean, if we're not afraid to change things, if we introduce something and it just ends up not really fitting, we'll work with it to make sure that what you're calling is what you would expect to call. It gives you a promotion delegate, table screen, web screen, map screen, and some other things as well. But in all, it's a very focused gem. It's really focused on UI view controller, management, communication, things like that. So that's great. But what about production? I mean, you're abstracting all this stuff. We have performance issues. We have problems in production. We use promotion in production apps. Mark tends to use the bleeding edge version in his promotion apps. And not recommended, by the way. It is lighter than bubble wrap. Many of you use bubble wrap. It's lighter than teacup. It's lighter even than Formotion, which is a very focused app. I mean, a gem. And so it's actually not a heavy gem at all. It doesn't add a lot to your application's footprint. We also do some things to make sure that we're not being invasive. Sugar cube, much as I love sugar cube, it really goes in there and adds a ton of monkey patching everywhere, which is awesome. I mean, I use it. But we don't want to get in the way. So we stay out of the way. We don't monkey patch very many things. There's a couple of little things that we'll do. But we're very unobtrusive. It has a cooler name than RMQ. Sorry. Actually, I couldn't think of anything that did better than RMQ, so RMQ is an awesome framework by an awesome developer. And we actually do a lot of things to make sure that we don't conflict with RMQ because we know that it's a popular gem and we want to make sure that people can use both and they don't get in each other's way. And so we really focus on that. Currently, it's 36 files, 2,073 lines of code. That's for Promotion 1.2 and has 521 tests. So it has a decent test suite. We know when things break. I just broke something a few minutes ago and fixed it. And this is the coolest part. We have 37 contributors. I really, really appreciate that. That is awesome. It's far beyond what I ever expected from Promotion. I thought maybe 37 people would even look at it. But we have 37 people from all over the world and all different languages, all different cultures. It's just amazing. But what gravitates maybe non-English speakers to Promotion is the fact that it's very simple. It's very easy to remember. It doesn't have all these long English words. And so that's something we take very seriously. We want this to be a welcoming community for beginners, for non-English speakers, as well as advanced programmers who want to do some really cool apps. So Promotion really is here to help you. It's not here to dictate your conventions. It's not going to be the rails. It's not going to go in there and say convention over configuration type of thing. I mean, we'll have our own conventions. We'll show you how to use it. But you don't have to use every part of Promotion. In fact, people rarely do. They'll use parts of it. Well, actually, I use almost every part when I'm building an app. But then they'll mix in other parts where if they have an issue where they need to do something more custom than what Promotion allows you to do with its API, then they'll implement their own version of a method that maybe we have implemented behind the scenes. An example is the Inspect app. This is some code that Mark wrote. And it's the Speaker View Controller. So if you pull open the app, you're going to look at that and you can scroll through the speakers. Actually, I'm sorry, this is the one where you can see the individual speaker. So you'd go there from a table. You can see that it's inheriting from Promotion's screen. There's a Style Sheet. That's not us. That's Teacup as well as this layout here. This is all Teacup here. And it works great. I mean, even where Mark had to go in there and implement his own, let's say, Promotion, for example, he would implement his own version of Promotion and then mix in the Promotion screen module, which brought in all of the awesome Promotion sugar with it. So you can mix and match your own view controllers and Promotion screens. You can open screens and view controllers, you know, with your present view controller, or you can do it with Promotion, open modal, things like that. Promotion actually doesn't care if something is a Promotion screen. It wants a UI view controller, but you can give it just a bare UI view controller and it'll open it. And you can mix in other gems, as you can see. Teacup works great with it. We really, actually, because Promotion is such a popular gem, we have 970 some stars on GitHub. Maybe some of you could start and get to 1,000 here. But because it's so popular, we hear about it if something doesn't work. And then we have a lot of issues that get opened. By the way, feel free, open an issue, even if it's like you think the dumbest question, we're nice, we don't like jump on you about stuff, even if it's something that, you know, read the docs. We'll give you a link to the docs, to the right spot on the docs. So how do you scale Promotion? Well, I think one of the things is keeping, like Brian Carnegie had said, keep the complexity under control. You don't want your UI view controllers to have all the styling logic in it. So get them out of your screens. I'm a contributor to, Colin has done most of the work on. RMQ has its own styling system. And you can use Teacup as well. There are other ones out there. I know Jack has a styling system as well. You can subclass your own UI views. I'm not going to go into this. This could be its own talk in and of itself, but using UI view subclasses to pull logic and, you know, behavior and stuff out of your controllers. You don't want a lot of that in your controllers. There's many different ways to structure this, and I'm sure that going through this conference you're going to hear about a lot of it. Make your own screen subclasses. We've heard a lot of people request something called a collection screen because they want to be able to do something like, you know, swiping through a list of, you know, music albums or something like that. We haven't done that. It's actually a pretty tough task to do. We may do it at some point, but feel free to do your own. And build your own gem that works with ProMotion's great API adds to it and allows you to do something like a collection screen. Amir Rajan built a dark room. He says at the bottom here, I have made millions, thousands, hundreds. I think he's probably made more than hundreds now. But as Laurent said, he's been at the top of the app store for pretty much forever. And 12,000 lines of RubyMotion, some of those, not a lot, but some of those were ProMotion. He used ProMotion as the basis for all of his view controllers, where he could. And I talked to Amir, and I don't think he could be here today, but he was very complimentary. He said that it was, he would use it again if he were to start over with a dark room. He says, ProMotion table screen was stupid, simple. Thanks for the framework. I can't help the Google, though. I'm sorry about that. I asked my cousin, like, what name I should give it. That was a mistake. I did actually just look, and I think it's actually like 8th in Google if you just type ProMotion. It's kind of weird. So, let's see, where am I? So they are just view controllers. They're used in production apps already. Many production apps are using ProMotion, and it works well with the layout and styling gems. Pretty much anything. We spend a lot of time making sure that ProMotion doesn't get in the way. I'm going to talk a little bit about ProMotion 2.0. I've been working on it. I have it about ready for a beta now. I'll probably get it out by the end of the conference. Really, this is probably the only announcement this week where someone will announce a version that has fewer features than the previous one. Really, we focus ProMotion. ProMotion has gone from being, hey, let's do everything for you to... No, let's not do everything for you because everybody else has different ways and better ways than I do at doing things. But we do a few things really well. 20% less code went through, and because we had great testing suite, I was able to refactor, bring a lot of methods. I don't know if any of you have heard of Sandy Metz and her rules for classes, Ruby classes. We try to follow those where we can. Not always successful, but we're doing a better job now. If you look at the PM2 branch, you'll see that the code is very clean. I'm kind of proud of it, actually. Don't look at the other branch. Builds 55% faster. I think this is huge. When you're building a ProMotion app, the ProMotion part of it is going to happen 55% faster. In other words, like 45% of the time it would have taken before. We also got our code climate score up from 2.65-ish to 3.5-something. So much, much better code, much cleaner, much easier to read. Maybe you guys can help us contribute now that the code is actually very, very clean. By the way, 20% less code. We're actually at about a little over 1,600 lines of code. It's not very much, really, for a library. We also extracted some non-core parts. ProMotionMap, ProMotionPush, that's push notification support, which, by the way, is a really nice DSL. If you're using push notifications, go look at that gem. ProMotionForMotion is now out of the code base. So you would just say gemPromotion, then next one you'd say gemPromotionMap if you want the map. It all seamlessly comes together. We do a lot of things to make sure that they work really well together. And like Laurent said, he wants some help with the Android version. Well, I just added this bullet when I was waiting. ProMotion 3.0, Android support. It's something I've been really interested in doing for my consultancy, for one thing. Having Android in our portfolio is a big thing because we have a lot of startups, and a lot of startups are going to come to us and say, can we build an iOS app? Yeah. We can build an iOS app. No problem. Can you build an Android app? I think I know somebody who does Android, you know. But now we can do it. And if ProMotion does that, for one thing, it'll allow you guys to, if you haven't done Android before, if you know ProMotion, you can then jump over and have a common set of APIs that you already understand, you already know. And we'll do as much as we can to keep the APIs consistent. I haven't done a lot of thought about it. Again, you know, in the last 30 minutes or so, is how much I've thought about it. So really, for your next app, start with ProMotion. You can use the ProMotion new generator. Just basically create or close down a template. Get a prototype up fast. Add other gems. There's tons of other gems. Use them. They'll really help you. And then hopefully profit. That's all I have. Thank you.