 My name is Sarah Allen. I go by Ultrasaurus on Twitter and pretty much everywhere. I am going to talk about cross-platform mobile applications with Ruby. I apologize I don't have any photos of hippos or really great artwork, but my hair is the color of Jessica Alba's eye shadow, so I hope that helps. Being a mobile developer is a lot like being really into getting tattoos. So either you're really insanely motivated to achieve this end result or you're perversely into an exquisitely painful experience. This is the mobile landscape. These are the major platforms and for each platform, not only does it like desktop applications, come with its own set of APIs, but each platform almost necessitates a different language. So this is just a crazy development landscape. You're really learning a different tool set and having to apply different languages with every platform. In this talk, I'm going to share with you an experience using CDD, conference-driven development. I decided I was giving a few talks on mobile Ruby development, so I decided to build an app that would be the same across different platforms and open-source the code. I know the network is really bad here, so I'm going to be showing the code at the end of the talk if you want to check it out. It's on GitHub at Blazing Cloud and the project is Rhodes RubyConf. So this is a specific application that I thought would be fun, even though I don't think anybody here has participated, but I'll show it to you on three different phones. So the process that you usually go about when you're writing an app is you write the code, you release the app, people use it. Of course, you have to think about this backwards. You want to think about what you're going to build, how are people going to use your app? You have to think about how you're going to release it, which is a little more complicated on mobile devices than it is, say, on the web or even with a desktop app. And lastly, you have to figure out how to build the code. So this is the order in which we're going to talk about the apps today. So you all know Ruby, I'm going to show you the code last. And what I'm going to share with you is some of the things that you have to think about when doing mobile development. Who here does mobile development? It's a mattering of people. So some of this will be new to you. You've probably all heard of this type of stuff before. So this is where I think mobile development should be. Instead of feeling like body piercing, it ought to feel like creating a custom tailored suit. So I think that some of the tools that I'm going to describe to you today will let you do stuff that's more replicable, where we can recognize common patterns in mobile development and repeat those, not only the design patterns, but similar technical details that we can develop tools for that are just reproducible in ways that they really aren't so much today. So a lot of people have talked about that we were really aspiring to write once, run anywhere. Now I don't believe that's going to happen in my lifetime. I've worked on a lot of these write once, run anywhere platforms and what I've found is you have to develop for each platform. You have to design for each platform. And if you're working with a good tool set or some smart developers, then you can end up refactoring your code so that it's maintainable across platforms. So the next feature you add doesn't necessitate building all your old features on end different platforms. So first I'm going to talk to you, show you the user experience of this app. I decided to show it to you on the device, which requires a little experimental. We'll see if the camera comes up. Here we go. So there's a picture of my dog. There are pictures of animals in my talk. So this is the iPhone app. How many people have an iPhone? I'd say the majority of people in the room. The iPhone is gaining in popularity. It's probably more prevalent in this crowd than it is in most of the United States and certainly it's in a tiny minority in the world. So with the iPhone you get a touch screen and I can scroll this app. This is a relatively simple app. I've got the conference schedule. I've got a couple of tabs. You can see the people who are at the conference who've registered, that would be me. And there's a map that takes a little while to come up because the network connection show I'm not going to show it to you and there's a little about box. So it's just four tabs. It's using the regular tab bar control that you'll see on most iPhone apps. So I've also got here a Nexus One, which here we go, which also has the same app. So you can see that it's got the schedule. It's got a touch screen interface, which is pretty much like the iPhone. It's got tabs across the top. They look a little different, which you probably can't see at this resolution, but they pretty much act the same as they do on the iPhone. Now in the BlackBerry, things are a little different. You've got a schedule. You've got this little wheel thing here, which is how you scroll it. You don't have a tab bar because you don't have a touch screen, but you do have this little berries menu and you can select different screens and they come up and they act just like a tab bar. And this may look really weird to those of you who use an iPhone or an Android phone or are used to these rich experiences, but if you use a BlackBerry phone, how many people use a BlackBerry? Wow, three. I think that's a record for Ruby conferences. Awesome. But if you use a BlackBerry, this is a familiar interface. So the key thing is that these phones are really different from each other, but from the perspective of somebody using the phone, they all do the same thing. And once you've used the phone for a few applications, you can figure it out and it's pretty straightforward. For the degree that we have different development experiences, the phone differences are actually very minor. So many people who are looking at developing applications historically in the last few years as application development has gotten hot by individual developers think about, hey, I've got this idea for an application. What platform am I going to put it on? Where's my audience going to be? But as we move forward and as more and more people have mobile phones and more than half of the people on the planet have a mobile phone now, when people are looking at mobile applications, it's more that businesses are thinking they have to move their business to the web. I mean, from not only the web to the mobile phone and that they want to reach every person who's one of their customers, not just people who have a particular phone. So what we're seeing is in terms of user experience is the brand really transcends the platform that you want to think about your design independent of the platform that you want to deploy it on, which is nice as a developer because then you can start thinking cross-platform. The other thing that I want to point out is that even though these things are like little computers, there is more power in this small device than there was on the computer that I first learned to program on. But from a design perspective and a development perspective, they're not just little desktops. The key thing that you want to think about is these phones enable you to do fundamentally different things with geolocation, the camera, that they're almost always connected and that they have a contact list on them that you have access to as an application. People don't expect to have the kind of privacy concerns that you do for desktop applications. There isn't this import-export thing. Applications aren't so siloed. They're task-oriented and people expect that they can access all of the device capabilities. So your application has that much more freedom. So after you've thought about your design of your application, then you want to release your application or you want to think about the venues for release. So for this application, I released it on iPhone, BlackBerry and Android. Now, most of you probably know that the iPhone can only... You can only release iPhone applications on the Apple Store. Android and BlackBerry applications can be released wherever you want over the air on the web. So on this page, which you can get to if you go to mobileruby.haroku.com, there's a link to the Apple Store and then there are a link to the actual applications for Android and BlackBerry. And if you have those phones, you can just navigate to that link and it will automatically install the app, which is very, very nice. So the Apple Store is... This is what it looks like if you navigate to that link. You end up with... And this is actually not an updated slide because this is the LA RubyConf schedule, but you have your application hosted. It's kind of an experience, which isn't that transparent. You have to sign up and get your Apple ID. You have to fill out a form. You have to provide a legal contact. You have to submit for enrollment and you have to wait. I have a personal application developer certificate or membership, which took about 24 hours, maybe 48 hours to get, but they don't tell you how long it's going to take. So this is the kind of thing you have to do in advance. I just signed up for a company one and we'll see what the verification process is. So once you get accepted for membership by the Apple Developer Program, then you get these certificates that you make in this mysterious process that there appears to be a lot of great documentation for, but it's really hard to find out exactly what you need to do. And then even if you're using one of these cross-platform tools, you end up opening Xcode, although I hear that Rome Mobile now has a rake task that lets you do the same thing. And then you go through these conniptions and put in your signing certificates and you build your app. You submit it to the store and you wait another indeterminate amount of time, which for this application the first time I submitted it was three days, which is like records time for the app store. Usually it takes weeks. And then when they accept it, it's magically up on the store. When I did the dot releases, they took 24 hours for the first one and about eight hours for the second. So I guess if you just make minor changes to your app, it gets better. So that's the Apple Store. And how do you get an Apple iPhone app released? On BlackBerry, you also have to sign up for a key. The Apple Store costs 99 bucks as an individual. It used to cost $300 for a company, but now it appears to cost $99. BlackBerry, you have to pay $25 to get some keys, which they will also not tell you how long it takes to get you. I received three separate emails over the course of three days. And then I could install my keys on my Windows machine, which is actually parallels on my Mac. And then using Rome Mobile, you can use a rake task, which produces these COD files and a JAD file, which is what you stick up on the web and you can navigate to with your BlackBerry. Then if you want to actually put it on the store, you have to apply for a vendor portal. And after paying $200, then you get this email, which makes you either give them your incorporation papers or you have to notarize a form and then you can put something on the BlackBerry app world. Android makes it easier in terms of key generation. You can do something on your local machine. And then, again, with Rome Mobile, you can use one of these rake tasks in real life if you were doing not in real life, but in an alternate universe, if you were writing a Java app, you would do it in Eclipse or something. But you can use one of these. You use this rake task. It creates this APK file, which you can ADB install if you've got your device connected or you can SCP up to your web server and navigate to it. Then if you want to put it on the Android Market, you fill out this form. You pay $25. With BlackBerry, you have to use PayPal. With Android Market, you have to use Google Checkout. And I tried to do this four days ago and haven't yet gotten a response. So pretty much when you're... If you want to use one of these venues, when you're first starting to think about deploying and publishing your app, you should probably sign up for these programs because they take an indeterminate amount of time. So now to the fun stuff. After you've figured out what your app's going to do and you've figured out how you're going to get it out to the world, you can write some code. So I'm going to tell you a little bit about the RoMobile platform, which is how I use Ruby Code to develop cross-platform mobile applications and how I developed this application that I just showed you. So Roads is the RoMobile client-side framework, which uses a MVC pattern which is common in web application development. And some of you may notice, may recognize this type of a picture. The key thing to remember is although it's borrowing from web techniques, it doesn't actually go out to the internet in this request-response cycle. So you define your application UI using HTML and CSS and that develops a screen of your mobile application. When you click a button or a link, that makes a request that has a URI. But that goes to your controller code which is written in Ruby which is on the device. And then optionally it can go to the data store which they call RoM which is device agnostic. So it'll talk to whatever database is on the particular device with a unified API. So you get some data, you render it, you can use ERB files and those get rendered into HTML and that response then becomes the next screen of your application. So it's a very familiar cycle. It's a very handy cycle because a lot of us are familiar with web development. I've done a lot of native code development but the truth is when it comes down to it, you're pretty much making a little state machine and we've worked out in web development really good ways to make little state machines using these techniques. So now I will finally show you some code. So this is the application and it has a structure which is reminiscent of a Rails application. It has a lot of things in common with that framework and it borrows a lot of ideas from that. But the details are different. So I thought I'd start with just walking you through the tabs. So you have your application class. You don't have to have a tabbed interface. This is what this application happens to have. And so you define this data structure which is just a hash that has the label of every one of my tabs, its icons and an action. And like I said, this action is a URI that maps to my file structure here. And then this is the menu for BlackBerry. So here I thought we'd look at the map action. So map calls app person map. So in the person controller, it goes to the map action. And here it creates people instance variable and it's calling person.find. So person is my object that's coming from my back-end web service which happens to be a Rails app which has a person data structure. So I have a person index page with a bunch of person attributes and I do a find and I get all the people. So this has a little remnant of the first time I built this app was before Rhodes actually had map working on a special custom native map control working on Android. It used to be that on Android you would just do it in DHTML. And I thought I'd just show that to you to give you an idea of the kinds of things that you can do in iPhone and Android. So iPhone and Android have the WebKit browser which is pretty much like the Safari browser. So they're pretty powerful. You can do JavaScript using this framework. You can embed ERBs that create as part of your JavaScript. And then you can just have HTML and you can do pretty powerful things. But what I think is even simpler is and it ends up looking really nice because you get a native control for your map is what has historically worked on iPhone and BlackBerry and is now working on Android as well where there's just an API for map view. And this is just a cross platform API that Rhodes has created that abstracts those specific differences between the platforms. So you go through your people objects here. We're mapping the people objects to these annotations which are the specific dots on the map. And then we can call map view create. We're doing on time. Pretty good. So the other thing that I wanted to show you is something that's very different from what we might do on the Web. What I just showed you where you have a UI element where you click on something that turns into a link which ends up calling a controller action. Some of the details are different but it looks a lot like Rails. Something that is substantively different from what you would do in a Web framework is how the settings controller works. So in this particular app, I'll make this a little bigger, the settings controller it arguably should be renamed now that I'm using it for something else. But basically I took the default settings controller and I'm using it for the application startup sequence. So if you just create a vanilla Rhodes app, it has a generator and it'll give you this settings controller which lets you interactively log into your app. What this particular app does is it automatically logs in when you start up and it does this with a sequence of asynchronous events. So you start out at the start action and this is just something that's configured. There's a config file here that'll give you a start path so you can pick any controller action you want to start out with. So we've got a start action and it'll check if you're logged in. If you're not logged in, it calls the sync engine login which will end up talking to the server. If you are logged in, it just navigates to your app route. And then the sync engine has a callback and I've lost my scroll bars but trust me, there's a callback here which ends up calling login callback when it gets that event responded from the server. And then when it finishes logging in, it'll call do sync. So there are these sequence of controller actions that are strung together in something, if you've done event-based programming on the UI, it's more like that than it is like web development. Clients are then classic web development even though you're doing it through controller actions. So I'll stop there and see if anybody has any questions. Yes? So you're good enough to mention the $100 cost of Blackbird iPhone Dev certificate and the $200 cost of Blackbird. How come you didn't mention the $5,000 cost for roads? Sorry about that. Or they're incredibly restrictive licensing. Or in general, why shouldn't we use PhoneGap to do exactly the same thing except for free and with better support? Nice question. So in reverse order, why not use PhoneGap? It's free and there's better support. So PhoneGap is pretty awesome if what you want to do is take HTML and JavaScript and wrap them in an application controller and ship it. I've found the tools to be fast moving in such a way that every time I sync the source, I have to change my methodology, which is a little frustrating and the mailing list hasn't been quite as responsive but I think they have great technology. It's MIT licensed and if it suits your needs, that's great. And I think that PhoneGap is really, seems to be best suited for the things that have the best browser. So if you're doing iPhone Android, then you're going to have a lot of freedom with PhoneGap. If you're doing Blackberry, it's very, very awkward because Blackberry has like 1997 browser embedded in it and it's just very awkward to do Blackberry stuff anyhow and PhoneGap doesn't do a lot for you there that I found. And I haven't tried it on the other platforms. Those are the three platforms I've worked on. So the other question was the licensing for Rhodes and I apologize for not including that but Rhodes is GPL, which is not so friendly. If you want to open source your stuff like this is, that's great. And the truth is I think that most of the time when you're building a mobile application, what's hard is the release dynamics and your code is not typically so magical. The actual code of your application is not often your secret sauce, especially the kind of applications that are really nice to be doing with Rhodes. So I don't think GPL is evil but it means that you do have to open source your stuff. So for the Rhodes, the client-side framework, it's $500 for the license. Rhodes Sync, which is a server and is $5,000 for starts and it goes up from there. Anybody tried to write a Sync server in the room? I have. It's really hard. So most applications don't need Sync. If you don't need Sync, don't pay for it. If you do need Sync, I think that's actually fairly reasonably priced. Other questions? Yes? I have a question or two about it. As I go to the different tabs, they seem to be reloading or there's like, it's blank for a while and then it loads them and I'm curious if I know why that is. And then I just kept on adding myself and going about Sync and I can't see the difference. So there are two questions there. One is, what happens when you go from tab to tab and it blanks out? And I think that, I think I'm forcing a... Here we go. Now I've got a scroll bar. Awesome. Except it doesn't go up. Here we go. So this was probably just a late night desperate, make sure it works, Act. But I am forcing a reload of every page when you go to it. You don't have to. Probably for this app, I should only be doing it for the people page just in case you get new data. The other thing that the app's not doing, the question was, I add myself and I don't see myself right away. So what the app should do is have some logic in there so that it gives you some feedback that it hasn't, because it has to submit to the server and get the updated data. It keeps deleting. So it's... It shows up and then I go away. So what's probably happening is it's not handling errors very well, but that will happen if you go to the server and it has an error and then it didn't really get there. So it's a work in progress. But that's absolutely... In a real app, if this was a production app, you would want to handle those error conditions. Good question. So I'm glad somebody downloaded the app. Thank you. So yeah, I think that this app doesn't give you any feedback if you're not successful in logging in and sometimes that happens on the mobile web, internet. So I'm glad it's working for some people. So it's not a fundamental problem. It's probably just a feedback problem with the UI, not being fully completed. You up there? So in your controller, when you did, like person.gui, you said that was a call to your backend. Was that an API like Active Resource or making it look like that? Person.find, it looks a lot like Active Resource. And I think it's borrowing that syntax because it's familiar to some people who come to roads. Yeah. And it actually won't... It'll get it locally if you have it. And then it'll trigger a sync if, you know, if the time is elapsed where you need new server data. And that's what you're paying 5K for that functionality? Well, you can do this client-side only. So if you want to just keep the data client-side and, you know, you're making a to-do list app or something, and either you're going to use like the Net HTTP APIs or you're just going to keep the data locally, then you don't have to have the RoSync server or use it. But you'd still use this syntax to talk to the local database. Other questions? You? I've heard that the roads of VM had to disable eval because of Apple's restrictions on dynamic code. In practice, does that limit enough the kinds of gems you can use in a roads app? Or does it not really come to be a factor in practice? Well, in practice, I don't know ever in my real life that I've used eval in any dynamic-stripping exercise that I've done in other languages as well as Ruby. But up until recently, you couldn't actually use gems on the device, so I hear that you can now use additional libraries on the device. So pretty much what I've been doing is I just stick to the basics that are available in roads and I haven't experimented that much. Other questions? I just have a question. So using this app, partly it could be the reload issue. What's your experience with performance on the app? Typically, is it native speed or is there, because you're doing this stuff so much? Yeah, you're using a framework and you are going to see a slowdown because of it. I definitely find that it's a little more sluggish than a native app for doing the exact same thing. However, it is challenging to eke performance out of a native app as well. So depending on your application, that can be more or less important. You wouldn't ever, you wouldn't want to do something where there was a lot of dynamic gameplay in a roads app, but I think that, I think it's just going to get better over time and you just have to weigh your development maintenance costs against that performance slowdown that you see sometimes. All right, thank you. Thank you.