 Hello, RubyConf. I'm really excited to be here. Just under a year ago today, around December 13th, I started learning Ruby in order to learn Rails. Who's a Rails developer in the room? Who's not a Rails developer? My goodness. I had the feeling that all the Rubyists were like, no, Rails. So I have some people who are of the same heritage. But I've done a whole bunch of projects in Ruby that had nothing to do with Rails. And I find the Ruby language very delightful. And I've had the opportunity, amongst other projects, to do some mobile development in Ruby. And that's what I'm going to talk about today. So just to get a feeling for the audience here, who has done mobile development? Raise your hand. Actually, that's a fair number. I'd say probably about a third of the room. Anybody done mobile development in Ruby? Oh, a handful. And of mobile development, iPhone. Probably most of the mobile developers in iPhone. Blackberry. A few Blackberry. Windows Mobile. Three. Android. Six or seven, maybe 10. Anything else? WebOS. Anything else? Palm. J2ME. All right, we got some, all right. Server-side SMS-based applications. So we may have some people in the room who are way more expert at mobile development than me. But I want to start out by telling a little story about a project that I did this summer. So one last question. Who here has done consulting or professional services? Probably say about half the people here. So this story might have some familiarity to you folks. And the other folks might find it interesting. So it was a little adventure in agile development, which is always a challenge when you have clients. And generally I found it easier to do agile development when I'm doing product development rather than doing engaging with a client, especially for something short. But I regularly, I'm an independent consultant and I regularly get calls for prospective projects. And often the mobile projects are strategic, which is usually a code word for, this is not actually important, but I'm gonna get points with my boss for having this conversation with you. So sometimes it really is strategic, but that is an important, and they're actually planning to do something in the near term. But often you have these conversations and people are thinking about it. So I got on the phone with this guy and pretty big company, Fortune 15, actually pretty enormous company. And he was one of the more technical folks that I end up on the phone with for a first call. And actually had a pretty good idea for a mobile application. Sometimes you'll get these ideas that are, they have some big sprawling web application and they all wanna squeeze it into a three by five interface and that's just not gonna work. But this guy had a really good idea. And so I borrowed a trick from some of my Ruby friends and I suggested that we could pair on a project and we could develop a prototype together. His team could learn, I could teach, and then I wouldn't have to spend so much time writing a spec and it would be awesome. So that resonated pretty well. And he said, okay, I have a meeting tomorrow, but this is probably in the January timeframe or so. So he got back to me the next day and he said, the meeting went really well, we need a proposal. We talked through the specific screens and I said, well, this seems pretty straightforward. I think we could do it in like six or seven days on the iPhone, another few days for the Blackberry. And he said, wow, really? I said, shit, I should have said longer. But he came back and after yet another meeting with his execs, he said, we have a user conference in three weeks and we wanna do a prototype for that. And I said, well, you know, you are a pretty big company. Can you really move that fast and blah, blah, blah. And they actually managed to sign a contract in three days and we got together and two of their engineers flew out. And in San Francisco, we went from having a story of what this mobile app, what somebody was gonna use this mobile app for to a prototype on iPhone and Blackberry that was fully integrated with their soap backend in 10 days. And it was really awesome and a tribute to a lot of the agile development methodologies that I've picked up with this crowd and to the real mobile platform, which I was working with. So with that introductory story, I'm gonna tell you a little bit about the technology. Oh, I wanted to point out that typically I'm working with enterprise customers who have this challenge, which is they wanna reach all their customers. It's really not that bizarre a thing for people to want. However, it's a technical challenge. So those of you who know mobile development know that we are in this really kind of odd situation which is very different from the desktop world, which is that pretty much whichever operating system that you're using almost dictates the language that you use. Now there's some exceptions to that, but frequently, you know, like on Symbian, you can do it in J2ME, but then you have limited access to certain APIs and, you know, C-Sharp, you can actually use a whole bunch of different languages, but that doesn't mean that you can do the types of things that we're used to doing on Windows and Mac where you have a C++ app and you wire in some libraries and most of your code is identical across the platforms. And that did take us several years, many years, to get to on the desktop. Anybody who's developed desktop apps, probably 10% of the audience, but that's what I used to do long time ago. Anyhow, so this is the kind of situation that companies are faced with. They want to actually reach most of their audience, but it's a technical challenge to do so. So this is where Ruby comes in. So there's an opportunity for really solving these problems with cross-platform framework. And so combining Ruby with HTML and CSS, you can create something that has the same technologies across all of these different runtimes and shares not all of the code because the UI still has to fit the form factor and there are differences, but not in your application logic and not in the core features. So today I'm gonna talk mostly about RoMobile and do some live coding, but I have backups on the slides just in case. And also about a couple of UI frameworks that I found to be particularly neat in working with iPhone look and feel. So talk first about RoMobile technology, which is called ROADS as the client side and then there's a server side technology called ROSYNC. So ROSYNC is really best for data-driven applications. You can develop those kind of applications really quickly. You've got local data on the phone that ties in to all of the various, the platform-specific stuff and you don't have to deal with it in a platform-specific way. And like I said before, the Ruby code is shared across all of your applications and the HTML, CSS can often be shared certain platforms like Android and iPhone or both WebKit and those are really easy to share code across, but then other phones are a little more challenging. So this gives you some familiar tools. So ROADS is a gem. There are some rails like generators that I'll show you. There's a lot of rake tasks that make building this stuff a lot more seamless and ROSYNC, the middle tier, is a Rails application and ROADS is not Rails but it has some things that are sort of hard from Rails and picks up some tricks in terms of workflow. So one thing that is a little hard to grasp for some folks is we do a lot of web stuff so it's easy to think about having an HTML interface and think you're building a web app. But actually the way that it works is this may be implemented in HTML. It doesn't have to look like it's a website and in fact it's installed, like it's a web app, you get like an icon that you select and it opens your web, your, sorry, your native app and it's just that the UI control is embedded inside the application. So it's being used for application UI not to communicate over the network and this is actually something that I've seen a lot of people use just in their regular Objective-C apps or Java apps. In fact, Laurent showed it the other day with Mac Ruby, this application, the demo application that he built because it's really convenient to quickly lay out some UI in HTML and these days there's an awful lot of designers who speak HTML and can lay stuff out and it creates this sort of lingua franca of UI design that we didn't really have pre-web. So I think there's a real opportunity there. So Rhodes has within the phone, within this native application the same kind of MBC model that we see in Rails. So you'll have, I'm gonna just point because I don't seem to have a mouse, so you'll have a screen and the user clicks a button and that will generate what looks to your program like a web request but it's all internal to your native app and it goes to a controller and then the controller might access the local database on the phone and of course it could access the remote database as well, the sync server and then when it gets data back it renders a view which is HTML, ERB files and then that creates another screen of your app. So now we're gonna write some code and I say we meaning me. So the RodeGem installs the RodeGen command so I can just say RodeGen app and we're gonna make a little inventory app for our store and it generates a directory with a bunch of files in it. You get a configuration file, some build specifications, your views, rake file and some other stuff. So I'm gonna go into that and then I'm going to create a specific model and the views that go with it. This is similar to Rails Scaffold. So I'm gonna make it a product model and it's gonna have, and these are, I'm just gonna pick out some attributes that map to this web service that I'm gonna call later if we get to that point of the demo. So we have a brand, a name, a quantity, price, I think that's about it. And it creates a configuration for that specific model and then the sort of the standard views that you might expect an index view that would list them, edit, new, show and a controller and these are unlike Rails, these are all grouped under a single directory and then I can run a rake task to build it. Oh, before I do that, let me actually just fix up the start screen. I'm gonna edit the config file because the first screen that you go to is configured. So normally, it just goes to this index page but just for a shortcut, I'm gonna go to the product page and that'll go to the product index page. So now what it's doing is it's actually taking my Ruby code that was generated and I'll show it to you in a little bit and binding that with the native code and so some of the code gets compiled into Objective-C and some of it remains a Ruby byte code that's executed in the context of this application and then the HTML views are bound up with the application and then it automatically runs the iPhone simulator that I have installed with the iPhone SDK. So this is my inventory app and I can click on it and I get my index page for my products and I'll specify a product and make it a scooter. What's that? Oh, rockets. Yes, that would be, that'll be our next product. Think a new, so that's the Acme product and there is my show screen. So it's really, those of you who've done mobile development might know that it's normally a little more time consuming to come up with an initial app, so that's pretty fun. So now I actually wanted to say instead of just Acme I wanted to say the product name. So let's see, here I'm gonna skip over to another copy of this app and I'm pulling out of the oven, no. This is actually the exact same thing, I'm just using this, nevermind, I'm not going to use that because it's not starting up. So what I wanted to show you is I think it's easier to see the directory structure when you have it laid out graphically. So here are your views and this is my edit view which contains ERB, so HTML. Here actually, I'm gonna just go to where I can edit it. So in my app directory, in my products directory is an index.erb and then I will make this bigger for you. There we go, is that readable? Maybe? Yes. All right, that's probably less readable because it wraps. So this isn't that surprising, right? You've got a few things that might be a little different from a webpage because of the layout, you wanna have a toolbar and whatnot that are typical of mobile applications. And here I have a link to Helper which is just named the same things as it is in Rails and I wanna specify that it's gonna have a name as well as the brand. So this is just a little bit of embedded Ruby code amidst my HTML in a way that's probably familiar to everybody here. So then I can run iPhone and that will rebuild my iPhone and generate, I mean, rebuild my iPhone app and generate the native code. It also cleans up the database every time because you wanna sort of start from scratch. There's all sorts of ways that you can decide not to do that but it's generally a good idea. So what do we want? Rockets this time? We'll have 52 of them and maybe they're free. Yay, and now we have Acme Rockets. Let no applause. Here we go. So we went through, so we generated the app, we generated a model which is created the views in the controller which we'll talk a little bit more and we configured it and we ran it. There are also rake tasks for most of the different devices and the Roe Mobile team is actually amazingly fast at churning out new helper stuff. So it was a little gritty earlier this year but it's gotten to be pretty smooth workflow and it's constantly getting better and if we have time I'll show you Roe Hub which is a new, I don't know. I just got a chance to borrow the droid. Thank you. So yeah, this is it, running on an Android droid, Motorola droid and you can come up afterwards, we were gonna have, or I might try to broadcast it if we have time but the apps are generally pretty similar but there are device specific features like the BlackBerry has this little menu that if you press the berries button you get to see. So you can specify those things and then the iPhone, the iPhone has a toolbar, you probably all know what an iPhone looks like but yeah, the iPhone has a toolbar and it could have the navigation panel or the toolbar. So I wanna talk a little bit about sync which is optional, you can build something that's completely client side on roads but sync features are pretty cool and having done some client server sync stuff in a past life, it is pretty time consuming to get all that code right so it's nice to be able to just use this. This, there's also a generator that will let you generate the boilerplate which is these specific touch points that you'd expect for sync. So this login and log off which are optional, you can just have blank implementations of those if you don't require authentication and then query and sync go hand in hand, query checks out your back end and then sync gives you an opportunity to fix up the data if you want to and then create, update and delete are basically an opportunity where the client will call the server with the records that are new or changed or deleted and then the middle tier, your source adapter here calls your web service with whatever protocol that that service works with. So it's pretty neat because I can be offline and be modifying my little database here and changing things and be out of range and then when I'm in range the creates will go up to the server and then my code will be able to sync up with my back end. So I wanna tell you a little bit about the actual query just to give you a taste of what it's like. You end up with really like a page, page and a half code. It's pretty straightforward code to write especially if you already know Ruby. In fact I know a lot of people who don't know Ruby and come try this out and it ends up being pretty straightforward even if you're brand new to Ruby which is kind of neat aspect of Ruby language. So in this case I am up here is my JSON. You probably can't read it but I'm sure you all know what JSON looks like which is comes from this mock service that's written in Rails but it could be SOAP or it could be XML or whatever. So then in this case I've implemented this query method which opens the URI and pulls out the JSON and then just iterates through it and turns it into this other format. So basically, Rowsync if you hand it this hash of hashes where you have a unique ID and then name value pairs, it will keep track of all of that and update your device with what you need and then on the device side you get these simple data structures that then you can pour into your views and these Ruby objects are actually pretty easy to work with on the client side. So then just a little detail here, I just wanna give you the flavor of what it's like to do this. If you're running your own Rowsync server you would then configure the source adapter and configure the client to point to that source adapter and then you're off and running. So I wanna dive a little bit more into the human interface. The controllers are looked very much like Rails app would. You, when you're doing like a product.find your, you can pass in parameters that are any of those attributes and you can get them together in Array or Singleton and then they get handed to your view and you deal with them in ERB just like you would in a Rails app. And then we talked about the ERB in the coding session. So if we have time I'll demo that a little more but I wanted to touch on some of the toolkits that we've experimented with. So there's probably like at least when we looked at this in August there were about 25 different toolkits that did some iPhone special looking thing. And most of them implement like two or three controls or a couple of animations that aren't really that much more than jQuery. But some of these two stood out as ones that are particularly interesting and fully featured and you can actually use them together and we've done that. iWebkit has native looking iPhone widgets so it's got a really nice collection of widgets. Here's most of them and you end up wanting to have these graphical elements and they're not that hard to build but it's awesome that these kids in Sweden or Denmark have created them and it's open source, it's LGPL or you can buy a commercial license if people you work for don't like that. And then JQ Touch is made by Netobi and it's also open source and it creates native feeling iPhone UI. And we've got an app up here we can show you afterwards that does the all the slidey swooshy stuff that you like to see. So you can end up even though you're building your app without all of the native Objective-C Cocoa stuff you can end up having it feel like a genuine app. And really that's a tribute to the strides that Apple has made with the WebKit browser and it's great to have these toolkits so you can sort of quickly build this with the velocity that we expect to see from web application development. So I think I've been pretty speedy, what time is it? Excellent. So is everybody up for a quick demo? All right. So if we have internet connectivity it does show like three bars. I want to show you Row Hub because what I showed you just now was really quick in terms of building a mobile app but this is even quicker, my Row Hub account. So the neat thing about Row Hub is in addition to the generators that it's got a GUI for so we'll create an application here. And this is a hosted service by Row Mobile and if your app is open source then it's free and you can pay to have private apps. So we'll create an Acme Store app and we'll say that Roadrunner, it's not really Roadrunner who shops at the store it's Wiley Coyote shops here. Really, I miss that from, oh I'm not supposed to put the spaces there. I did watch that but maybe I just missed that little piece of the action. Okay, so we created the Acme Store and now I'm gonna create my model. So we'll make another product just in case I'm gonna make an Acme product. I don't know how many millions of products I can have on my little Row Hub account here. And just like I did in the generator I'm gonna give it a brand and a name in the quantity and I'll create that. And I think this is a, it's a little slower than it usually is. And this is, it has actually a hosted IDE and I could see all my code here. I can actually go right here and do a build right now. Maybe I'll build the whole app right now. Cheat sheet just in case. Oh no. We'll see how it goes. We'll talk about it while we wait for the network. So here it gives you all of the stuff that you would normally have in the web interface of your Roasting server that you might build. And I'll make the config change. And I'm gonna go right into changing the server. It reminds me that I don't have users subscribed. Help me remember to do that. Save the changes. And right here I can modify my source adapter. And I'm gonna write some query code. What was I gonna do? Oh, I want to, I've got a required JSON and I'm gonna use open URI. And I'm gonna open this store which is at, it's hosted at Heroku, go store.heroku.com and I know you can't read that. So I'll just read it aloud. And we'll go to products.json, I can barely read that. And then we'll do something with that. So I wanted to clear it up here so it's available outside of scope. Okay, so I'm parsing the JSON file which is coming in with my list of projects, products. What this query function is supposed to do, one query method is supposed to do is create an at result instance variable. So I'm gonna go through the parsed JSON and turn it into this other format which is just a couple lines of Ruby. So we're going to take the items from the product object. It has an ID and we're gonna use that as the hash key. And it needs to be a string and then we will assign the value which is really what I'm gonna do is just use all of the attributes that come back. But this is an opportunity if you wanted to, like sometimes you end up working with these soap APIs that have like this enormous amount of data that you don't want to go to your little tiny client. And so this is an opportunity for you to throw out the data that really is redundant or not necessary or not relevant to your mobile interface. And if I've typed that all right, we'll be able to check to see if it works. So I'll save it. And you have this little tester here where you can just show the records that came from your web service just on the server. So before you bother to build your client app. And I have a syntax error, too many closing brackets. Good call. Anything else? Does that look okay? All right, we'll see how that goes. I still have errors in my code. Oh, because I have another, I just got crazy with the brackets. No, I need that one. No, that one, this one. Oh, oh, the documents saved. All right, so now we'll check it. Oh, and I got records. Ooh, okay. So these, so these are the records that come from my web service. And now I can build the mobile app. It's a good thing we're like, you know, what would you call, you know, group programming here. Yes. All right, so now we'll see if we can. There's this new fancy thing. And there's one for Windows and one for Mac. And on the Mac, you can download this iPhone launcher, which is actually this little that runs on your Mac that will automatically launch and relaunch the iPhone simulator with what it's downloaded. So it just saves you the, you know, the extra steps of copy this, unload that, put that in there. And it turns out to save you a tremendous amount of time. So I just want to be by date modified just to make sure that I'm getting the right one. Well, it's one, two, three. And there's my app. And there are my equity products. Yay. And this you can use just as a starter and download the code and do it offline if you prefer to work in your own editor. And it's a great way to just, you know, get started on something. So, so now if anybody has questions. I didn't see it when you ran the ROGEN, but does this have facilities for testing? That's a really good question. As far as I know, nobody has done that yet. So, so that's something that I'm really interested in, but and it's theoretically doable, but it hasn't been done yet. Oh, wait, did we have a follow up comment? Oh, it's just going to say, Rowsync has a test framework that was actually contributed by a third party developer, Robin SP from Sweden. And so doing some form of TDD within roads on the client is now a priority. We'll get to that soon. So on server side, there's, you can do the test framework stuff, but on the client side it's still an innovation to be had. Yes? How well does it integrate with X-Codes? Like can you use the debugger and all the performance tools? So yeah, you can, I actually, before they had this iPhone launcher and ROHUB and all the rake tasks were all worked out, I would routinely work in X-Code. And one of the reasons I decided to spend time learning roads was that because it's all open source, it means that if there's some, if there's some iPhone specific facility that I wanted, I can just build in an objective C. Like I've done a lot of proprietary stuff where as soon as you get to, there's a bug or there's a feature missing and then you just hit a wall and you can't deliver what you wanna deliver or create what you wanna create. The neat thing about the whole thing being open source is, I mean it is more time consuming, but it's, it would be to build in an objective C in the first place. So you can dive in and it's documented how to do that. In the back. So how does this relate to Apple's license agreement for the iPhone that you're not allowed to have interpreted code? Well, Apple doesn't want you to download interpret code. So if you internal to your application happen to have some byte code that you're interpreting, that's not an issue. The issue is that Apple doesn't want you to sort of distributing applications and executing them in your application. Other questions? How would you get this to the iPhone store or the distributor, whatever is that possible? It's a real app. Like on my machine, I have the same, like I have that thing that Xcode built. And in fact, for code signing, you have to open up Xcode and put in your signature and that's actually, it's a straightforward thing. It's just there's a lot of little silly steps you have to go through, but it's the same steps you'd go through if you had built your own app natively. And the same goes for every platform. In fact, I should mention Vidal and I and Lee Lundrigan are working on a book. So I was actually inspired by Dave Chilinski's our spec book, which I found great value of when it was halfway done and really enjoyed reading and found that it had information that I couldn't find elsewhere. So we're working on a book and the four chapters are done that cover that cover most of Rhodes and the iPhone and the vision behind the book is that it covers the native development for each of these different platforms so that you can understand how it would be to develop it natively and that you have all in one place, all of the code signing connections that you have to go through. And then it'll cover how you would do the cross-platform stuff in Rhodes and then this other JavaScript-based framework called PhoneGap and some of the UI toolkits. So a little plug for our book. But it's up on the APRES site. So other questions? Yes? Has the APRES store any compliance about the code generated for the Rhodes gem? I mean, did you come up with your application with Rhodes in the APRES store? Yeah, there's a bunch of apps that are on the store. I mean, like the Wikipedia app, I think, what's his name? Hampton spoke about at sort of a little bit at Golden Gate Ruby Conference. He took, he made an app in Rhodes that he submitted to the app store and there's a whole bunch of apps on the app store. So it hasn't really been an issue for Rhodes. Yeah? Can you include other standard Ruby gems? Can you include other standard Ruby gems? Do your views in Hamptons in ERB? So, I think so. You can just include Ruby stuff. It's interesting that we offered that to Hampton and he said no, since it's all about being small and tight, he actually liked the fact that it was ERB. So he, and he could have added Hamptons. I mean, he just stayed with ERB for it. So I have helping me in the audience here. Adam from Rome Mobile. No, thank you, Adam. Raise your hand if anybody has questions about how Rhodes is built. You can bug him afterwards if you have questions about how to use it in the wild. Fadal and I have a lot of experience building apps. So I'm gonna pause there because I think I'm out of time. I wanna thank my helper, Fadal Grapera. We have a number of apps and phones here that you're welcome to come up and check out and feel free to come up afterwards if you have questions. Thanks.