 As Marc said, I'm very happy about this conference. I'm really happy to see you guys and that you guys could make it. I'm really not a very good speaker, but I will try to do my best. And sorry for my French accent. So yeah, so this is going to be a one hour keynote about the state of Ruby Motion, basically the past, the present, and the future. So if we look at Ruby Motion yesterday in the past, it was about two years ago when I started the project. Actually, I was working for a company here in the barrier that makes fruits, or I was working for Apple. And I decided to leave the company to do my own thing. And because I couldn't stay in America, I had to go back to my home country, my home country of Belgium. And when I think about Belgium, I think about this. This is the best picture I have in mind for Belgium. It's actually a beer. It's pretty the best beer, I think. And I think Marc would probably agree with me or not. Disagree? Anyway, I worked for about eight months on Ruby Motion. And I think it was in May 2012. I think it was the fourth May. We actually shipped it. And I was very surprised about all the interest that this project received. I really didn't expect that. I thought it would be a failure, actually. So I was extremely excited. And I think that was the first day we released it. We had this huge article on ARS Technica, which gave us a lot of attention. And then it started growing very fast. And today, Ruby Motion is really not what it used to be two years ago. First, I'm not the only one working on Ruby Motion anymore. That's a good thing because we can get more releases and more backfaces. And actually, we are five people. We are actually three people full time and two people part time. So the two guys that you saw just a few seconds ago were our full time people. Eloy is working from Amsterdam, actually on a boat. He lives on a boat, which is great, right? He's actually building a new boat. So he's really a boat person. That's what I can say about Eloy. She's also known as Watson, lives near Tokyo, Japan. And Watson is like our bug fixer. He fixes bugs when we sleep. So this is great. If you wake up and you can see bugs fixed. And I work from Belgium, but I just drink beer and eat waffles all the day. So I don't really do stuff. And then we have two part time guys. We have Colin, of course, who's going to speak later today or tomorrow. I don't know today, right? And Colin is our community manager. He maintains the Google group. He does all the interviews on our blog. And Colin lives in Denver, Colorado. So I must excuse if I didn't put the pin correctly. I'm not really good at geography. I think Colorado should be right there. And finally, we have a French guy who lives in Exxon-Provence. And you know what? Because of the stress, I forgot his name. Geoffrey, Geoffrey, man. That's going to be tough. He's going to hurt me. Geoffrey is very lucky to live in the south of France. And he helps us with support. Anyway, we are actually doing very well. And a lot of people are always afraid that it's a startup and we don't have VC money. We actually bootstrap 100%. And we didn't take investors' money. And we're actually doing well. Oh, and I can't really tell you how much money we make. But I can show you this graph that I made a few days ago. And I can give you the actual numbers. But we are doing actually very well. And we don't really need investors' money. At this point, I also manage the company very conservatively. So we are doing great. And we have a lot of cash in the bank also. So if there is anything that could happen, we could actually maintain ruby motion for at least a few more years. And actually, I'm very excited that ruby motion is used by a lot of people actually today. And I would like to show you a few of these guys. And first, we have Djokely. And Djokely is a very nice application that you can use with your friends to find concerts. They first launched in New York City. I know they are available in most cities in America. And it's actually great. It's very well-polished. The design is awesome. And it's all written in ruby motion. And Colleen here is actually working for Djokely. It's his main job. So this is very nice. And Jimdo is also one of our other success stories. It's actually some sort of an application to make websites. It's from Germany. But it is extremely popular. And their iPhone and iPad app is written in ruby motion. And I just discovered recently that Julian Anderson, the actress, is using the application. And she's what I really like here. I was a big fan of the X file. So this is big for me. Bandcamp is also another great success story. It's an app that actually is basically some sort of a network of independent artists where they can publish their music. And their iPhone app is all written in ruby motion. And it is actually a very interesting app. You can stream music right away. And they actually put the music in the background if you actually shut your phone off and start it again. So it's all written in ruby motion. And they make very nice, very interesting things with all the APIs of iOS. Oh, we also have Frontback. Frontback is a very popular app. Basically, you take a picture of you and then what you see. And they make a picture with both pictures. And they have a social network base on it. It's actually very, very popular. I think my wife uses it without even knowing that it's written in ruby motion. It's pretty big. And oh, a little bird told me that they just got over 1 million downloads. So it's pretty the largest ruby motion installation. Oh, and finally, we have a dark room. It's like a text-based action game, more or less probably more like an adventure game. And it was usually a web app. And a guy named Amir Rajan decided to port it to iOS, to the iPhone. And so don't really look over the graphics because they're all text-based. And it's all buttons and text fields. But the game is extremely addictive. And it went, actually, I think it was a few weeks ago. It was the number one paid app on the US App Store. So the entire US App Store, including all the apps, including apps from Apple, a dark room was over that. It was the number one. I think it stayed at for 15 days. So this is extremely addictive. And I never played because I don't have time for that. I know that I'm a weak person. But my wife actually played for a few weeks. And she said that it was extremely addictive. And anyway, today we have this conference. And I'm really excited about that because there is no way I could have told you that we would have a conference in San Francisco two years ago. If you could go back in time with the time machine and tell my past self that we would do that, I would ask you what you are smoking. And if you still have some, for me, it's like a big achievement. Anyway, we are not here for that. We're here for tomorrow. And I would like to show you what tomorrow will be for Ruby Motion. So it's going to look like this. So as you can see, the future is flat. So here we go. On the left side, you have the old Ruby Motion logo. Well, not the old. The current one. And on the right, you have the new one. So I would like you to take a few seconds to actually look really and convince yourself that the logo on the right is the best, right? It took me some time to get over it. I didn't design it, of course, but it took me some time and now I'm pretty confident it's the best logo. So we have this nice typeface also, a nice font that goes with the logo. It looks good, I think. And anyway, the future is really about Ruby Motion 3.0. And today, we would like to show you a sneak peek of Ruby Motion 3.0. And we would like to show you three features. You see Ruby Motion 3, three features? They might be more features in Ruby Motion 3, but today we'd like to show you three of them. And the future number one is performance. And for that, I would like to welcome Shizuo on stage. Watson. Hi, good morning. I'm Shizuo Fujita. Call me Watosun. I'm very happy to see all of you today. Thank you for coming. The first feature, we've changed many Ruby Motion internal for performances. So the subject in my section is improvement to Ruby Motion performance. Okay, let's begin. The first, I handle two topics in my section. The first topic, I'll show you performance measuring tool. I created two gems for measuring performance. These are Motion Benchmark and Motion Benchmark IPS. These were created for CRuby, MRI, with other also. I just repackaged these library for Ruby Motion. So, Motion Benchmark and Motion Benchmark IPS have methods which are compatible with original libraries. Okay. Motion Benchmark can measure the time of executing the method for processing. The time will be displayed on terminal, like this picture. Very useful. And Motion Benchmark IPS can measure how many times it executes the method per second, like this picture. I measured Ruby Motion performance using these libraries. Okay. Next, second topic. I'll show you how much we've improved Ruby Motion performance. First, Method Dispatch. Method Dispatch is about the time of method calling. It means booting time of method. This is a simple call in this slide. If you select one method, which have simple content like this call. You can measure the performance of Method Dispatch. Method Dispatch is now 1.8 times faster. This performance influences almost all Ruby and Objectivity method calling. So, this performance is important. Okay, next. This is Raterals syntax for range object. Range object will be created 2.2 times faster than Ruby Motion 2.0 using Raterals syntax. Great performance. Okay, next. This is Raterals syntax for string object. String object will be created 1.6 times faster. Great. And this is string interpolation calls. It is 1.8 times faster. Raterals and interpolation are very basic syntax and very important because I think everyone using these syntax so many, many times. So, very important. Okay, next. This is string concatenation using string plus method. It is 1.8 times faster. This is an array concatenation. It is 1.5 times faster. We have improved many, many performance. Unfortunately, I can show you all of the performance in my section. So, in here, I picked up some performance in this table. Okay. I'm sure you can find Ruby Motion has great performance now. So, I will publish a table in online for more detail. Okay. Now, Ruby Motion has great performance and 2.0. And we will continue to improvement in Ruby Motion performance. If you find slow performance, please tell us, we will fix it. Thank you. I would like to point out that this is the first time Watson gives a presentation in English. So, I think he did a great job. And so, for feature number two, I would like to welcome Eloy on stage. Good morning, everybody. I'm glad to be here and I'm glad to see you all and I would like to talk to you all later on. Hopefully, all. So, for my section, we are going to talk about the Rappel, probably one of the Ruby's best friends. And while Ruby Motion is probably, has been the leader of the pack in the Objective C developer tool arena, with regards to a Rappel. We have a feature such as a view selection. It has always been just that. One code line evaluation. So, it's great to try out something, but if you have tried it out and you want to back to your code base, you have to remember to either copy paste it and well, I mean, it's annoying, you'll get all the extra syntax as well. So, it's great to try out APIs to query the current state of your application, but arguably we need something better for your application development process. Because, well, yeah, this is so last week, a simple Rappel. So, we need something better. Enter real code base reloading. With this in place, it will finally be possible to develop your application without having to quit, recompile, and relaunch your application. Just as Epic get intended. Okay, so before we get into the details, let's speak, let the demo speak a thousand words. Okay, so, since everybody works on timer applications, it's probably a good way to show it. This is one of the demo applications that comes with the Ruby sample code repository. And here I've already launched it. It's running, and here is the code for it. So, while it's running, I figured that white and blue, it's just too conformant. So, what we can do, for instance, is change some colors, flip the frames, change some colors, just save, and there you go. Oh, it's purple, but apparently not that much, that visible, so let's change that back to white in this case. There you go. Okay, so that's that. But, I mean, this is not a typical Ruby application, right, a room motion application. We're running on the project to see runtime, and there's many run loop sources going on at the same time, probably. In this case, we're going to show that by a simple NS timer, but in your case, that could be delegates coming in from, I don't know, maybe a web view, or, oh no, you don't have that on iOS, but any other type, of course. So, for instance, let's start the timer. Oh, something happened. Let's go to the terminal, and the terminal's too large. Right, so, a message was sent, timer thread, that has to be timer fired. So, because obviously, I'm a developer, and I make mistakes all the time. I just say that now to make you feel good. So, I misspelled it here. What would happen normally at runtime if this came in from a run loop source is that your application would just crash. On iOS, on the main thread, run loop, raising an exception means crash. On OS 10, it's slightly different, arguably more annoying, but this is what would happen. So, what we do is, because this is something that you will run into, is we catch all those, and in this case, it asks you, would you like to redirect this message so that I can just keep on working, or would you just like to ignore it? In this case, let's redirect it to timer fired. I'm just gonna hit enter, I don't know, it's not on the screen right now. And there it goes, it will just redirect to the right place. Okay, clearly I need to fix the UI there. Anyway, so that's running, that's nice, but now that I, let's say I changed something else, and I save again, you see it jumps back, right? Because in this case, it's getting reset in the view will appear method, but the timer is still running, and that might not be what you want. So clearly, we're doing the naive thing, we're just calling your view will appear, which will work in most cases for just the simple stuff, but if you need more, what we actually do is we define a method on all UI view controllers called remote and did reload source, and this will be called on your view controllers, and you get to do whatever custom resetting or ever you need to be able to get the best feedback loop. So if we save this, then it should just reset back to initial state, and yeah, that's pretty much the demo for, well, I mean, it's pretty clear that this should be able to get you, your application developed pretty quickly. Let's do the dance again. All right, so just a bit more on the details. Traditionally, this is what in Roo Emotion 2, this is what happened, right? So the tool chain, you hit the build command, the compiler will compile all of your source, it will tell the sim tool to launch your application, and it will set up the REPL, but that's that. So now what happens is that the sim tool will start watching all of your project files, including resource files and what have you, and any time it detects a change to any of those files, it will tell the compiler to recompile it on the fly and the sim tool will inject it into your application again. And like I showed before, that's, the arrow should have been a bit more to the left, Laurent. I guess your OCD wanted it in the center of the big thing. Yeah, right, so obviously just injecting is not enough because the application will be running and you will need some kind of way to reflect the state as you want it, so you get the Roo Emotion Did Reload source message send, and by default, that message will be implemented on all your view controllers and it will call view will appear and view did appear, which may or may not be enough for your controller. You may override it completely or call super and it receives the file names of the files that were loaded if you need to perform some reflection on that to see if that's the view controller that you want to actually work on. So to conclude, there are definitely still some corner cases, for instance, with OS X applications, some people like to develop their OS X application in running inside a sandbox, obviously, test that it will work as intended, but that means that you're not allowed to make any file system changes inside the resources directory of the application bundle, so we'll probably have to add some runtime patching of methods such as an image named, so that it actually also looks in one of the directories where it is allowed to make changes, but we expect those types of issues to be ironed out during the next month, where we'll work together with people working on real applications and give them the opportunity to give us feedback. Well, that's it. Back tomorrow. Thank you, Eloy. Okay, I know I'm going to show you the last feature that we want to show you today. And the feature number three is a new platform. I will try to speak in a microphone. All right. So the new platform, we actually thought a lot and we got a lot of feedback from you guys and we decided to implement BlackBerry support. Because BlackBerry has this huge market share and I think pretty much 90% of our customers ask for BlackBerry support. So here we go. We'll be motioned for BlackBerry. I'm not joking, by the way. No, I'm joking. Okay. So can you guess what the new platform is? Android. It's okay, it's okay. So why did we actually port to be motioned to Android? Because we already have iOS, right? Well, the reason is that Android has a much bigger market share. There are lots of people who really want to do Android applications. So I took these numbers from Google yesterday. I typed Android market share and I found these numbers. So I'm not sure if they're correct, but clearly Android is winning in a way. And this is for the smartphones and this is for the tablets. And in 2012, apparently according to this website, iOS was as a bigger market share over Android. But now it's different. iOS is shrinking, Android is growing. And this is the number from last year. So maybe this year it's gonna be different. But clearly, there is some interest in writing applications for Android. And right now you have to write applications in Java using Eclipse and writing XML files. You see where I'm coming. So and with RubyMotion 3.0, you can finally write full-fledged Android apps in Ruby. So you don't have to use Java. Okay, so this is Hello World in Java. So it's actually not that bad. I think it's better than Objective C, honestly. But so we create an activity, which is a class in the list from Android App Activity. We have this method on create that you have to overwrite to actually customize the user interface. And here we actually create a text view. We set the text property of the text view to Hello World. And then we assign the text view as the content view of the activity. All right, this is a very simple Hello World. You can actually shrink the constant lookups in Java by importing the packages. But here I wanted to make it as short as possible. And this is the same in RubyMotion. And this is, no, Java, Ruby, Java, Ruby. So actually, as you can see, you can type text equal instead of set text, the same as in iOS. And you can just create classes and inherit it from Android classes, Java classes, exactly as in iOS, like you would inherit from Objective C classes. What's else? Yeah, you can build a literal string here, Hello World, and pass it to Android, and it works. Just like in iOS, Reversion for iOS, or an OS then. But anyway, I'm going to show you very quickly how it works. So of course, you get to use a simple command line interface, actually the exact same command line interface that you use to build iPhone and iPad and Mac apps. So to create a new project, you type motion create dash dash template Android, then the name of the project is going to create a directory with a bunch of files in it. So it will be exactly the same, it's exactly the same as if you already use RubyMotion, honestly, same experience. So we have a reg file by default, and in the reg file, we have a bunch of tasks already, pretty fine. So obviously the default task is going to compile the application and run it in the Android emulator, right here. But it takes a lot of time, like you don't even imagine, like honestly, you need to be very patient if you want to use the Android emulator. So we really recommend to run on the device. If you have an Android device, you just plug it, and actually you don't need to do anything, you don't need to get a certificate or a provisioning profile. Android is awesome. So you just plug it and type regdevice. Honestly, that's all you have to do. Oh, I'm sorry, you have to enable debugging on the device. So that's just a three step, but it's very easy. Yeah, Android is very easy for developers. So you type regdevice, and then it starts on the device. Here it's Nexus 7, it's my main Android machine. But it works on, we actually tried on Samsung phones, and there's a reason why it wouldn't work as well. And it runs right away. It actually installs the application, then it runs, it starts the main intent of your activity. I'm trying to get into Android programming, but I think that's what it does. And then you actually, it starts logging messages, and all the messages logged by the application will actually be in your terminal. So once you're ready, and you want to ship your Android app to the world, you can type, break, release. It's going to build the application. But then at one point, it's going to ask for the code signing key store that should be used to actually code sign the APK. And for that, you actually need to generate a key store file yourself. But the great thing is that you don't have to add to do that with Google. You can generate the key store on your machine, and then save it somewhere. They're probably on a safe place, and then just use it. So you don't have to get the certificate from Google either. So it's actually very easy. And once you do that, you type the password, and then you get an APK file that you can just give to people or give to Google. And for a hello world, this is what you get. So it's about half a megabyte. We actually work a lot to get it. Someone is calling you, Colin. I'm not going to take the call, right? Okay, let's keep on. So you actually get an APK file. An APK file is more or less a zip archive. But here, as you can see, it's half a megabyte, which is great. There is actually a limit on the IPK size. I'm a bit stressed out, so I don't remember. I think it's 10 megabyte or 15 megabyte. And if you go over that, you need to ask Google permission to have virtual disks attach to your application. So it's kind of weird. But here it's half a megabyte by default. So if you start adding code, it should actually not grow that fast. All the big files will actually be resource files. So it's great. There are actually many platforms that do Android development by default. You have a five megabyte application. So this is very important. And obviously, you keep to use your favorite editor. That's one of the main interests of RubyMotion, right? So if you really don't like Xcode and you try to use Eclipse, you're gonna have a bad time. It's way worse than Xcode, you see? X, compared to, Eclipse compared to Xcode is like, I don't know, it's like hell and something before hell, I'm not sure. So I actually to show you how bad Eclipse is. Two days ago, I opened an Android project that I created a few months ago. I just used Eclipse and did open project and this is what I got. And I have all this red stuff in front of each line and I have no idea how to think that I tried and it says, I can't find the package. And they say, okay. And it's really, really weird. Honestly, I have no idea how Eclipse works. Maybe I'm pretty stupid about Eclipse. I know people are actually like it, but it's really hard. It's also very slow. So obviously, I prefer to use Vim to write apps. And you can use any text editor which will be motion for Android. And actually, if your editor supports CTAX, you will have auto-completion or Java APIs. And I have only tried it with Vim because I think everyone should be using Vim, but if you have enough memory on your computer, you can try Emacs. I don't have enough memory on my machine. I have only four gigabytes, so I can try Emacs. But on Vim, it actually works nice. And this is just that, oh, this is the timer app. It's written 400, so I'm going to show it to you after. And one of the things also great with remote motion for Android is that you don't have to write XML files. If you have done a little bit of Android programming, it's all about XML. Like, it's an XML file for the project, XML file for the resources, XML file for the strings. It's like insanely in XML, like you live in XML. And here, you can actually write the user interface in code, so no need to use XML files for layouts. The project file is actually a rake file, so you need to use XML files for the Android manifest. The Android manifest is generated for you. So the idea is really to not use XML and just use Ruby and your favorite editor. Thank you. But this said, if you want to use XML, you can. There is nothing that prevents you. So in Ruby Emotion Project, Ruby Emotion for Android Project, there is a resource directory where you have all these application-level resource files, and you can create, I think, it's a string sub-directory and put your XML files there, and you can create a layout sub-directory and put your layout XML files there. So you can do the same thing as Google recommends you, but honestly, we recommend to do that in code. A little bit like for iOS and OS X, we don't recommend to use interface builder. It's the same here. And the great thing is that we can finally share code between iOS, OS X and Android, because it all uses the same language, Ruby. So obviously, if you write an iPhone app and an Android app, the user interface is going to be platform-specific so that would be this very specific code that you write for, for example, Android activities and UIV controllers. But the rest of the code, the backend code, is actually portable. There is nothing iOS about it. And you can just, if your architecture project well enough, you can share code between all these three platforms. And I think this is going to be a very big deal. And now let's try a demo. And I'm going to pray the gods because this is very hard. Okay. Now what? I think I'm going to mirror all the display. It's gonna be better. You got a message. Okay, it's much better. So let's go here. Can you read the font? I'm gonna make it a bit bigger. Okay, so let's go on TMP and create a new Android project. And it creates a bunch of files. So I can get to arrow and I can type regdevice. And here I actually have a Colin's phone connected to my computer. So if I type regdevice, oh, I forgot. That's a good thing. Because I need to set the reg file. I need to point the reg file to the Android SDK and SDK. So this is only because I use this very early version of RubyMotion. In the future, when you install it, you will provide it at installation time. And then it's all good for your project. So yeah, I just have to provide the SDK pass and the SDK pass. Anyway, I do that, type regdevice. It builds my application. It signs it. It installs it on the Colin's machine and here we go. It's only right here, but actually, I can show it here. Here we go. Can you see that? Okay, here we are using a BBQ screen, barbecue screen, I guess. It's like an Android app that you can use to project the content of your Android device on your Mac. So we use it as some sort of an emulator because the emulator is so slow and here it's fast. So I'm gonna put the device here. So yeah, by default, you have just a low and a black screen. So I'm gonna type something there. So if I do control C, it quits the application. Now I can edit it. And so by default, you can see we have our main activity and we have our own create method, but we do simply nothing, we just call super. And now I'm going to do something. I'm going to create a text view. And each widget that you create in Android, you have to provide a reference to the activity. I think it's called a bundle. Honestly, I'm learning on Android the hard way, so then you can set the text property to something and I will say, hello. Okay, oops, let's close the string. Then I can type serve.contentView, assign it to my label. And we should be good to go. So I can go back here and type regdevice. We don't have code reloading yet for Android while working on it. It starts the app and it's actually not connected. You see, that's the demo code in action. It's actually, the message is actually on the screen, but it's a program with the Android app to project it on the Mac. Oh, now it's working. Okay. Okay, so we just had to reset the app. So I'm going to start it again, like here. Okay, here we go. Can see the message here? Hello, one, one, one. So it's actually working. And actually, again, if you want, I can go there. How do you actually, how do you actually kill an application in Android? I mean, on all the home button. Okay, oh, no, I don't want to take a picture. I think Android is great for developers, but for users, it's, you know what? I'm not going to show you that because I'm afraid it will break the demo. But anyway, yeah, RubyMotion for Android app, they start as fast as Java apps. There is no thing required. Of course, you expect that, but if you have tried to use a Roboto, which is a Ruby for Android, you might see it takes like five seconds to bootstrap. And here it's just as fast as Java apps. So now I would like to show you other, a few other samples that I've been working on. Okay, so here we have our hello, a very basic hello application. You can type break device to shoot to you. And this is the same hello sample that we have for iOS. So it shows hello, RubyMotion, then you can click, right? And if you drag, it say, oh my God, I need, just sure, okay, very simple. And I'm going to show you the source code. We have just one file for this sample. Here we create our text. We actually set a bigger text size. It's because I use an Android Nexus 7 at home, which is a tablet. So I need a bigger font. And here on Colin's phone, it looks bigger. So, yeah, you have a lot of resolution screens in Android. So you need to actually, it's not as easy as in iOS, I think. You need to make sure that you don't build your eyes that are really, that are optimized for all the platforms that you target. But anyway, here I have this method, dispatch touch event, which is another method of the activity class that you can overwrite. And then you get callbacks when the user actually touches the main content view of your activity. And here I actually check if it's action hop, which means that we actually hop the finger from a touch event. I can just increase the counter, set the text. And what do I do here? I set the background color to black. I ask because if we actually move, I set the text to, oh my God. Here I actually set the text to a completely random color. So as you can see, the rant method is actually implemented for notion 400. Anyway, that's a very simple app. I'm gonna show you a few more. Or the paint went, oh, maybe the timer. Yeah, let's do for the timer. Boom, here I have a timer up. And I can actually click here and start. Stop, start, stop, wow. Now you can make, now you can make money. Oh, no, no, no, keep it that way. So yeah, timer up, very simple. Let's see the source code quickly. I have a button listener, which is some sort of a special class that we actually, that you actually pass to a button and that will be used. The onclick method of this class will actually be called when the button is tapped. Anyway, then I have a timer task, which is an object that you pass to an Android timer. And here the run method will be called. Anyway, here I have my main activity. I have my label somewhere on screen. Then I have my button somewhere on screen. And here I actually use an Android widget linear layout. Which is in Android, you can actually build using interfaces based on layouts. And you have vertical layouts, horizontal layouts, grid layouts. So it's very similar to Java something, Java Swing, Java Swing, I think. Yeah, I done some Java programming at school. It was AWS abstract window toolkit. Yeah, they actually take the same, I think it's very similar. So, and this is actually something I like because in iOS, you don't have that. You have to build your own packing view. Well, now you have auto layout, but this is actually very nice. So here you can build your, I actually have a vertical layout view and then I have two views that are packed vertically. I have my label and my button. And here I set the gravity to center horizontal which means that the view will be centered horizontally. Anyway, simple, I have a button that toggles my timer. Here I start my timer. Anyway, that's very simple. Oh, there is one thing that's actually interesting that I wanted to point to. Here at the beginning, I create an Android OS handler object. The reason is that if you use Android timers, your callback may actually be called from another thread, not the main thread. And if you want in this callback to change the user interface here, I actually want to set a new value for my label. I want to increase the timer. I have to do that from the main thread. So what I do here is that here, when the on create meta is called, I know it's the main thread. So I create my Android OS handler object and I store it in an instance variable. Then here, here when my timer runs, I actually use the post method and I pass a block and I know that this block will actually be executed inside the main thread. So you can actually see Android underers a little bit like GCD. They are not really the same but they can actually send tasks from one thread to the other. And what's great is that normally you're supposed to pass an object that implements the renewable interface but in remote motion for Android, procs implement renewable. So you can just pass a proc here. So this is nice, right? You can just do the lambda funky syntax and you cannot do that in Java. You have to create an anonymous class and this is insane. Anyway, simple app, let's see. Or the paint one is funny. I'm just going to show you, I'm not going to show you the source code for this one but it's a simple app and you can start drawing lines and each line has a different color. Then you have a clear button here that removes the screen. Actually, I can just show you quickly, yeah. We have our own touch event here. Actually, this one is the big deal. The underer method on the very, here we actually subclass Android view view. Android view is a package and view is the class in the package. So here in Ruby version for Android, you need to provide the whole thing. Android view view, that's made some weird but that's the way it is. You overwrite on draw and then you can, here we draw on the canvas all the passes that we have to generate when the on touch event method is called. And before showing the final one, I'm going to show you this one. Web view demo is a nice sample that shows you that how you can integrate a web view inside an Android app and then provide and expose a Ruby objects that web view. So here I have my SQL, this is a web view. This is HTML and CSS and JavaScript. And here if I click the, click me, I think it's a element, you click. And as you can see, I have a message here from the terminal. The message is actually printed the terminal then routed back to my Mac. And if I show you the source code, let's see, here we create a web view. Then we actually specify here the demo JavaScript interface as for the web view. And demo JavaScript interface is actually right here. And it has this click on Android method. And this method will go from JavaScript. And the thing is that since Android API level 18, which I think is KitKat, or I don't know, you have to provide a special annotation to the methods that would be called from JavaScript. This is for security reasons. Actually before API level 14, all the methods were exposed to JavaScript and there were huge security vulnerabilities like Android was very insecure. And then Google changes mine and you need to provide an annotation. And so in Java, you can actually provide annotations to a lot of things, at least methods and classes, pretty more. And annotations in Java are just objects. So here we actually extend the compiler, the remote and compiler that, so that you can actually provide annotations. And here I provide the Android, WebKit, JavaScript interface annotation to my click on Android method. And if I show you the assets file, I actually have my demo HTML. And here, here as you can see, I, when you click the, when you actually hit the A HTML element, I'm sure it's called, it's going to call a click on Android. And it's going to call our Ruby method, which is great, right? I don't know. Anyway, and finally, I'm going to show you a funny app that I wrote actually a few days ago. It's called conference and it's actually an application for this conference. So it's a schedule application. It's really not as good as the iPhone version because I'm bad at design and I also learning Android the hard way. But basically here we have a list view. It's actually a custom, it's actually a list view with a custom adapter. The adapter is what provides the data and look and feel for each row. So here we have a custom one because we have, as you can see, we have the time for each session, which is centered vertically, then on the right we have the title and then a description of the speakers. Oh, and the schedule is not up to date, by the way. We made last adjustments yesterday, so don't read it too much. But we have a list here. And here we have this menu, this drawer. And this drawer actually is, this is not code that comes from with Android SDK. It's actually code written by Google inside what they call an extra package. So this extra library, this GAR, this jar, it ships with Android, but it's not part of the built-in Android APIs. So here if you want to use it, you need to vendor it. So in Ruby Motion for Android you can actually vendor third-party Java libraries. And here we actually vendor this tiny library written by Google who's not part of Android. So it works exactly as you would expect in Java. So I can see the day two, I can see the venue, and this is actually interesting. It actually shows the venue in Google Maps. And believe me, it took me a day to do that because you don't have a map view in Android by default. You need to use the Google Play Services library. So it's a third-party library written by Google. So you need to vendor it, then you need to initialize all the map view stuff. You need to configure Android Manifest file to have all the permissions required for your app to actually connect to the Google Play something. Then you need to get an API key from Google to use Google Maps. So it's not that easy, but as you can see, it works fine in Ruby Motion. So all the steps that are required normally in Java, you can do that in Ruby Motion. And I have a sponsor here, very simple. Oh, actually if you click on the sponsor, it's gonna open the URL in Chrome. So that's called an intent, I think in Android. You can correct me if I'm wrong. But the great thing is that here, if I actually go back, it goes back to my app. So there is some sort of navigation thing going on here. And then we have the above screen here. Very simple. And I'm not going to show you the source code because it's not as simple as the other samples, but it will be on GitHub later today. Okay, this is all for the demos. So I can actually go back here. Okay, so thank you. So how does it work actually? That's a good question, right? So I'm gonna spend the last part of the talk explaining how it's implemented. So first let's talk about the runtime. And the runtime is Ruby. And more specifically, it's a brand new implementation of Ruby. So it's new code. We didn't actually take any code from RubyMotion for Objective-C. I actually wanted that on Jelly, but then I realized that it wouldn't work. Simply because we are trying to make the best implementation of Ruby for Android development. And so there is pretty much nothing we can take from RubyMotion for iOS. So it's brand new. So I told myself that I would never write Ruby again, and I... Anyway, and the first thing is that it has a unified object model with Java. It is exactly the same ID as we implemented RubyMotion for Objective-C, the Objective-C runtime. So basically, we have RubyMotion and Java, and they are all running on the Dell VQtune machine on Android. And here with RubyMotion, we actually use the Java native interface to actually reimplement the entire Ruby object model on top of the same runtime that's going to power Java applications. So, and of course, on top of that, we give the entire set of Android APIs that are written in Java. So from RubyMotion, you can access all the Android APIs written in Java that as you would do in actual Java code. The runtime model is really unified. More specifically, Ruby classes are always Java classes. Ruby methods are always Java methods. Ruby objects are always Java objects. And Ruby exceptions are always Java exceptions. And this is Versa. You can take a Java class, and it will look exactly as if it was written in Ruby. When you get a Java object from a Java API, you can call methods on it. It will work. Same runtime. And exactly the same way we implemented RubyMotion for Objective-C. This is obviously good for performance because there is no bridging involved here. Also, the built-in Ruby classes have been rewritten on top of core Java classes. Again, exactly like RubyMotion for Objective-C. So, I'm just showing you a bunch of classes here. It's not the full list, but string, it's actually based on Java LAR care sequence, which is an interface, not a class, but with our string class, which you implement this protocol, this interface, sorry. Java interfaces are a little bit like Objective-C protocols. And there are lots of APIs in Android that expect Java LAR care sequence. One of them is actually the setText method on our TextView class. If you remember in my demo, I typed label.text equal a string. And that method expect Java LAR care sequence. So, it works. No conversion. Arrays are actually Java-util-array list. Ash are actually Java-util-ash-map. The numeric types are based on the built-in integer and numeric classes of Java. The big name is actually a Java math big integer. So, Java already has a big name class, so we use it, why not? Regular expressions are based on the Java regular expressions. So, a regapse in RubyMotion 400 is a Java-util regapse pattern. And the match object is a Java-util regapse result or something, I don't remember. But the great thing about regular expressions in 400 is that they use the same library that we actually use in RubyMotion for Objective-C. It's called ICU. And so, it behaves more or less the same way. So, they won't be any major differences. As far as I know, they shouldn't be any. And finally, RubyMotion threads are based on Java lang thread. Threads in, at least in Android, are fully Pusik threads. They run completely re-entrantly. They're fully concurrent. And the runtime in RubyMotion 400 is also fully re-entrant. So, there is no global lock. There is nothing that prevents you from having two threads running at the same time. It is very similar to a red notion for Objective-C. And this one is a bit tricky. We have memory management. It's completely automated. And it's completely delegated to the Dalvik return machine. But the great thing is that Dalvik has a great garbage collector. It is way better than what iOS has, honestly. It's like day and night. First, it's generational. So, it does a few, it does many passes. And you try to collect the young Objects quicker than all their Objects. It's fully concurrent. The GC runs on separate threads. So, for example, each Objects can actually be finalized in completely other threads than the threads that were actually created. So, it's actually very, very nice. And each thread has a per thread allocation pool. So, when you do allocations, it's not actually sending messages to another thread. So, it's relatively fast. So, allocations are actually very nice. I forgot to mention that, but the Android GC also supports, also can obviously resolve retained cycles or cyclic references. That's obviously a fact because they are a real GC. And they are basically two, they are more than two types, but they are mainly two type of references that the runtime creates. The remote runtime. The local references are created by default. So, every time you call a method and that method returns an Object, the runtime is going to return a local reference to it. However, if you actually explicitly set a strong relationship between an Object and another, as an example, if you create an instance variable, this is going to create a global reference. But global references are done explicitly. They are done by you. You actually know when you actually create a global references. The description of local references is determined at copine time, as I'm going to show you in the next slide. Basically, the compiler determines where local references are no longer needed. However, the description of global references is done at runtime. So, it's really, for example, if you have an instance variable and you set this instance variable to a new value, the order value, which is a global reference, will be destroyed. So, it's more like a runtime thing. Yeah, as an example, x equal object.new is a local reference and at x equal object.new is a global reference. Obviously, when an object doesn't have any reference to it, it is promoted for garbage collection and it can die as soon as possible. And since the GC is actually a completely concurrent, it can die right now because it can happen on a thread running next to the thread you're currently using. So, let's take a very quick example. I have a full method with a few lines. So, let's try the first line. I create, I do x equal object.new and this is going to create an object x. And this is a local reference to my object. Then I do y equal object.new and this is going to create an object y. Again, this is a local reference. Now, I do at z equal object.new and this is going to create an at z object but this is a global reference here. Now, actually at the end of this line, my object y dies. We actually destroy the local reference, y, exactly. Because if you look at the rest of the method, the y local variable is not used anymore. So, the compiler knows, hey, we don't need this object anymore. So, we just destroy the local reference and at this point, the object can be destroyed anytime. At least it doesn't have any reference attached to it anymore. Then we can call the bar method. The bar method again, because we like bars. Then we can print the value of x. So, it's going to print something and at the end of this call, obviously, as you can expect, x dies. We destroy the local reference because at the end of this method, we don't use x anymore. And the global reference, obviously, remains alive. And as long as the object remains alive or object at z will remain alive. So, I hope that was clear, but anyway, we have documentation for it. So, now I'm going to just talk quickly about the compiler and the compiler is based on LVM, obviously. So, the Ruby files are actually statically compiled into machine code. In Ruby Motion 408 app, we don't use Java at all. We compile straight to ARM code. Very similar to iOS and OSN applications are compiled. So, this is straight machine code. As an example, if we have our main activity with one method on create, it's going to generate this LVM instant representation. We actually have two functions. The first one is going to be as you have a message. It's actually your wife. It's okay. The first one is actually the implementation of the on create method. So, this is the Ruby code that will be compiled into machine code, pure Ruby. And then we generate a second function here. It's at 2881. It's actually a unique number. We don't control that. And that method will actually be the one that will be inserted into the Java runtime. So, we use GNI for that. GNI provides you a way to register native methods. And this function actually complies to the GNI expected interface. The first argument is actually a GNI environment. And the other ones are the Java arguments. So, we need to convert some of the types from Java to Ruby. Actually, most of the time, this OCVAR to RVAR will just pass away the pointer because there is no conversion needed. Sometimes, we might have to convert certain types. Then we can invoke our method defined earlier and then we can just rescue exceptions and do things. But basically, what I would like to show you is that the Ruby stuff is always compiled into machine code and registered into the Java runtime. And this is, by the way, the exact same way we do our notion for Objective-C again. Very similar. The compiler will also generate decks by code for Java interface, for classes interfaces. The reason is that in Android, while at least in the GNI implementation of Android, it is not allowed to create classes at runtime. They don't implement the full spec of the GNI specification. So, you cannot create classes at runtime, sadly. So, for that, we need to create the decks by code to actually create the classes. But the methods are truly native. But the class structure is decks by code. So, as an example, here we have a new class with two methods, onCreate and onTouch. Sorry, dispatchTouch, even. And we're going to generate this decks by code. I forgot to mention, decks by code is the by code we read at runtime by Dalvik. And here, we actually have two virtual methods. As you can see, we have dispatchTouch, even, and onCreate. And we just define, expose them. And before that, we actually expose our main activity. And we say that it is a superclass of Android app activity. All this stuff is created by the compiler for you. If you look carefully, you will see that the access of each virtual method, it's publicNative. Native means that the code is not there. The code is not by code. The code is machine code somewhere else. We emit, the compiler emits dwarf metadata, which is very specific support to provide proper debugging information. So, as an example, if you dwarf dump the library that we generate, you will see a bunch of information. You will see that we have file and source line information right there. So, if you have an app that creates an exception at runtime like we call food and food call does not exist, you will get an exception and you will get the proper file and line information, which is something you expect, but I had to write it. And finally, a very quick talk about the build system. The build system attacks all the RB files and all the resource files and generate an APK for you. So, if we look inside the APK, it's actually a zip archive. So, you can just unzip it and look what's inside. And you will see that there are a bunch of files. The first one is lippelow.so. It's a share library that contains both the source code, sorry, the machine code of all your RB files and also the machine code for the RubyMotionRuntime. So, it's all zip into a share library. And RubyMotionFrontreadApps are using NDK, the native development kit that allows you to have a machine code and Java code at the same time. And this code would just be loaded at runtime. Then you have an Android manifest.xml file, which is the project's configuration or, yeah, project configuration. And it is very similar to the info.plist file that you have in Objective C project. And this file is actually generated based on values in your REC file. So, you don't actually create it. It's done for you. Then you have the classes.dex, which is the DEX bytecode for the class structures of your program. So, again, it only contains the class interface, not the real code. The real code is in the lippelow.so library. Then you have a resource directory where all the resource files of your app will actually be there. And you can have both raw resources, like assets, and then application-level resources, like all the XML files I was looking about. You can have both of them in the project. And the build system is smart enough to do that. And you also generate the famous r.java class so that you can actually access these resources from the code. That's an 100th thing, but it's there. And finally, there is meta-inf directory, which contains the code signing information for your app. So, if you actually create a release build, it will contain your public key, the public key of your key store that you generated. And there is something I forgot to mention is that the conference app I showed you a few minutes ago, it's actually on the Google Play Store. I submitted it and they approved it in two, two, or three hours. Actually, they don't even approve things. I think it just automated. So, this is another great thing about Android. You can, well, a great thing and a bad thing, I guess, but the app is there. So, if you have an Android device, you can try it. Now, you will see that it's two megabyte. It's actually because it bundles the Google Play Services library, which is already two megabytes. So, the application is not that fat. It's just that library that we ship. This is for the maps view, by the way. It runs on pretty much all the Android devices I could find, which is my Nexus 7 tablet and Colin's phone. I'm not sure if it's gonna run on all the Android devices. Actually, when you submit this, it says that you have, you can generate 200 devices, anyway. So, let's recap. Remotion 3.0, with performance improvements, with faster development cycles, thanks to code reloading, and with Android support. So, you can finally create Android apps in Ruby. You can share code between iOS, iOS 10, and Android apps, and you use the same experience. So, no Eclipse on Android, no Xcode on Objective-C. Use the same development experience. So, this is a preview of Remotion 3.0. This is a sneak peek. The only reason we are showing it to you today is because we need your help to actually make sure we can deliver it to everyone. So, we cannot give Remotion 3.0 to everyone at this point. It's still in early development, and we really need help from the community, which comes to my last slide. We need you. So, starting from today, actually a little bit further in the day, I will do a blog post on our post, and we actually ask for interested developers to actually try early builds of Remotion 3.0. And we really need your help because especially for the Android support, the Android support is brand new. It's a new implementation of Ruby. And when we ship Remotion for iOS, it was already based on Mac Ruby, something I work on for five years. So, it was well-tested and solid. This is not solid. This is brand new. So, we really need your help. And we're looking for a bunch of profiles. We're looking for people with Gems that may exist in Android. So, I'm thinking of you, MotionKid, Babarap, Promotion, all the stuff that may make sense on Android, and you want to port it. And also, if you have applications on the Apple App Store, and would like to port it to Android, and would like to try early builds, you're welcome. And we really need people who are able to deal with frustration and pain, because there will be bugs. And we will need you guys to report us feedback and make sure we can test early builds. And hopefully we can deliver Ruby Motion 3.0 to everyone later this year. But we will actually ship it when it's good enough for us. And that's all. Thank you very much.