RailsConf 2013

TDDing iOS Apps for fun and profit with RubyMotion

By Brian Sam-Bodden

As Ruby Developer I've had a pretty involved relationship with my Mac. I own iPads and iPhones since Apple started to make them. A few years back I told myself I was going to build apps for the Mac/iPhone/iPad but then reality sunk in when I started learning Objective-C and using XCode. The environment (and the language) felt like a trip back to 1995.
If you are a Web developer used to working with dynamically-typed, lightweight languages, following agile practices like Test-Driven Development, and comfortable with a Unix Shell, then jumping into a development world with an ugly cousin of C++ and an IDE that looks like an F16 cockpit just doesn't seem appealing.
Luckily for us there is an alternative in RubyMotion, a Ruby-based toolchain for iOS that brings a Ruby on Rails style of development to the world of iOS application development.
In this talk I will show you how you can use well engrained Ruby practices like TDD to build iOS Apps with RubyMotion.

Help us caption & translate this video!

http://amara.org/v/FG9Q/

RailsConf 2013

00:00:16.560 all right hello everybody I'm Brian Soden and first of all
00:00:25.519 smile all right so um
00:00:30.640 whoa I'm here to talk about Ruby motion and I titled this tdd in iOS apps for
00:00:37.000 Fun and Profit with Ruby motion uh the profit part hasn't arrived yet I'm
00:00:42.440 working on that but I'm having a lot of fun with it so let me tell you a little bit about
00:00:48.840 me uh I'm not from Portland actually this is awesome to be the last session of the conference I hope you enjoyed the
00:00:54.879 conference I had a great time and I hope to see you next year so uh
00:01:00.440 I am a longtime programmer I've gone through pretty much every language you can think of I started with lisp that
00:01:08.000 lasted uh about three months when we ran out of money and ended up doing Java for a long time and in ' 05 I made dhh uh
00:01:16.280 here at oscon and um I was talking about a clone of rails and he promptly made
00:01:23.600 fun of me and fast forward a year later I was running my own rails company so
00:01:29.159 what do you know I live in Phoenix I'm not in the witness protection program which seems to be the
00:01:36.880 tendency in Phoenix and I want to start with confessions I'm an apple
00:01:43.920 Fanboy there should be no reason a 41y old man has a white leather case
00:01:54.799 iPhone there's a there's a price to pay but you know I'm I've been paining it
00:02:02.360 willingly I work with Ruby every day uh we're a rails consultancy we do tdd
00:02:09.440 driven development for our clients uh agile the whole shabang and uh before
00:02:15.319 that I used to do back in the 90s desktop applications uh Borland Deli you
00:02:21.280 guys remember that you remember 4gls so I really wanted to do iPhone and
00:02:28.480 iPad applications but Apple wants you to use xcode and
00:02:34.840 xcode took me back in time to those Deli and Visual Basic days and it fell Prett
00:02:42.239 retro and I tried it I tried it but it just I just could not get myself to go
00:02:48.120 back to that mode of operation basically dragging and clicking and and connecting things with drop downs it just didn't
00:02:54.280 feel right it felt like this it felt like a pretty complex environment where
00:02:59.760 where there was no flow you had to live in it for a long long time to have that sense of
00:03:06.560 flow and everything about it just slowed me down trying to do simple things
00:03:13.480 resulted typically in me actually restarting the application from the
00:03:24.560 up and then there's Objective C I know there's a lot of people that really like
00:03:29.959 the language but for me I I've done C and C++ in Java it just it it felt like a
00:03:37.599 weird combination of some good things that turned out pretty bad like Rosemary's Baby version of a programming
00:03:44.920 language so I I tried it couldn't do it then I heard that there was something
00:03:52.319 out there called Ruby motion actually let me uh rewind a little bit I found Mac Ruby because I wanted to do
00:03:57.920 beautiful apps uh on the desktop for the Mac so I started playing with Mac Ruby which is a ruby interpreter for the Mac
00:04:05.720 I build an Objective C but luckily somebody else had to do that work not me uh but there are a lot of constraints
00:04:13.959 that iOS has that would not allow you to build an IOS app with Mac
00:04:21.440 Ruby so somebody created Ruby motion which is a you can think of it as a fork
00:04:28.759 of Mac Ruby dealing with the restrictions that iOS imposes on the
00:04:34.520 environment uh Ruby motion it's a commercial product but it's actually pretty cheap it's 199 bucks and if you
00:04:41.680 stick with me till the end of the session uh I'll give you a surprise slide at the end the source is available
00:04:48.479 but not all of it uh there's some parts of it that are hidden from from the public uh but there's contributors
00:04:55.320 there's there's contribution being done to Ruby Motion in the open source fashion so there's a lot of gems
00:05:02.080 appearing there's a lot of dsls appearing to basically help us deal with the sometimes complexity that is IOS
00:05:10.039 development so they titled it a ruby based tool chain for
00:05:15.160 iOS and it is based on Mac Ruby uh but targets iOS it compiles it creates
00:05:21.440 binary artifacts that you can send to the App Store and sell them and you know
00:05:27.039 make a lot of money and start driving race cars and stuff like
00:05:32.960 that it was created by Lawrence sanetti and I'm probably mispronouncing his name
00:05:38.759 but I'm sure he'll be okay with it he worked at Apple for seven years and I worked in I life in OSX so the guy had a
00:05:46.000 lot of experience with the environment but he also was a rubyist on the side so
00:05:51.720 M Ruby came out of his effort uh and a few other people but one of his gripes was this
00:05:58.639 that xcode which just not a really good environment to deal with Mac Ruby even when I was playing with Mac Ruby I was
00:06:04.160 using textmate or Vim so the guy doesn't like xcode I
00:06:11.680 tried it I don't like it either it's actually pretty to look at it looks complex and it makes you feel like whoa you know this is pretty nice but after a
00:06:18.360 couple hours struggling with it it just didn't do it for me so who is a ruby motion's target
00:06:25.000 audience it's it's us really if you are an expert
00:06:30.400 xcode Objective C iOS Developer you're going to probably laugh at Ruby motion
00:06:36.039 because it's in a language that you don't understand um following processes
00:06:41.080 that you're not used to one of the things I started doing when I started playing with iOS is trying to figure out
00:06:46.680 how they did their test driven development and they don't actually they barely test it seems
00:06:53.599 that testing is uh they probably could buy that robot that they showed at the uh at the lightning talk yesterday
00:07:00.080 because it seems that it's just user testing and throw it over the fence and good luck the the old QA Department type
00:07:06.120 of approach and I can't work that way anymore uh it's it's been too long to actually go back to those habits so Ruby
00:07:12.560 motion it's targeted to rubyist that actually might not know um iOS at all
00:07:18.319 and that was me I started learning the iOS apis through the veneer of Ruby motions Ruby
00:07:26.680 flavor web developers should feel pretty comfortable with Ruby motion uh because
00:07:31.879 it gives you a rail style of development you're going to see that we have models views and controllers uh there are gems
00:07:39.759 that provide apis to make each one of those uh areas of the MVC stack more
00:07:45.639 palatable to you and you can use uh a a a shell you
00:07:51.080 can use bash you can use whatever shell you like to use and have that semblance of writing a test failing The Test
00:07:58.319 passing the test and moving along your design and development process that way so tdd and bdd are good friends to Ruby
00:08:05.039 motion it's not as fluid and agile as let's say a rails application nowadays
00:08:10.280 because it you know we've evolved this stuff over the years but it's getting there and my goal for this session uh
00:08:16.520 was to me uh to prove to myself that I could tdd a ruby motion
00:08:22.319 app so let's jump a little bit off track for a second and obvious question that
00:08:27.879 always comes up it's why you just build a web application and it seems that uh
00:08:33.120 users are still getting this tactile responsiveness feeling from native
00:08:38.159 applications that they don't seem to get from HTML F web apps uh I'm not going to spend too much time on this but I I left
00:08:44.640 you a couple graphs in there that you can take a look at um I think that to hit Market it's it's pretty good to have
00:08:50.720 an HTML 5 application but in learn how your users use your application and eventually you might actually want to
00:08:57.200 Target a native application if your domain requires it so if you're doing gaming if you're using any of the
00:09:03.600 hardware devices on the phone uh you probably want to go
00:09:09.600 native so let's uh do our first example which is our hello world in French I
00:09:15.240 hope that's right Lauren's going to kill me and uh I'm going to show you just a quick slide that uh Ruby motion it's all
00:09:22.760 encapsulated in the motion command in the motion command it's like the rails command you use it to create your
00:09:28.040 applications in this simple example I'm creating a hello world
00:09:33.600 application and it's also R driven development so you have a as you create
00:09:39.720 a ruby motion application you have a set of rake tasks that can allow you to do a lot of different things about your
00:09:45.839 application you can build it you can build it for a specific device version uh you can build it uh for the simulator
00:09:52.279 and you can run your test uh in most cases you're going to use rake to run
00:09:57.399 the application and see it live and R spec to actually run your test and that's typically the two commands that I
00:10:03.519 use all day as I'm building iOS apps so I have a cheat
00:10:09.120 sheet for my
00:10:18.360 demo and I have the simulator right on screen so first thing
00:10:24.160 I'm going to do is show you the version of Ruby motion that I'm running
00:10:30.800 and let's create our first Ruby motion
00:10:36.519 application and if I run the right command it's uh rapidly going to fail
00:10:43.120 because I'm not in the directory of my application this is that that moment as a presenter where
00:10:49.320 you're like Co sweat CD to the
00:10:56.480 directory this application does nothing but as you can see it launched uh the
00:11:02.240 application on the simulator if I exit out of the application you can see that
00:11:07.680 there's uh the icon created for the app the only problem is it doesn't even have a single view so all you get is a blank
00:11:17.200 screen now one uh thing that I wanted to mention let me run it one more time and
00:11:25.000 notice that my console now it's sitting at a prompt so that's the reppel that's
00:11:30.320 the reppel of Ruby motion which is like the IRB or the or the rails console and
00:11:35.399 that is the place that was my my experimental lab to learn about iOS because you know what's the the number
00:11:42.240 one uh method that you call on a class that you don't know methods so typically I started digging
00:11:49.440 into the iOS apis through the console and playing with things and the nice thing is that whatever you do on that
00:11:55.600 console reflects reflects live on the simulator so let me take some of my can
00:12:02.360 examples that I have in here and uh show you what's going on in
00:12:08.920 here so the first thing that you notice it's that the self object it's main just like in uh many interpreters I'm going
00:12:15.279 to create something called an alert and an alert it's uh it's the UI alert view
00:12:20.519 it's one of the iOS classes that we use to basically do a pop-up
00:12:26.440 dialogue and I'm going to set some values on my
00:12:35.600 alert let's put a title a message and now I can go ahead
00:12:48.279 and show my alert so and that's the cool thing about it yay one Dialogue on an
00:12:53.959 iPhone app awesome but I I know it sounds it looks
00:12:59.240 simplistic but having that feedback loop it's what allowed me to actually learn
00:13:04.760 iOS I mean I'm not an expert by by any stretch of the imagination but it has
00:13:09.839 allowed me to to delve into something that looked really foreign to me before and and really extract some knowledge
00:13:15.399 out of it uh I can also uh
00:13:21.920 dismiss that alert so it's a a pretty simple environment to learn about iOS and if
00:13:29.000 you're a ruby developer and you've been wanting to learn about iOS uh to me this is the be best vehicle that you could
00:13:35.199 possibly find and it's only 99 bucks so now let me go back to the slides for
00:13:40.399 a second so again that's my number one
00:13:47.519 reason to love Ruby motion it's the rebel the console allows you to explore
00:13:53.199 the Ruby motion uh API and therefore the iOS apis Ruby motion motion basically
00:13:59.519 puts a just like J Ruby and Mac Ruby and any other foreign platform Ruby
00:14:05.440 interpreter they they create a thin wrapper around all of the classes available in iOS so the rapple to me was
00:14:13.160 the first thing that that brought me into the platform uh you can interact with the running iOS application in learn and
00:14:22.279 discover and actually we made it past this yay so now let me tell you about a
00:14:29.000 number two I like Ruby motion and that's the bacon who doesn't like
00:14:34.519 bacon bacon it's an arsp clone and in particular uh Ruby motion uses something
00:14:41.560 called Mac bacon which is very expensive bacon and uh Mac bacon again it's a a
00:14:48.920 small clone of arsp not completely one to1 syntax wise with arpeg but it's the
00:14:55.759 vehicle that we're going to use to do bdd and tdd with Ruby
00:15:00.920 motion a uh here's a little slice of Mac bacon and you can see that you have a describ block you have a string that
00:15:06.880 describes the context of the block uh then you have before blocks like you do in most bdd Frameworks like arsp and
00:15:14.320 then you have your it examples so for example uh an array it should be empty
00:15:20.959 it should not include one things of that sort uh you you have more of this uh
00:15:26.480 fluid um meta chaining API that in in arpec now we have the spec parenthesis
00:15:32.560 and some statement so it's slightly different it's probably closer to arpec 10 that than
00:15:39.880 20 and it it it has a lot of different things that allow you to basically do
00:15:45.000 the type of testing that we're used to doing in the Ruby and rails
00:15:51.040 world so Ruby motion tdd the highlights of the demo that we're going to see first of all testing
00:15:57.880 it's all done with B uh red green refractor looping for iOS
00:16:04.279 sometimes not as easy as it sounds um the environment for Ruby motion it's
00:16:10.519 meant to test units so you're meant to test for example One controller your
00:16:16.040 your largest unit that you can test is a controller so it's meant to test One controller in isolation if you're
00:16:21.680 testing going from one controller to another one you have to go with something outside of Ruby motion
00:16:27.480 something more uh can cucumber and there's a few products out there that are cucumber like uh specs to basically
00:16:34.600 run full Ruby motion uh Suites or iOS Suites in general and I'm using two
00:16:40.440 libraries just to show you that here's where the power of Ruby open source in our community comes in to basically save
00:16:47.759 the bacon uh motion model it's a an active record like uh clone for iOS
00:16:55.759 applications that uses uh one of the simple local local storage uh facilities that iOS has and form motion it's
00:17:04.439 imagine simple form for iOS I'm I'm a pretty lazy developer so I wanted to
00:17:09.959 find ways to declare a model and then say turn this into a form that somebody can input data in the phone app so I'm
00:17:17.760 using those two libraries in combination just for the demo uh there are probably by now hundreds and there's
00:17:25.000 a whole list of libraries available out there gems available uh to you and they
00:17:30.120 cover everything from 2D gaming to dealing with some of the hardware devices on on the uh on the phone um all
00:17:37.960 kinds of stuff out there so let's talk let's look at our second demo and I have an application
00:17:44.160 that I it has probably around probably 40 or 45 commits the last time I Tred to
00:17:50.360 demo the whole thing it took me two hours so I'm going to do some of the initial commits and then fast forward in
00:17:56.000 time to some of the last commits so you can see the progress that I made in
00:18:01.240 there and my application is called okona which according to Google Translate means done but I don't know if it's done
00:18:07.799 as in being completed with a task or done as in a stake so it could be a complete misnomer of my application but
00:18:13.960 we'll see I should have asked Joko before she left and the application it's on GitHub
00:18:20.600 so you can if you get a copy of Ruby motion you can grab it and play with it and this is what it looks like but
00:18:28.960 let's get to the Demo First all right so I'm using a get
00:18:34.240 presenter so I can fast forward through my um commits and if you can see there I have
00:18:41.360 a pretty large list of commits so I'm going to uh notice the initial commit uh by default a new Ruby
00:18:49.320 motion application let me show you what it
00:18:56.760 has it has pretty pretty much nothing it has an application delegate which happens to be your entry point into the
00:19:03.320 iOS stack and from there you basically wire your controllers and your views and your models to show something to the
00:19:10.520 user so by default they have nothing and in terms of test it has only
00:19:16.720 one test that says that you should have a window let me make that a little
00:19:27.240 bigger so if I run those
00:19:32.799 tests you will see that I have a failed test and I think Lauren intended for
00:19:39.760 people to basically start at the red state of the tdd cycle and then start building you know start building the
00:19:46.679 fleshing out the application that way but most of the examples that I found out there it's like people are going
00:19:52.640 following the iOS Mantra and not testing or testing after the fact and if if you
00:19:58.480 have an environment as powerful at as as Ruby and rails when it comes to tdd in an application or or close enough I
00:20:05.360 think you should use it so now let me um move
00:20:11.120 forward to my first passing test in my first passing test just says
00:20:18.520 that I should have a window so I'm trying to pass the test that was broken that comes built in with Ruby
00:20:25.919 motion and to do that now I just slapped a window inside of
00:20:39.840 foreign to a rubyist for for example that word alloc that means you know allocate or you guys remember Malo from
00:20:45.880 CN C++ so in here there's a there's a concept of allocating memory for
00:20:51.400 something uh luckily for us in most cases you can replace that with new and
00:20:57.039 it seems to work just fine so in here I'm creating an instance variable called window and I am
00:21:04.799 initializing that with the current frame to basically take the whole bounce of the screen and if I were to run my
00:21:12.600 application now you will see that it's still a blank
00:21:18.640 screen but it happens to have one window it's just
00:21:27.039 blank all right so going back to the commits now I'm going to fast forward so
00:21:32.919 this is a to-do application I was I was setting out to build a very simple list of to-dos that had a due date in a
00:21:40.799 Boolean that will tell me whether the to-do was accomplished or not so I'm going to fast forward now to
00:21:48.520 my first failing test for real functionality which is number commit number five which
00:21:53.679 is it should display the given to-dos so let's go to number number
00:22:03.559 five run my test and I should see the test
00:22:12.240 failing ignore the stack Trace uh so I have my todu controller
00:22:19.320 typically one of the things with tdd that is hard uh for for people jumping into tdd it's where to start and
00:22:25.480 sometimes you try to start with something way too complex so with iOS uh with Ruby motion development the first
00:22:31.080 thing that I said to myself I'm going to test something very simple I'm going to test like the the controller class that I meant to create it's not there and
00:22:37.640 that gives me just a place to start it might be a silly test but it gets you started it gets you down the road of
00:22:43.600 basically doing the tdd loop so typically I add a test like that that says uh the control the to-dos
00:22:49.760 controller should exist as you can see the original uh application uh test that should have one window it's passing now
00:22:57.159 but my display the given Tod do test is failing all right so now let's fast
00:23:04.840 forward to the next commit where I actually implement the possible the minimal thing that would pass that test
00:23:11.760 and for that the the process of getting to that first that first real commit uh I actually used the console to figure
00:23:18.120 out hey how do I show a table of data on an iOS
00:23:24.360 application and it happen there happens to be something called a UI uh table View and that's where I basically
00:23:31.799 started playing with so it's typical Discovery process you know going into the apis uh the API exploration happens
00:23:38.880 through the console see what methods are available try them uh see some memory errors because you don't know what
00:23:44.039 you're doing and eventually flesh it out to the point that it makes
00:23:49.200 sense so let me show you the code to pass that and I'm going to make it just slightly smaller so we can see the whole
00:23:55.880 thing in one shot so what I did it's um I created I have
00:24:02.400 my window as before and then I'm creating a table which is a UI table view uh my table view it's also taken
00:24:09.279 the whole screen width and in height and then I created a very simple array of uh
00:24:15.120 things that I should buy in for my pantry and um I'm creating something
00:24:21.159 called a data source which is down below in my data source it's an object that
00:24:27.080 the table view it's going to use to acquire its data to ask for example how many elements are there on the table and
00:24:33.960 things of that sort so notice that I'm implementing two methods in here um
00:24:39.200 table view number of rows in section and table view sale for row at index path
00:24:44.600 and this is a good stopping point to talk about the weird syntax that you're seeing right now uh first of all notice
00:24:50.480 that there's a lot of camel case rather than uh than snake case like we're used to in Ruby some of those this methods um
00:24:58.399 are direct translations of The Objective C signature uh Objective C has a concept
00:25:04.880 of pseudo name parameters which Ruby 2.0 would have uh name parameters but in
00:25:09.919 this case that celf for wrote at index path colon index path it's one of those
00:25:15.279 name parameters so for most people it looks like you're overwriting the same method down below it's a completely
00:25:21.880 different method signature and the Ruby motion interpreter understands that uh it took me a while to not thinking that
00:25:28.240 I was overwriting my own code in the next line so notice in here that my to-do
00:25:33.960 data source has a data attribute and then inside of the table view sell for row at index path that's the question
00:25:40.760 that the table will ask when it says hey I need some data for this row I returned something called a UI UI table view sale
00:25:48.360 so again this is all discovery of mine through the console to get to that
00:25:53.880 point and let me run the test now just to show you where we're
00:26:03.480 at so now we have a clean passing set of
00:26:11.200 specs if we run the application it's not terribly exciting
00:26:17.039 right now but I have a table of data and believe me when I got to this point I was like yes I have an I have built an
00:26:25.399 iOS application I am the master of my domain give me a couple weeks I'll be
00:26:32.440 rich now one of the things that I wanted to show you let me go ahead and delete the applications that I have on the
00:26:39.000 simulator one of the things that I really like about this it's that if I run the
00:26:47.600 test what ruby motion does oh what is
00:26:53.600 that what ruby motion does it's actually run the test and creates an application that has the
00:27:01.679 state of those tests at that point in time so I could run this application again and it's running the test it's
00:27:07.440 just one so it's really fast but if you have a pretty comprehensive Suite of tests when you click that application
00:27:13.159 and you could save that application you can you know have snapshots of it if you want to have a binary of what the tests
00:27:19.360 did at specific point in time uh it's a produce artifact of your test suite and I thought that was pretty cool because
00:27:25.840 as I'm building the application I would play that and it's kind of like seeing a capibara uh Suite running through a
00:27:32.520 website you start seeing like oh okay it it kind of clarifies your mind of you know the the path of behavior that you
00:27:39.240 have in your
00:27:45.240 application all right so now that you've seen basically what the tdd cycle of
00:27:51.159 doing things in uh in iOS with Ruby motion looks like let me fast forward to
00:27:57.240 uh some of the N
00:28:03.200 commits I'm going to show you first what I did with form motion so let's go to
00:28:10.120 commit number
00:28:21.159 26 and again let me run the
00:28:26.440 test
00:28:32.279 unfortunately things get compiled so we're talking about now C object linking
00:28:37.559 and embedding and all that stuff that we tend to forget about when we're using Ruby uh but it's happening all in here
00:28:43.960 so uh noticing here that now I have fleshed out my test Suite to be a little
00:28:50.200 more complete so I now I have a to-do controller I have a model now my model
00:28:55.960 notice that I started with the simplest possible failure hey I want the model to exist in the first place and I'm
00:29:01.679 checking that it has a name description due date uh now I'm checking also that I have a to-dos controller that should
00:29:07.360 exist it shows all the given to-dos and also shows the correct label for a given to-do let me quickly show you what that
00:29:13.200 test looks like because I heard clapping and that means that my time is up unless it's just some random guy out
00:29:20.080 there that's just really good so so here's my to-do spec and this is
00:29:28.240 really the the spec for a very simple model
00:29:34.240 object and here is my extended to-do controller spec so let me run this so
00:29:40.320 you can see what we have so far and then I'll really quickly move to uh the last commit you see where I ended with this
00:29:48.320 so here's the application notice that now I started learning things about uh iOS by some of the warning messages that
00:29:55.440 appear in the console like for example example A View should not be unrooted from a controller a controller a view
00:30:02.320 needs to live inside of a controller and I learned all that through the warning messages in the console uh even though I
00:30:08.519 have pretty much every iOS book that has been in print I think I probably read Snippets of each one of those but this
00:30:15.399 was the best environment for me to learn this stuff so now I have uh a Model A
00:30:21.559 real model with local storage that backs every one of my to-dos I use a form mod
00:30:27.600 to create a oneliner form to basically be shown in here and as you can see I
00:30:41.240 can there's no such thing as fat free orange juice isn't
00:30:46.880 it but as you can see the label doesn't change in I'm not saving anything so let
00:30:52.000 me now fast forward to uh my last commit and I'll show you where I ended
00:31:02.440 all right 34 so there's 34 commits in there uh it's it's been a lot of fun
00:31:07.720 actually building this example for the presentation because even the things that I thought I knew so far uh were
00:31:16.360 clarified so here's the final uh specification
00:31:25.559 set and it's gone coming and it's coming the the the only problem with Ruby Motion in demonstrations is that
00:31:32.080 compiling time will get to you so now I have a slightly more complex testing suite and you can see that stuff was
00:31:38.399 happening in there now let me run
00:31:55.200 it and you should see the final version of my okanawa application notice that I
00:32:00.919 added some decorations in here uh there's a create new to-do button now so
00:32:06.799 a little more complete than
00:32:15.840 before when I
00:32:23.240 save my need to do I put them at the bottom I should probably put them at the top
00:32:29.799 uh if I modify uh an existing
00:32:40.679 too oh what happened I broke it save yeah I had a listener in there that
00:32:47.679 apparently I broke but well that's what happens when you do live coding so but again iOS it's no longer a
00:32:55.600 frontier that's too far for a ruby is to travel to um I'm I feel pretty
00:33:01.120 comfortable uh with the environment now the syntax it's not very hard to to grasp uh the moment that you stumble
00:33:08.760 upon a class that you don't understand there's a lot of examples uh written in
00:33:14.200 Objective C that now I'm my mind is translating directly to Ruby motion after you know just a few months of
00:33:20.320 working with Ruby motion so it it's a pretty viable Avenue for us to actually build cool iOS apps uh let me show you a
00:33:27.480 couple of the things that are out there now um there's a bunch of rappers for
00:33:35.000 everything that you can possibly need for uh Ruby motion and iOS development and uh Base Cam for the iPhone it's
00:33:41.760 built on Ruby motion and it it's partially uh some web rails app and a
00:33:47.799 ruby motion app living together in harmony and there's a bunch of other stuff out there I mean there's there's
00:33:53.600 iTunes like apps uh there's yeah this this is uh one for the uh London subway
00:33:59.600 uh just figure out where you're going and and what times the trains are arriving so people are building
00:34:05.080 beautiful applications I didn't have the time to put some makeup on my peg uh but that will be probably the next step I'll
00:34:10.800 take send me an email and Lauren will give you a 15% discount on Ruby motion
00:34:17.000 so do do the math uh about 14
00:34:24.440 bucks and all the sample code is on my GitHub repository and I'm actually going to put an ebook together about this
00:34:31.679 experience as I flesh out about three or four applications with Ruby motion of different kinds and types and flavors
00:34:37.760 including games so any questions all right well thank you very