 Hi, my name is Benjamin Stein, and I'm going to talk about mobile app development. So we're talking about is iPhone, Android, Palm Free, that sort of thing. And to give you a little bit of background about where this talk came from, I have a company called Mobile Commons, and what we do is a communication with text messaging and phone calls. And the thing about text and phone calls is it operates on the server side. So we don't do any client-side mobile development, which is an important distinction. Over the past few months, it's obviously been on a lot of our customers' minds, so people keep asking, what about iPhone? What about Android? So trying to figure out, basically, from a Rails developer's perspective, how to navigate this world and really how to work on mobile devices. And this is going to be very relevant. If it's not relevant to you yet, it absolutely will be. I mean, mobile is where we're going. A lot of this talk is relevant to web development. So it's not very specific to mobile. There's definitely a big mobile component, but there's also a lot of web development going on here. And also, just to clarify, I'm not talking about kind of legacy phones, Symbian or Windows Mobile or anything like that. It's really this kind of next generation of phone. The format of the talk, unfortunately, there's not going to be a lot of Ruby code. I think that's okay. There's going to be a lot of, I think, very relevant information, a lot to learn, and it's a very broad talk. So there's going to be a lot of content that I'm going to cover. And I'm also going to throw in a few parenthetical asides. So I have a bunch of slides of things that are tangentially interesting that I'm just going to throw out there. So why mobile? Why is mobile cool? I'm sure you all, you guys know this list, but I'm going to review them because it really is worth thinking about a lot of these things and realizing why is mobile different than web development? What can you actually do once you have a phone and that you can't do on your desktop or your laptop? So location is probably the coolest thing. GPS, however you're going to find location. Accelerometer and orientation. Your device knows where it is. It knows its position in space. The phone, the fact that it actually is a phone, right? Remember that a phone is the killer app for the phone. You can make phone calls, you can send text messages, and you have an address book. I mean, it sounds funny, but it's very true, right? You actually have a communications device multimodal with you. Almost every phone has a camera, so you have this ability to do multimedia and sound and vibrate. Sound and vibrate is much more than a gimmick because what it really means is you can push notifications to users, right? So whether you have a background process running that's polling or doing something that can then say, hey, buzz in my pocket, something is going on, or in the iPhone case you have a push server, suddenly you can interrupt a user, whatever they're doing, and you can send a notification to them. So this is actually a really big list, a whole lot of really new stuff that we really were never able to do in the web world. Actually, just curious, how many people here have built an Android or an iPhone client-side app? And of the people who have made one, how many have one in the App Store, like actually in production? So there's a handful. There's also some very uncool things about mobile. The first one is unreliable connectivity, right? So you want to kind of assume when you're building a web application that the person's gonna be online. With a phone, you really can't assume that. So you launch an application on your handset, you may or may not be online. Second thing is Java, right? I mean these are other languages that you have to be learned to do on the phone and things like memory management, right? As a Rails developer, as a web developer, you typically don't think about this sort of thing, right? Malik and free and release and reference counting and these just aren't tools that we're necessarily using on a daily basis, right? I mean actually the first time I wrote an iPhone app, I tried to install Monit to bounce my app every time that it used too much memory, as a joke. So let's review kind of some of the options, right? So you're a Rails programmer, you just released a really cool site for your customer and they say, oh yeah, also it should work on iPhone. You're like, what? So what are your choices, right? So your first obvious answer is, maybe your web app is good enough. When Steve Jobs first introduced the iPhone, he showed The New York Times and he said, hey, this is a real browser, this is Safari. You don't have to do anything special and that may be the answer and if that's the answer, that's great. A second very common approach is a mobile formatted version of the site, right? So you take the content that you already have on the web and you just serve it up differently for the different handsets and I'll talk a little bit more about that option. And then the third choice is making a client app for each platform and that also has some pros and cons that I'll touch on. So I'm gonna ignore the, you know, keep your app the way it is, right? Kind of boring. Let's talk a little bit about mobile formatted sites. So typically the way this is done is you're serving up an alternate style sheet, right? So you have your main Rails app that's being served up and you use, do some sort of user agent detection to say, hey, this is a mobile phone, I'm gonna serve up a different style sheet, I'm gonna format it for a small screen. Often this is done with a different subdomain. That's kind of a convenient way to do things so that your application logic can know, oh, I'm using the mobile subdomain, I should be serving up some sort of different content. And as a best practice, it's also nice to be able to let the user choose, oh, I wanna be seeing the mobile version, I wanna be seeing the real version and subdomains are a great way to manage that state. And if you're going down this path, something I'm sure you've come across is WERFL. So WERFL is the open source database for user agent detection. So it has literally thousands of strings that identify the phone associated with that user agent. So in the web world, you're used to dealing with a dozen common user agent strings. This really gives you the whole list of them and it tells you convenient things like the size of the screen and from there you can figure out your color depth and sort of complicated pieces there. What are the cons of this approach? Well, you don't get any of the cool mobile features. So the list of cool mobile things that I talked about, you don't get any of them. You're just serving up a web application. And there's no app store distribution. So you can typically, you could bookmark a web page that you visit on a handset. But if the trend continues as it is, I think these app stores are a really big deal. They give you a venue for getting paid and they give you discoverability. And we're seeing four or five of these big companies launching their own app stores. So I think app store distribution actually is quite important. Okay, my first parenthetical aside. If you're building a mobile, an iPhone specific site, no doubt you come across the IUI library. So IUI was written by Joe Hewitt, who's the guy who brought us All Firebug. And what IUI is is a set of style sheets and JavaScript that give your web app the iPhone look and field. Excuse me. So it loads up a page and you build your classes in a defined way. And that will load a lot of content, AJAXY, and it gives you the kind of menu in, drill back, iPhone typical look and feel. NoRapin has a Rails IUI plugin, which gives you a rake task to generate these JavaScript and CSS files in your project. And then a lot of really convenient methods like is this iPhone format? Is iPhone subdomain? And an iPhone controller method. You can also register a MIME type specific to iPhone. And then you can do a response to block in your controller that says, hey, if this is an iPhone, render this index.iPhone.ERV file. So just a quick parenthetical aside there. So let's talk about native apps quite quickly. So why are they good? Well, it's a rich user experience, right? You get access to all the cool device features. There's fantastic graphics on these devices. There's Zippy, there's good processors. So there's really some nice advantages to building a native app. And you have the App Store distribution. Here's kind of a screenshot of the Facebook native app. And going back two pages, you can see the Facebook mobile formatted website. So they look kind of similar. The native app definitely looks better, but you can sort of get the idea of what the difference is here. And what are the cons? Well, the big cons are that they're new technologies. They're new technologies. They're different technologies, right? So every platform has its own different programming language and there's frameworks to learn on top of the languages. And this actually is a big deal, right? Because it's like a practical problem that there's only so many hours in the day and we can only learn so much. So to actually become an expert in Objective-C, and in Java, and in the frameworks associated with them, all the while developing Ruby and Rails code, it's really just too much. Excuse me. So what I'd like to do is to propose an alternate technology stack. So this is a stack that could be used possibly for rapid prototyping. It could be used in production. Or it's just a theoretical and an interesting thing to talk about. So this is the core of the talk and where the real meat is. So what I'm going to propose is using WebKit as your view layer, right? So WebKit is the rendering engine that's in Safari. Excuse me. It's in Chrome and it's on both of the mobile devices and it's going to be on Palm Pre when that's released next week, I believe. And so what that gives you is HTML, CSS, JavaScript, that's your front end. Now take your business logic and instead of putting that into libraries that live on the client device, these can live in your web application, right? So whether that's a server-side application that's being, that's your Rails logic or a client-side application that has business logic and JavaScript, for example, that's where your core business logic lives and it lives in a realm that we all understand. Kind of the aha moment here was a library and there's a handful of different libraries that are kind of jockeying for position here, but a library that exposes all the cool mobile device features, accelerometer, location, the phone, through a JavaScript interface. So I'll talk about a couple different projects that give you this ability. But if you, and you can imagine, you now have a JavaScript interface and a common JavaScript interface to all the native features of the phone. And finally, HTML5. So HTML5 has been getting a lot of press over the past, like really, the past few weeks it's really been heating up. So I'm gonna talk a little bit about HTML5 spec, what's coming up with that and specifically client-side storage. So if you can do client-side storage, so actually have persistent storage on the device, access to all the features and serve it up with HTML, CSS and JavaScript, hey, this actually sounds pretty good. So all of this works and I'm gonna do, show you some code and some demos of this. And again, this can work all the way to production. There's some pros and some cons. Or, and the most important thing is this is rapid prototyping. This is what we as Ruby and Rails developers have been basically, this is what we do. We release early, we release often. We get things in the hands of users. And if you can whip together a web application in a very short amount of time and let people play with it, that's a big win. And I can promise you, if you think that your customers don't know what they want in their web app, they absolutely don't know what they want in their mobile app, right? So to ask them very simple questions like what happens when I turn it sideways or what happens if I'm not online. And these are just not things that people have thought through. And it's not a criticism, like these are really, really new things. So actually letting people try things out and touch it and say, oh wow, this actually is on my phone and is just a great way to get started. Okay, so continuing along with what this architecture is gonna look like, either you can serve up your application as static HTML that lives on the device. So imagine shipping an application, right? This is gonna be like an app store binary or something that you actually install on the phone. Contained in this application is the web view. So all it's gonna do is render your browser window and figure out what HTML to serve up. Now that HTML could be shipped right with that binary so it's self-contained or it can go out to your remote site, pull down content. And it can also be some sort of combination of the two, right? So maybe you pull down some content, maybe you serve up some content and we really are blurring lines here between native app, web app, online, offline. And you'll sort of see how this gets to be pretty cool. Any questions at this point or comments or anything? Okay, web kit. So real quick slide on web kit, open source browser, right? All of these phones use it, which is very, very nice. Suddenly this sea of cross browser compatibility that you need to deal with just goes away and web development actually becomes very, very pleasant again. And additionally, web kit really is pushing the boundaries of, excuse me, a lot of these technologies. So they're pushing out these nightly builds that are implementing some of the features of HTML5 before the spec is even finished. So it really is on the bleeding edge so you can get to play with some of this stuff today. This is what I came across when I first poured into the HTML spec last week. And it's absolutely true. Trying to get through it, it really is a kind of a mess. It's really, really cool stuff in there, but it's tough to navigate. It was first proposed six years ago. The working group started two years ago and things are starting to come together. So just a quick summary of some of the neat things that are coming up. Canvas. Canvas is a way to do vector graphics in your HTML. So if you think Yahoo Pipes, right? Yahoo Pipes has this really smooth interface where you can drag pipes around and kind of looks like flash, but you can't really tell and that's vector graphics in your HTML. The video tag, right? So just like you have an image tag today, you also, we're gonna have a video tag. For those of you who are bored, you can go to youtube.com.html5. It looks just like a normal YouTube page, but if you view the source, you'll see that all of the controls are just HTML elements and the video itself is a video tag, right? There's no flash player involved. Geolocation, right? So there's gonna be standards for Geo in your HTML. Web workers, that lets you do asynchronous JavaScript in a non-blocking way. So, right, as you know right now, if one of your pages starts spinning up this JavaScript process, everyone else is gonna be blocked. Client-side storage, client-side storage, which I just mentioned, and I'm gonna dive into it a little bit because it's actually very, very cool. Excuse me. So the next parenthetical aside is, doesn't this sound a lot like Google Gears? And it does, so what is Google Gears? It's a set of extensions for all the different browsers out there that essentially give you all this functionality. And this was Google saying a couple years ago, hey, we're not gonna wait for this spec. We need to get our apps done now. So we're gonna release this open-source framework for people to do all the things that are coming down the pipe, and most likely it's gonna be replaced by HTML5. So it remains to be seen, it's up in the air, but it seems to make sense that a lot of the functionality in Gears is going to be replaced by the standard. On the storage side, there are sort of three types of storage. This is kind of confusing when digging into the spec to figure out what is what. The first one is structured storage. And what this gives you is essentially a in-memory hash map for dealing with client-side, almost ephemeral data. The second thing is app cache for caching your application resources. And the third one is a proper transactional SQL database on the client side. So let's take a look at this first one. I don't know if this code is all readable, it's also not that important. So what this storage gives you, it's a way to just have information on the client that you can access cross browser window and cross tab. So the way we do a lot of things now is you put an ID in the cookie, and then for every bit of information, you go back to the server to get your session data. That's option A. Option B is you store something right inside the DOM. You store something in-memory local to that page. The problem is your other pages don't get access to that information. So this is a new part of the standard that will say, hey, we're gonna give you a new session storage and a local storage element in your DOM that all of your windows are gonna share at the same time. And it's a hash map, right? Get, delete. App cache. So this is the second type of client-side storage. And what this lets you do is define with a configuration file, what parts of your application can be completely cached. So they can be served up completely off of your browser's hard disk. There's a new attribute to the HTML tag, which is the manifest. And this manifest points to a file. And what this file says is these are the resources, HTML pages, images that can be served up directly from the disk. And you're right, this is much better than even doing a 304, not modified. You can imagine it's just, let's serve this up. And so the concept of, this is a sample manifest file, the concept of an offline web app suddenly makes a lot of sense. And you can also specify which resources should never be cached. So you can say this server CGI script, well you always have to go remote to get this data. Okay, real quick parenthetical aside, because I know you guys all wanna see some Ruby, Ruby characters are annotations. So this is a concept completely unrelated to programming that show pronunciation for Chinese or Japanese characters. And there's gonna be a Ruby tag in HTML that lets you specify these pronunciations right in line. So a little snippet of code right there. So I know you get some Ruby here. Okay, the third type of client-side storage is a database. So what they actually, what they have in the spec is a proper transactional SQL database that you can access from your browser. The implementation that exists right now is in WebKit. It's a SQL lite implementation of the database and there's a JavaScript API for it. It's an asynchronous API. So this is probably a programming model you've come across but it's not the same programming model that you're probably very used to in Rails. So the way it works is you specify your callbacks in your JavaScript methods. You call a method specifying callbacks and then when the method asynchronously runs, it then executes these callbacks. So you end up with kind of a different programming paradigm than maybe you're used to. But again, if you've been doing much JavaScript or any Ajax development where you specify the callback after the remote request comes back, you know exactly what I'm talking about. So if you guys can see this code at all, this is the interface copied right out of spec that defines what a database is supposed to look like. So there's an open method, open database method. You give it a name, a version and you get back an instance of a database object. This database object, it's an interface essentially and this interface has a method transaction. So this is a SQL transaction and you give it a SQL transaction callback and then a couple other optional callbacks for errors and success. So this is the, you're gonna see this repeated over and over again where you pass in an argument callback, a success callback and then an error callback. The SQL transaction gives you an execute SQL callback and this is where you specify your string, your SQL string and your parameterized arguments and then again the two success and error callbacks and you get back a result set. So what you get back is the number of rows affected and a collection of rows and these are the rows right out of your database and the number of rows that came back and then you can iterate over this collection and deal with your data. Again, all in JavaScript, all client side. So what does this look like in actual code? So here's just a bit of sample code. So let's imagine we have a my database object and we then call a transaction on that object. Going in a couple layers, you have your SQL right there. This is a SQLite syntax. It's actually a subset of SQLite syntax. So doing things like transactions and rollbacks is not supported within the SQL itself, right, that's kind of managed by the transaction object. You pass in your parameterized values and you get back a callback on success which is here all I'm gonna do is just send up an alert which says the number of rows that were returned. And let's actually take a look to see what this looks like. So if I can somehow get over to Safari. So this is Safari 3.2. This actually works right now on Safari. This is a local page. This is just a little sticky note application that the WebKit guys have as a demo. So we can make these sticky notes. Go, Ruko. And what's neat is this is just persisted. This is persisted on the client. If I refresh this page from scratch, everything I just did is right there. Move things around, refresh, it's all saved. And you can take a look at your somewhere, web inspector. If I can get this to fit on the screen. What you'll see is a new tab here that maybe you've never noticed before, databases. And this is a note test database, that's its name. And you can see the two different, the IDs, the notes, timestamp, and their position. So these values are stored right in the database client side. So, and if we refresh our view, you'll see, go, Ruko rules. So this was saved in the database. Okay, just a really very quick note on security and privacy, because client side storage brings up a bunch of concerns. And thankfully, we're 2009 and we realized that security needs to be thought about up front. Cookie Resurrection is something that suddenly made very easy. So you go into your browser, you clear all your cookies, you go back to the site. Wait a second, there's a whole another data store that this company or organization knows about me. They can just repopulate your cookie. And so if you imagine things like tracking cookies that watch you as you go across the web in these ad networks, and you know, actually this is kind of another vector for people to get data about you saved. So what the designers did is they enforced the same domain policy. So you all are familiar with this from the JavaScript world. You can't do cross domain scripting. In the same way, every database is stored as local to your domain. And that has some interesting ramifications with shared hosts, for example. So if you have a shared hosting environment, you really can't do client side storage because you can't segment things by path name. It's only by domain. So I think this is smart. Kind of remains to be seen how, if it will work and how well it will work. But this is the way the spec is defined. Okay, this is Gmail. Gmail released a new version, probably two or three weeks ago, for the iPhone and for Android. And it's really cool. So the way this works is you start Gmail, and you can do this when you're on the subway. It will load up the page right in the browser. It's not gonna give you a popup that says could not connect to the network. It will load up Gmail, and it will load your inbox. So it's gonna load all of the messages that it's seen before. And you get a little spinner, and all of your mail will asynchronously populate. And the way this works is there's the app cache, right? The resources that the application says don't need to be fetched every time it's loaded. So that will load up the main page, the CSS, and you actually get that really quickly zippy right there. Then all of the messages that you've downloaded are stored client side in your inbox table. And everything that you send goes into an outbox. This actually lets you build an outbound queue. So you can send a message while you're on the train. You come above ground, load this web app up again. It's gonna pop messages off of your outbound queue and send them to the server. And it's all HTML, JavaScript, and CSS. So this doesn't take advantage of some of the mobile features that I discussed, but as far as being a hybrid online offline application, I mean, this is pretty amazing. Okay, PhoneGap. PhoneGap is an open source project. It's kind of just the one I'm gonna talk about that gives you access to the phone features from JavaScript. There's a couple different competing libraries. You know, I'm not advocating one or the other. This is just the one that I've been using. Excuse me. And what it does is it gives you a native code. So Java code, objective C code, and it gives you essentially the framework of a project. So you download this from GitHub and you get a shell of a project. And then there's a folder for local resources and the configuration file that says, what URL should I load when I first come up? As you can see, they have a little table explaining what features of which devices are supported by the project so far. Blackberry is an interesting one. So Blackberry actually isn't supported well in sort of everything I'm talking about. Blackberry uses J2ME and has its own browser and it's not the same across all versions of Blackberry. So for the most part, it's kind of outside of this discussion, unfortunately. So this is just an example of what the interface looks like. So you get all the methods that you would expect, get current position, get current acceleration, beep. Just all the things that you would expect to happen, you get from JavaScript. And what's neat is it abstracts away the implementation. So this works on all the different platforms. Just kind of a laundry list of some other companies that are doing this sort of thing. Point about is a company down in DC. Liquid Gear, Big Five, these are just other developers that have similar type of ideas. So they have springboards and JavaScript interfaces to native phone features. Another quick parenthetical aside is XUI. So this is a JavaScript library that was inspired by jQuery. And what they did is they ripped out all of the parts of jQuery that make it browser independent. So if you imagine you don't need any of the IE6 gunk in jQuery, rip it all out and you optimize it for mobile, suddenly what you're left with is a very, very small framework, right? So this is a two and a half K when it's minified in GZip. So it's geared towards mobile development and it's optimized for WebKit. Okay, so finally we're gonna make an app. Someone have the time? So the app that I'm gonna make is a little bit inspired by our customer base. So we want people using the phone as a phone and calling their senators or calling their congressman. So what this application is gonna do is it's going to find your current location. So it'll find your lot long from GPS. It will then go out to a remote service to look up your legislator. It will show a link, like a telephone specific link to access the phone's phone and it's also gonna cache the content locally. So if you load it up again, you don't have to do that remote query again. And other than that one remote query, everything is designed to work locally. So you can do this when you're, let's say you have phone service, but no data service. Then everything in theory could work because you would have your cached legislator and you could use your phone. So just another very quick aside, how are we gonna get this data? Some of you have seen me talk about our legislative lookup tools that Mobile Commons has recently open sourced. And what this does, it's an open source Rails app and we have a hosted version that lets you pass in a lot long and get back specific legislative district information. I'm gonna use this for this app, but I also bring it up because one thing we're interested in doing is adding more and more data sources to it. So if any of you have gone on to data.gov, which kind of went live this week and are seeing some of the wealth of data that the government is starting to put out, if you have any interest or if any of your projects require any type of location information that you'd like hosted as an API, just let me know. It's a migration to get new data into the app. And I also wanted to mention before we get to coding, HTTP client. So if none of you learn anything from this talk at all, you should learn about this application. This is essentially an OS 10 GUI around Curl. So it is just a, it's an HTTP client and it gives you all the HTTP methods. So you don't have the silly browser restriction of being able to test your rest of web service only with get and post. It gives you syntax highlighting. You don't have to view source. It just gives you back XML or JSON code or whatever the server returned. It has basic auth. It's pre-populated with all the popular HTTP headers. You can spoof user agents and you can save it as a document. So if any of you are still using Curl to try to test these things and worrying about escaping things in the command line and remembering how to pass in your basic auth credentials, I highly recommend it. So let's see if I can find it. Okay, so this is an HTTP client window. The URL I'm gonna hit if you can't see it is the R-Legislative Lookup Tool. And I'm gonna pass in, you know, here's an XML format, send the request and what you get back is exactly what you'd expect. XML, I mean it's so simple that it just seems so obvious to do. But people are always viewing source. You have all of your HTTP methods so you can specify which ones you wanna do and you can add any HTTP headers, right? So you can pass in your content type to specify that you wanna get back a different content type and it comes pre-populated with all of the fields that you would expect. You can also do user agent spoofing which is extremely convenient for debugging your application. So it comes with all of the strings for popular browsers so you can do user agent spoofing as well. Okay, that advertisement aside, let's jump into some code. Code, okay. So what I'm gonna show you is the application that I just described that I was gonna make and I'm gonna show it in TextMate because see if we can see it, all it is is HTML and JavaScript. So, is that big enough? Should I go bigger? Bigger? Fortunately, there's not a lot of code to see here. Okay, so what we have here is the index HTML. Onload, it's gonna initialize our database and it's gonna find the most recent senator and a little disclaimer which is, this is not like the paradigm of JavaScript development. This is kind of done out explicitly so everyone can sort of see what's going on here. And looking at the body, basically here's an empty span where we're gonna stick our result and I'm gonna make a big button that says look up my location and my legislator and that's pretty much all of this web app does. I'm gonna show a little bit of JavaScript code here. So, this is the initialized database method. So, this is a JavaScript implementation of the interface that I showed from the spec. You know, it's really only one important line here which is open database which takes in the name, couple of other parameters and returns a database. And I'm just gonna save this variable as a global system DB variable for simplicity. Let's take a look at the Congress JavaScript. So, this is where all my application logic lives. And what this does, this method that I just defined, look up location and legislator, it uses the phone gap method, navigator, geolocation, get current position. So, it's remarkably simple, right? All this is just a JavaScript call and you pass in two callbacks, the success callback and that means is when we get the current position we're going to call this method for you and we're gonna pass in the lat long. And so, I specify that the method to call is look up. So, let's see what look up returns. So, I have the hard coded for now. The problem with doing this demo on the laptop is you don't actually have GPS on here so you don't get back, excuse me, accurate lat long. So, sometimes you'll find you'll be in the ocean and you won't get the right congressional district. But this is the lat long of pace. And what I'm gonna do is just append the JSON file from the congressional look up. And I'm just gonna pass in the lat long. I'm gonna specify the callback that should be called when the method returns. And that is display senator and cache district. So, this does exactly what you'd expect. It calls the display senator method and the cache district method. And it got back JSON from the web service. I don't think I have to go through this just displaying the senator. This is the first kind of very new code. This is the cache district method. What this does is it calls a SQL transaction. It's going to create the table if it doesn't exist and it's going to save the district name, the latitude and the longitude. Saving it all as characters, drop it right into the database, couple of error handlers here. And then it's going to do the insert. So, we'll insert into this district table the parameters values, name, latitude, longitude. So, it's SQL, it's exactly what you would expect. And here's some poorly wrapped code that finds the most recent senator. So, we're gonna do this right when the body loads up. And then I just want to illustrate a select, basically. So, we're going to go to the database. We're gonna issue a select. We're gonna get the most recent district and we're gonna display it. So, that is the crux of the code. I can show you what it looks like quickly in an Objective-C project, or an Xcode project, rather. So, Xcode is the development environment for doing things in iPhone. This, the code on the right, if that displays, is the Objective-C that instantiates a web UI view. So, if you've actually coded Objective-C or if you've just done any client-side programming, what we're doing is building a browser control and we're specifying what URL to load. And the URL that we're gonna load comes right out of a Plist file, and I'm gonna load it locally. So, I'm just gonna serve up local host iPhone index.html. And this www folder is the container for the files that I just made and I just showed you. So, this is the list of the files that are in there. So, let's hop over to our simulator somewhere and Icongress, my silly name, specify splash screen. And this is what we just saw. So, we've never looked at your sender before. We can't really run completely offline. Now, I remember this page was just served up out of the file system. We're gonna look at my legislator and what this is gonna do is pull down that JSON data, sorry, it's gonna look up your GPS coordinates, pull down the JSON data. This is the thing that we hard-coded. This look up to actually get the district really did go live, so that actually went onto a server just now and sent back a phone number. And it won't work in the simulator, but this uses a tel colon slash slash protocol. So, it actually will instantiate the phone and dial the number. And that's about it. It's remarkably simple. I can't get to the button to end the app. What I would wanna, so actually I have a little hack here to reload the page. So, reloading this page is going to show you the cache district, right? So, I could drop my network connection right now, leave the app, start the app again and it would have all the values right there. Actually, I think there's possibly a button, possibly not. Oh well. The next thing I wanna show you is Eclipse, right? So, Eclipse is the development environment for Android. Android is all done in Java and you can sort of see here, this is the place where we render the web view. So, the exact same paradigm is true here. We start a application and we point to a URL and we load it. So, this gets the URL right out of a config file somewhere. But the important thing to note is this assets folder. So, this is the exact same folder. It's actually just a sim link on the hard drive. It's the exact same assets in both places and the app will run on both devices. I'm gonna skip running the Android thing for now because I'm short on time, but you just run the simulator and you get the exact same app. Okay, jumping back to that presentation. Okay, so quick downsides to this approach. The apps really don't feel like native apps. They just have to be honest. It just isn't quite as zippy. The buttons just don't quite feel like iPhone controls. They may look like them, but it's just a little bit, not quite there. Now, that may or may not matter, right? If you're building something almost brochure-ware or something that's very, very simple, it might be good enough. If you're trying to do some sort of graphics or games or take advantage of any, like advanced hardware acceleration, it's not the right tool. And just a real quick note on app store policies. So there's been, getting things into the app stores is kind of a black art. And I've heard of apps getting rejected for using these frameworks. There are also dozens of apps that are in the app store that use this framework. So I can't really speak to that one way or the other. But if you start reading some of the mailing lists about phone gap and associated projects, this is kind of what's been going on is people bitching about not being able to get in the app store. So what's next? The spec, the HTML5 spec isn't finished. It looks like some of these features are getting quite close and the implementations are coming out. There's going to be a ton of work to do to get a lot of these new features into Rails, whether it's Rails core or whether these become plugins or I'm not sure how it's going to play out. And the team has actually been starting to implement some of the HTML5 features in Rails 3. So some of these things are starting to happen. But this gives us a year of NYCRB hackfests to work on of these new cool features. So that's all I had. I wanted to leave a few minutes at the end for questions. We're talking about the local databases. Those are actually being stored in the HTML files themselves so that they're persistent when you close and reopen them. The SQL databases are absolutely persistent. They're not stored in the browser. They're stored, I guess it's going to be platform specific where it's going to store in the file system. But you can navigate through and you can actually find your database. And what you can do is if you know where it needs to reside in the file system before the browser, you can make your own SQLite database on the command line, copy it over, do some funny renaming and suddenly it's pre-populated. Do you want to roll mobile and kind of compare some of these strategies? That is Ruby on the device. Okay, so that's something I probably should have kind of clarified right at the beginning is they're a handful of projects that aim to do something similar and different. So Rhodes is an example of a library that is an implementation of Ruby that runs on the phone. So in theory, you can package up a whole Ruby interpreter, ship it with an app onto the phone. Maybe that's awesome, right? I haven't really played with it much, but in theory that's very, very cool. And there's other people who are getting web servers running locally on the phone, so you could actually serve up content right out of the web server on the phone and ship it with the app. So there's obviously lots going on as far as development goes. I think I remember it was a JavaScript file when you were doing the app demo. There was a navigator, geo location code or something where you got the location code. Are you saying that was that another library that was being used or is that part of HTML5? So that is the, in this case it's the phone gap. The phone gap, okay. Right, so let's just give you the access to that object. What are the back? So it's phone gap like an application? So it is a, so it's on GitHub, right? You can clone it from GitHub. And what comes down is a template, a skeleton project for the different platforms. So you get an xproj file and you get a. You execute the JavaScript. Exactly, you call JavaScript and then what the phone gap project does is it does the mapping from your JavaScript to the native call. Is there any reason why Apple doesn't provide that like the native dash code as you say, something like that? Not that I know of, but I mean, there's a lot of things that Apple should be doing. Specifically putting Ruby on the phone. Speaking of, I have a couple of minutes to show a couple of real quick demos. One thing that I built, if I can actually get back to my home screen. Does anyone know how to do this? Home, oh, okay. So part of the Apple development environment has a tool called a dash code. And what dash code lets you do, it was originally made to make dashboard widgets. So it gives you a template for building really, really simple, kind of pretty widgets that are just HTML, CSS, JavaScript. And what I did is I took one of these dash code widgets in, I specified the URL of the RSS feed of my blog, took that HTML code, plopped it into a, the www, like the assets folder in phone gap. And in all of 10 minutes, I had a client side app that runs locally, goes out remotely and pulls down content right from my blog. And suddenly we have a, I mean this really took five minutes to make this application that you can then ship and put in the store and anything you want. Another quick, if I have another two more minutes, Francis, is the phone gap guys made a cool simulator. One of the problems with the Apple simulator is you don't get to do things like test the accelerometer. So what they have is an air application. So this is an Adobe air app. So this is the phone gap simulator. You can press the watch accelerometer button and then you get a debug panel. And what you can do is actually tilt the phone in space. And you can see, it's surprisingly responsive. This is about how well it behaves on the phone itself when you look at the XYZ coordinates changing. And you can make it beep, you can make it vibrate. They have an implementation of Firebug so you can actually try to do real time debugging of your HTML app inside the simulator. It's not quite there yet. And they have neat little demo games that kind of ship where you can sort of look at their code. And even if you don't use this library, looking at the code is actually a very instructive way to learn a bit about Objective C and the Android framework. And you can sort of see what they're doing. And it's a nice kind of digestible project that touches on every single feature of each of these phones. So I kind of recommend just digging through that code to learn a little bit. And this is a really fun game. Yeah, any more questions on this? It seems that if there were many applications that use this platform, the actual iPhone app is very much the same except for when you are out of the chamber. Exactly. So when you said when you said this, any HTML with your app, all you do is change the icon, the splash screen, and the URL. You change those three things, you're done. And now you have this up and running. And yet, if we all did that, we'd all have the same portal with Apple trying to get that very, very similar application on the app store. That's true. Again, this is not really a point I can really talk to you because it's gone both ways. Again, there are dozens of them out there that use this framework. And it's a total black magic. It depends on someone's mood. In the JavaScript we're using systemdb, I didn't see where that was initialized. Do you get to say what your database is referred to or what the local storage file name is or something? Sure, just to make it simple, what I did was just a global variable, systemdb, and somewhere right here. That is just the variable name. The actual database name in this case is iCongress, has a version. And you also specify your size. So you have to specify how big you think the database is going to be up front. And you can change the value, and it can be as big as you want, but for some reason you have to specify the number of bytes that come in. What would happen if there was schema changes? So that's, I guess I should mention it. The question is, how do you deal with schema changes? Excuse me, so there is no migration framework in place for this sort of thing. Maybe there's some attempts to make migrations on in Objective-C, I mean, there's nothing there, right? So it's a nice hack-fest thing to work on. But it's also a problem for regular Objective-C apps, right? This gets back to client-side development and why so many of us migrated to web app development in the first place. It's because shipping things to the client is hard. You can't release updates all the time, and you can't do migrations in the middle of the night, right? So you have to figure out some way to change your data on the client side. But it's all theoretically possible. You can do all versions of the status and all of all of them. It doesn't do a lot of work to manage it on the client side. Absolutely, right? So, I mean, that's actually how I did it. Just playing around was if you want a pre-populated database, you can just write a JavaScript file that will load only the first time you run it. You show a little spinner, it runs your migrations, never loads again. So, I mean, it's a Cluj, but it actually works. Cool, so thank you all very much.