00:00:15.120
uh so how many people here are still trying to blame their hangovers on the altitude
00:00:21.439
keep it up honest uh yeah we we had kind of an impromptu
00:00:26.640
open bar last night uh the poor house and we're probably do something like it again tonight so uh
00:00:31.840
i don't know follow thunderbolt labs we'll tweet from there yeah you'll find us
00:00:37.760
just so can you hear yes
00:00:45.040
i'm not going to put the mic in my mouth it's not going to happen all right can i get a show of hands how many how many people here were here for
00:00:52.000
the previous presentation by rich kelmer okay fantastic i'm going to try not to
00:00:57.360
get feedback too that's good that was a really great presentation and
00:01:02.800
the way we set ours up is we want to go a little bit more advanced into the practical side of doing a ruby motion
00:01:09.200
app specifically doing client server development because that's the stuff that really excites us is combining
00:01:15.439
mobile apps with uh the cloud side now we got three three parts to this the first one is
00:01:21.119
introduction to ruby motion the second one goes into the client server stuff and the third part the final part talks
00:01:27.920
about more of the why you would or maybe would not want to go through motion so and actually one other quick question
00:01:33.360
how many people here sort of actively are sort of develop client server apis you know your json backend pushing
00:01:38.799
something to like back yeah that's good so one of the nice things about that is like when you start thinking about
00:01:44.479
client server applications once you do that it doesn't really matter whether the front end is a backbone app or you know pick the new javascript hotness
00:01:50.000
serenade maybe right or an ios app they can consume the same json payloads so it's a lot less work
00:01:56.720
and it's kind of important for reuse and keeping things pretty uh separated yeah okay so let's get started so first of
00:02:03.360
all introductions my name is tamar sala this is randall thomas and together we
00:02:08.399
are thunderbolt labs wait rs ebony and ivory
00:02:14.319
ebony and ivory uh fun little story i actually wanted to
00:02:20.640
name us that she actually did try names that i vetoed it as a pc thing yeah
00:02:26.239
because i figured over the phone nobody would be able to tell the difference between ebony or ivory um
00:02:32.000
oh so that you laugh at all right whatever yeah uh and um
00:02:38.879
we're gonna have maybe some time at the end for questions but that's not really how we want to do it really things a lot more interactive because we get really
00:02:44.879
bored just standing up here on stage so if you raise your hand we'll stop last question and it's much more relevant so
00:02:50.720
please don't be afraid to interrupt us yeah or shout like we might be like staring at the slides all right
00:02:55.840
by the way raise your hand if you sat in this presentation just to heckle us
00:03:02.480
here we go rich here we go all right so all right so first of all just to set
00:03:08.400
the stage here you know randall and i uh and thunderbolt labs in general we all have a wide variety of skills um
00:03:16.400
all kinds of things that we're good at right um one of the things that we're not an
00:03:21.840
expert in to be honest we're not ios people right we're not objective c developers who are trying out ruby
00:03:27.920
motion we are ruby developers who learned the uh
00:03:33.120
the objective-c semantics and learned coco through ruby motion right so
00:03:38.879
that's kind of a caveat that there are some deeper things in objective-c and randall actually has a lot more
00:03:44.000
experience with the deeper embedded stuff that i do but in general there is stuff that you know we're not experts on
00:03:49.760
that but it's the same um approach that we think most people in the community are taking where people
00:03:56.159
are coming to this because they don't want to deal with objective-c do a lot of anybody in the room actually have
00:04:01.680
really deep objective-c experience like most people yes no some okay okay matt raises his hand back mike
00:04:08.159
clark he's laughing because he actually taught me ios i actually went to a prag studio
00:04:13.920
course you don't count yeah and i still get to say that we don't know it mike sorry
00:04:19.120
you're just saying that because you've seen my code all right so anyways what we're going to talk to
00:04:24.320
you about today is ruby motion specifically for client server applications that's what we're excited
00:04:30.240
about um so first of all let's talk about how you get started with ruby motion what it actually looks like when
00:04:35.440
you're on the command line um is that font big enough for everybody to see not at all okay let's let's bump it up
00:04:42.479
how's that better i'll go one more and i might have to bump it down for other slides i think
00:04:48.080
that's fine um so as you saw in the demo on the last presentation creating a ruby motion app
00:04:54.960
is actually really simple you just use the motion command much like rails and you say just create a sample app and
00:05:01.680
it creates an app called sample and you've got your app delegate and you can see this is ruby code we're going to get
00:05:06.880
a little bit more into what the differences are in a second and then you just use rake to uh to build and run the application in the
00:05:12.880
simulator um so here's a quick syntax breakdown of
00:05:18.320
the the differences with mac ruby and ruby and and it was touched on the last one
00:05:24.160
but i think we need to really hit this home that um what you're looking at here map view
00:05:30.880
pass into map view region did change animated animated is uh that's the entire method that is the selector um
00:05:38.400
with the crazy like uh sometimes you've got named arguments except for when it's the first one or
00:05:44.560
whatever that's all the method name right um
00:05:50.160
and i have to pop it down sorry guys is that good enough for everybody
00:05:55.360
yeah yeah uh squint maybe it'll be all right um so it's the same as defining this
00:06:01.360
objective-c method and he's absolutely right there is no bridge you actually are defining that objective-c method
00:06:06.880
when you do that um and it's not the same uh which is a little bit confusing when
00:06:12.000
you're first coming into it it's not the same as defining a method that takes uh a hash of of options and passing in a 1
00:06:20.240
9 hash symbol it's not the same thing which means
00:06:25.680
if you define these two methods where the keyword on the second argument
00:06:31.360
is slightly different it's completely different method definitions and if you call one or the other you're actually
00:06:36.800
calling different method definitions you're not calling a method called map view and passing in different options so
00:06:43.039
this is really important because if you aren't used to writing objective c you're going to be spending a lot of time trying to figure out why something
00:06:49.360
didn't draw until you realize that you're looking at the wrong method so you know watch out for that especially as you get started writing ruby motion
00:06:55.680
applications right okay so
00:07:01.520
you know what well it will once it's actually out so like you said that's actually in um
00:07:08.960
yeah that's eap you can right now okay cool so i have not used it um and we'll go into that in
00:07:15.440
a second uh but i guess it does recognize that syntax when you're defining methods the actual the only
00:07:20.639
actual syntax difference with ruby is in the method definition when you say def
00:07:25.759
whatever and you pass in the keyword inside the method definition is not legal ruby it is legal mac ruby and
00:07:32.080
that's what this is based on so i'm going to go back uh point that out right
00:07:37.919
here so this region did change animated
00:07:43.440
that's the bit that if you tried to do that through a normal 193 ruby app it would be like i don't know
00:07:48.479
what you're talking about right do you guys have a beeper for me
00:07:53.520
you're going to need that okay so one of the cool things that came out
00:07:58.960
recently in just in general with ios development um and well actually in
00:08:04.000
general with apple development ios and osx development is the concept of storyboards who here
00:08:10.960
has used nibs in developing osx apps who here who use storyboards
00:08:17.199
who is yours cursed nibs when they're developing and remember when they try to improve it by serializing it to xml because that
00:08:24.319
really made things really readable so storyboards are actually a really cool concept i'll give you a real quick
00:08:29.599
rundown of how this works um basically you drag ui elements under this palette
00:08:35.120
and you kind of draw out what you want things to be and then you save it and unlike other systems like i think how
00:08:42.240
visual basic works it generates code that would create that ui instead of
00:08:47.600
doing that it actually instantiates objects into memory that um that are
00:08:52.880
those those view elements and when you save it it actually marshals them down basically like a memory image of this is
00:08:58.959
what your view is and when your application launches it loads that nib tosses it into memory and sets up some
00:09:05.120
connections between your instance variables your outlets and your uh selectors i think it's called yeah and
00:09:11.200
how many people here have forgotten which direction they need to drag their ib outlets to oh holy yes yeah i hate that so
00:09:17.680
much it's it's pretty painful but storyboards actually make that a lot easier because it actually especially with the new storyboard editor it's much
00:09:23.839
easier to hook things up and test it than it was in some of the old ios simulators right with these storyboards each one of these little boxes that
00:09:30.320
you're seeing um i know they're kind of hard to see let me see if i can bump it up oh no that just does the finest it's
00:09:36.080
it's controlled by my own computer that's great um each one of those boxes is uh uh an iphone screen
00:09:43.519
and you're connecting them together by dragging from the button of one to the next box and you can actually run that
00:09:49.920
yeah it's like director for ios nice because we all knew that was really good programmer so you can actually run that
00:09:55.839
and it'll run through this entire thing you just click this button it does nothing right but it's great for rapid
00:10:00.880
prototyping and showing like this is what i think the app's going to do and you can sell it for 99 cents in the app
00:10:06.399
store right it's pretty cool so storyboards are pretty cool and you can actually use them with
00:10:13.040
ruby motion you basically you end up creating a storyboard in your resources directory
00:10:19.200
and you use xcode to do that you change your break file so that the ui main storyboard file is set to the
00:10:25.760
name of that storyboard then you make sure that for each
00:10:30.839
element in your form or whatever you're going to be using for each element you make sure that it has a unique tag so i
00:10:38.240
have to click on this password box i have to click on the what is that a shovel i have to click on
00:10:44.240
the shovel and then i have to go over to the view and set a unique tag on there and the reason you have to do that for each
00:10:50.560
one of your elements is because in your ui view controller class now notice this is just ruby here it's like we're using
00:10:56.240
ruby motion you have to set up methods that will grab that item out of your storyboard
00:11:03.519
so you have because you're a ui view controller you have a method called view
00:11:09.200
that basically points at your your your what do they call it pain in the
00:11:14.560
storyboard yeah it is painful um so you can say view a tag one two or three
00:11:20.000
and now you've got it right that's the hard way of doing it and that's how you had to do it for a while
00:11:29.040
oh okay we're going to get to that in a second so you're right you would probably want to
00:11:34.320
put some constants in there uh you probably want to put some constants of the problem is you can't set those constants in xcode okay so one thing we
00:11:40.560
actually need to be very clear about is you are no longer in ruby land this is actually a very nice illusion over a horrible horrible dream right
00:11:47.760
so what you should think about this is like um uh like that scene in the wall you know where you're being chased by hammers and
00:11:53.680
like your teachers like like going over the cliff and everything's all horrible or brazil which is another horrible movie which has these terrible terrible
00:12:00.160
nightmare scenes but at the end he's like flying like a bird and an angel and it's cool this is like the angel scene
00:12:05.279
behind the scenes you still get these ugly little things that poke their head through and one of them is like you know having written a lot of c plus plus we
00:12:11.279
have defined statements all over the place and macros so like this doesn't bother us because you know we started writing code in the 80s and then
00:12:16.800
the 80s we did this it's cool right so yes you should but you're not in ruby land anymore so do it their way it's
00:12:22.720
much less painful and and there is now this gem which is actually really nice that ibm yeah ib um which helps out it's
00:12:30.560
such a hack the way it works though it's really incredible but it's it's the only way that really works well
00:12:36.399
anybody here who doesn't like hacks cover your ears like seriously so please elucidate how this works so you include
00:12:43.040
this gem and we're going to show how to do that with using bundler in a second um and then you in your ui view controller you extend it with ib
00:12:49.839
and then you've got access to these methods like outlet basically and you can say this view controller has an
00:12:56.959
outlet which kind of means an instance variable that can point to part of the view um named email text field or name
00:13:03.040
text field or button those are my outlets right um oh sorry i didn't oh yeah and down there
00:13:09.600
at the bottom you run rake design what happens when you run rate design is really fun so ib looks at all the the
00:13:18.000
classes that have extended ib and generates fake header files as though they were objective c classes
00:13:25.839
then it creates a temporary xcode project tosses those header files into
00:13:32.160
there launches xcode against that project and i think it creates a
00:13:37.200
storyboarder you might manually create a storyboard for that project and then
00:13:42.480
you can drag from the storyboard into this fake header file so how many people think that that's
00:13:48.079
great come on it's come on it's genius it's fantastic what if you change code in the header of
00:13:54.000
course that goes nowhere so don't do that spoiled by rails console rail cbd
00:13:59.040
rake test it is worth it to be able to use the magic that is storyboard now rich showed some gems that are being
00:14:05.760
written and worked on in order to give you this kind of dsl for making and
00:14:10.880
designing interfaces i've played around with some of them i have not found any of them to be nearly
00:14:16.000
as natural or uh or easy to use as storyboards one of the benefits of storyboards for example is
00:14:22.160
that i can hand it to my designer and say just make it look pretty right and they can do whatever they want to that
00:14:27.760
as long as they don't uh screw up the associations that are set up and we're all good
00:14:33.120
all right okay so the next thing that's too far is
00:14:39.440
bundler so we have a blog post you follow that url to get that blog post we're gonna
00:14:44.639
put these slides up or to tweet about them so you don't have to write any notes down right now um or you just search rubymotionbundler
00:14:50.320
and you'll probably find that blog post um including bundler and rubymotion is really easy
00:14:55.920
basically you just modify your rake file so you do require bundler and then a bundler.require and it uh
00:15:02.639
loads all of the um loads all of the gems that you have in your gem file that's in your your
00:15:08.000
repository just like you would with a rails application so now you can use gems like bubble wrap and things like
00:15:15.360
that that are built for ruby motion you can also install the gem cocoapods so
00:15:21.120
in here we've got our gem file that has the cocoapods gem set up and then once we have the cocoapods gem
00:15:28.160
cocoapods is like a bundler like rich when it is a little bit cocoapods is sort of like a rubygem system for
00:15:34.639
uh ios developer for objective-c development right um so we kind of bootstrap from
00:15:41.040
rubygems into cocoapods into now we can define these pods here and here we've
00:15:46.880
got a couple of pods defined like rest kit and cocos2d things like that um
00:15:52.560
when i looked at the specs rich said there's 600 pots when i looked at specs about three months ago i think is when i
00:15:58.000
when i looked last it was about 450 pots it's probably grown since then yeah that's why we put in counting we were
00:16:03.519
actually too lazy to really check yeah over there very close um but cocoapods are great because it
00:16:10.480
used to be the case you have to download the the code for an objective-c library and uh
00:16:16.720
dynamically link it into your app and cocoapods takes care of all that for you and dependency management and everything you expect from a package manager right
00:16:24.880
okay so now let's look at a couple of ios patterns and how they look when you're using ruby and again i'm not
00:16:31.519
focusing too much on the coco framework because we want to get more into the
00:16:36.560
into the client server stuff so let's look real quick one of the things that you have to do
00:16:41.759
differently if you're used to being a ruby or especially a rails developer you have to think about
00:16:48.560
mobile development very differently you have to think about memory right so one of the patterns that's built into
00:16:55.519
uh map view controller and also table view controller and a few others is that it will automatically try and reuse
00:17:02.240
components for you in order to save memory and not constantly be allocating stuff
00:17:08.079
so that's really hard to see so let me try and bump it up here
00:17:13.919
in here what we've got is a map view view for annotation right
00:17:19.360
and we first try and dq a reusable annotation view with identifier oh my
00:17:25.679
god i love coco so much um and then if we get that view then we
00:17:31.440
set the annotation and configure it however we want and that's for a little flag that shows up on a map right if we get uh one then
00:17:39.440
that means we have one that's no longer visible on the map area we can reuse that so let's use that um if we don't
00:17:46.480
get one if that's nil then that means we just have to instantiate a new one and we give it the when we instantiate it we
00:17:52.720
tell it what the identifier is view identifier using and it just goes ahead and uses that so it keeps kind of this
00:17:58.720
cue of recently seen annotations when you're scrolling around the map and if you need to show a new annotation
00:18:04.799
somewhere else in the map it'll just reuse that because it needs to pay attention to memory so one other thing
00:18:10.240
to note especially because we're all lazy is you have a tendency to cut and paste these dq reuse with blah blah blah
00:18:15.600
blah blah identifiers make sure you change the reuse identifier yeah you'll get some really fun behavior if you don't change that
00:18:21.600
reuse identifier yeah good times um delegation is another pattern that's very popular very popular in um in the
00:18:29.919
cocoa library uh who here has who here knows the delegation
00:18:35.280
pattern as coco uses it okay about 10 um so basically what delegation the way
00:18:42.880
that coco uses delegation is um if you have if you're using a coco
00:18:48.320
library uh component that it doesn't have enough information to be
00:18:53.600
able to do everything it needs to do you give it a designated delegator that it constantly calls back to with predefined
00:18:59.840
method signatures saying hey can i do this or hey this happened what do you want me to do right it's like 99 of the
00:19:06.240
time that delegate is actually yourself as the controller um so yeah sometimes
00:19:11.520
it isn't i mean i think the way that they normally describe it is don't call me i'll call you right and it's good
00:19:17.200
object-oriented design and um in general actually i learned a lot of about really good programming by reading this book
00:19:25.679
coco design patterns that came out recently very good book so anyways you can see here that for the
00:19:32.240
table controller we've got two delegate methods that we've defined one is table view number of rows in section it
00:19:38.480
gives us the section and basically that's saying how many rows do you want me to display dude and the second one is
00:19:43.840
table view sell for row at index path and that says give me the view that
00:19:49.280
should represent that or give me the cell that represents that view at that space basically tell me what to
00:19:54.720
draw when i'm drawing this cell inside that method by the way it also uses that same memory management pro
00:20:02.000
pattern that we saw earlier where it tries to reuse those cells whenever it can so as you're scrolling through a
00:20:07.760
table view when they go off the screen they'll try and reuse them as you need new ones
00:20:13.600
but uh but yeah so that is the delegation pattern now delegation
00:20:18.880
um delegation was also there at the time because objective c uh didn't support
00:20:24.480
lambdas it didn't support uh anonymous procedures right see so when you whenever you had even a single method
00:20:31.120
that you needed to act as a callback objective-c forced or coco forced you to
00:20:36.240
define a delegate that was usually yourself and then whenever something fired it would call back to you
00:20:42.159
now objective-c supports blocks and ruby motion makes use of that by
00:20:47.520
mapping ruby blocks directly to objective-c blocks if i'm not mistaken so here's an example of using ui views
00:20:54.559
animation stuff you could say animate with duration and then animations you give it a block a
00:21:00.000
lambda and in there you define what you want the animations to be and how you want them to work and then when it's
00:21:06.080
completed it calls this other lambda that passes in a finished flag or whatever and then you can do you can
00:21:11.679
move on at that point much better than the delegation stuff the the times that you still want to
00:21:17.280
favor delegation is when you've got like 20 methods you don't want to be passing in 20 blocks into a method call so
00:21:23.600
instead you pass in a delegator which is usually yourself and then you define all those methods and it's you know it's a
00:21:28.960
good pattern so one of the things to note here is anybody how many people have actually played around with xcode objective-c
00:21:34.720
like most so how many people actually keep the objective-c documentation open while they code
00:21:40.799
every hand should go up right because nine times out of ten if you're curious on how you do something you need to look
00:21:46.000
up what the delegate is for that application right because the delegate is basically where you get to hook in your behavioral code um if you start
00:21:52.799
doing things and start messing with base classes or starting deriving from things you're probably doing something wrong and it needs to go into a delegate all
00:21:58.400
right okay so now let's get into the client server stuff
00:22:03.600
the first thing i want to show you guys is a library called af networking af networking is a low-level
00:22:10.640
http library written by the guys over at gowalla and basically they looked at the
00:22:16.080
the ns uh was it nsurl connection yeah um and they looked at and they said this
00:22:22.320
is not good enough there's a lot of things that it does wrong so af networking does a lot of things right for example it takes care of streaming
00:22:29.280
you can do progress monitoring you can do authentication you can um
00:22:35.679
all of the operations are actually implemented as ns operations so you can throw them into an ns operation queue
00:22:41.760
they all get run in the background i think via gcd grand central dispatch and then you
00:22:47.440
can pause and resume them and things like that i believe there's caching built into it
00:22:52.640
and you also get scene success and failures uh the built-in cocoa networking stuff
00:22:59.440
i don't know when it gives you a failure but it's not based upon the return code that comes from the from the server this
00:23:05.919
actually does failures based on the return code from the server which is the way it should be it's a really great net library and it's
00:23:11.440
one of the reasons why the the cocoapod system and the objective-c ecosystem is really cool because they
00:23:18.480
they have to be more concerned with correctness and memory management stuff like this and this takes care of a lot
00:23:23.600
of stuff for you it's really easy to use af networking let me bump that up
00:23:29.919
that's about good one of the nice things it does is it builds as much as possible on the existing coco stuff so
00:23:37.440
first we create a url which is a normal nsurl url with string hbsurl.com
00:23:43.679
and then we create a request an nsurl request that's also still just regular coco um and then we had this operation
00:23:52.080
af json request operation json request operation with request
00:23:58.320
oh my god i love you request success lambda okay yeah i get that and failure nil which because i don't care if it
00:24:04.559
fails who cares um another question yeah
00:24:14.720
yes matt's here actually uh there you are who wrote bubble wrap
00:24:22.480
bubble wrap is based on the original coco networking stuff if i'm not mistaken which has all of the the
00:24:28.159
problems that the the last slide showed you so yes the reason i'm showing
00:24:33.200
you this is because this is actually what you want to use as far as i know well i mean the problem with with the ios
00:24:39.279
community is that you don't see into a lot of applications as much as you do inside the rails community or the ruby
00:24:44.640
community there's a lot more transparency in the ruby community but um i'm willing to bet that very few
00:24:50.480
people actually use the the straight coco networking stuff af networking is very popular
00:25:09.840
yes yes af networking is also built on top of the same same cocoa apis that bubble wrap is using but af networking
00:25:16.960
adds the operation stuff right and it adds same response codes and things like that
00:25:23.600
it also returns straight json you can see that the js this is the last thing here is actually json it's it's already
00:25:29.200
decoded for you um there's something else i'm going to say about that
00:25:39.840
that's what i was going to say thank you thank you so that brings up kind of a bigger thing
00:25:45.520
that we're going to touch on later as well but yes there are a lot of really
00:25:50.559
interesting ruby libraries that really abstract away what the coco framework is
00:25:57.679
but if you ever think that you might need to migrate away from ruby motion god forbid
00:26:03.600
or if you want to see more examples from the community of like oh how do i fix this issue
00:26:08.640
relying upon the kind of the native libraries is a very good idea yeah so
00:26:14.720
just so you know once again part of the problem is that this stuff looks like ruby but it isn't it's like and it's
00:26:20.320
really funny i remember we were looking at some code samples tara and iron and i got to the end and i didn't realize until i'm like you're missing a curly
00:26:26.720
brace and he's like no dude this is ruby right you have to think you still have to think in an objective seat basically
00:26:32.159
right so it's always better to be able the other thing is if you look at the examples most of the examples that you'll want to translate into ruby
00:26:37.440
motion are actually written in like the basically the os 10 developer library the developer notes have a lot of really
00:26:43.600
great examples and they're like really neat zip libraries so a lot of time you just download the code just to see how they do very small functions so in order
00:26:50.400
to be able to translate it from objective-c into ruby motion you need to be able to sort of be comfortable with
00:26:55.440
unfortunately as long and ugly as those those method calls are yeah to kind of figure out what the name of that method
00:27:00.640
should be and how it actually translates over all right and af network is also built
00:27:05.760
for subclassing which makes things really nice so you can actually define um i call this my client they have example clients for twitter and for
00:27:12.400
app.net and stuff like that but basically once you define this class the subclass
00:27:17.679
is from the af networking client or af client i think it's called then it's very easy to get a url and just parse
00:27:24.640
the json right out of there from anywhere inside your application okay so the second thing i want to talk
00:27:29.840
about is sd web image it's caching asynchronous image downloader and this is just written by some dude
00:27:36.960
and that's the url right there here's the when i first wrote a ruby motion app that had to do a table view
00:27:42.960
with some images in there this is the code that i used to populate the images from urls in the table view
00:27:49.520
from s3 um now this is we just said this is what you're not supposed to do who here knows
00:27:55.520
why yeah matt you cannot answer who here knows why this is a bad idea raise your hands all right went back there
00:28:08.000
yes so to repeat what he says the call is blocking and your world will just freeze and horrible things will
00:28:14.000
happen people are dying i'm paraphrasing um
00:28:20.159
there's there's mobile apps for uh medical stuff so when you download synchronously god kills a kitten and
00:28:25.520
this is this is an important thing this is one of those things that it's like you're not used to this with ruby with
00:28:31.200
ruby and rails no that's not true we have that thread class remember that thread class and ruby there if
00:28:37.120
you're if you're if you've been writing big rails apps then you're like okay i
00:28:42.559
need to worry about how many back-end hits i'm doing i need to use promises i need to you know make them concurrent uh
00:28:48.000
maybe return status to the client or something if you're doing a lot of javascript work
00:28:53.279
still less so you have to worry about blocking with um with ios application development and
00:28:59.360
os 10 application development you seriously have to worry about this stuff any block is just you know a zero rating
00:29:05.120
on on the app store right so so this is bad because like you said it'll block for each image sit there for uh two
00:29:11.600
seconds while it loads it from s3 populates it goes on to the next one over and over again really great um
00:29:17.600
basically you get the the giant beach ball of death right and i don't know who this hippie is but
00:29:23.120
um i think we'll prob we're probably going to hire him um okay so this is sd web image
00:29:29.919
and this is how you use it here and it's really easy um all you do is you you include it via
00:29:35.919
cocoapods and we already showed you how to do that and then again you just get a regular nsurl this coco
00:29:42.720
coco url and then here you also uh do a placeholder a local image you're going to use while it's loading it and then it
00:29:49.520
adds a method set image with url onto your image view and so you give it the
00:29:54.559
url you give it the placeholder and it just does it it's just like magic uses a background thread or maybe gcd and just
00:30:00.720
loads it loads them all at the same time so it works really well very easy it's like a no-brainer so we've mentioned
00:30:06.880
this a couple times does everybody know what gcd is grand central dispatch you've heard about it like it's not some mysterious thing i'm not seeing a lot of
00:30:12.559
hands go up okay thank you doing it oh no i think people okay for
00:30:18.799
those who don't know what gcd is gcd was actually a way to do dispatch and get callbacks by actually assigning blocks
00:30:24.080
in c which was not a native feature of c right so it's a very efficient way so basically it's supported by os10 and ios
00:30:30.720
it actually has operational cues that you can put essentially a callback method in to be executed and
00:30:36.960
the system worries about scheduling it's much easier than doing threads right so a lot of times you'll end up using gcd
00:30:42.159
instead of doing a thread if you want to do like a regular running process or something like that so it basically
00:30:47.200
greatly simplifies things that you would ordinarily have to do in a threaded a multi-threaded environment yeah okay
00:30:52.640
um okay so here's the big one this is the this is the mother bomb of all like how you do client server stuff um with
00:30:59.360
ios and it's called rest kit it's built on top of af networking as of this new
00:31:04.799
version and basically it's an http json orm and it's written by the guys over at
00:31:10.880
gate guru and it's a wildly popular library something you could really depend upon it's also now a moving
00:31:16.320
target fun fun fun so within about two months rest kit 0.20
00:31:22.559
is going to drop and as you would expect from a point release it changes everything
00:31:30.080
so this this presentation is focused on the new api of rest kit 0.20 which is like i
00:31:37.279
said i think it's going to probably drop in about two months it's hard to say there's a development branch going on uh that is almost 100 different it's good
00:31:44.000
times um but reskit is really nice it's very easy to use and it's a very clean
00:31:50.159
division uh from an object-oriented point of view point of view and it's really good basically you write um a
00:31:56.080
poro i knew you were gonna per person god what god did
00:32:02.799
you write a plain old ruby object jesse did a presentation on maglev and just ripped into anybody who calls it
00:32:09.279
poro so go yourself jesse um and then you tell reskitt what json to map
00:32:14.799
and how and then you get a url and like magic rest kit goes through all the way back
00:32:20.880
and returns to you you're plain old ruby objects which is really nice
00:32:26.399
unlike active record you don't have to write your your classes you have to write your models such that they know
00:32:32.480
about active record jesse you better plug your ears for the next three slides there's no system
00:32:38.080
in ruby that can persist classes like this when they don't know about uh okay
00:32:43.440
moving on uh so so you write a a a poro and um here we
00:32:49.919
got just class person with two attributes everybody everybody's rubio everybody knows what that is right
00:32:55.600
um and here's the json that we're going to get back from the server uh this
00:33:01.360
is by the way anybody and you may come on read the data
00:33:07.039
i didn't think if i could get that i'm touched classic of sitcoms yeah creepy um so
00:33:12.640
this is the json that is actually can somebody help me out is this the standard json that's
00:33:19.200
returned from rails when you get slash people yes this is not the active model
00:33:24.799
serializer json right
00:33:31.519
okay i use by the way who here has used jose villem's active model serializer
00:33:37.279
seriously holy crap it is so good it's perfect for json servers it's beautiful and it makes
00:33:43.279
everything clean and nice anyways so this is the json we're going to get back from the server and we already know this
00:33:48.320
ahead of time we don't need to control that and now we just tell json what js or tell reskit with json to map
00:33:54.880
it used to be easier it's like half the lines of code but with the new version of rest kit this is what you have to do
00:34:00.799
so it's a lot of fun this is your app delegate this is the main god class for your entire
00:34:07.760
application it's called the app delegate because it is set as the delegate for your application so whenever whenever
00:34:13.919
your application needs to ask a question it asks your app delegate it's also usually the junk drawer for oh my god i
00:34:20.159
just need something global right so the other thing is how many people are starting to see exactly how c-like
00:34:26.000
ruby development can be yeah it it looks like i'm developing coco right
00:34:32.639
sorry uh objective c um so what i have here is in and this is actually this is
00:34:37.679
not the cleanest way of doing it you should be pulling it out into another server class but i'm just doing it here
00:34:42.879
to make it easy to illustrate um in your application did finish launching you were with options
00:34:49.440
you get a url for the back end set it to an accessor called backend that we have set
00:34:55.679
there and then you add a couple of mappings you have this person mapping which over
00:35:02.079
here you've got this hash it says for the class person map it with this dictionary id maps to
00:35:07.280
remote id and name maps to name right and then i add that mapping for
00:35:15.040
all successful response codes and um
00:35:21.119
with a pass in the mapping there and then i add that descriptor to the back end it's complicated but it's much more
00:35:27.599
flexible than it used to be so it's actually it is actually a win believe it or not so up here you can see me calling it so
00:35:33.040
basically i'm saying if i ever receive anything that's that's got the the key person
00:35:38.320
then assume that whatever's after that is going to be for the person class and map it using the id to remote id name to
00:35:44.480
name mapping that i passed in same thing if i ever receive something plural people assume that it's a
00:35:51.440
part of that class and map it in the same way rest kit takes care of the fact that one is a singular and one is a an
00:35:58.640
array rescue will just take care of that it'll figure it out it'll assume assumes that they're all people right
00:36:04.480
then i just get an arbitrary url that's the wrong direction there we go
00:36:09.920
um so here we're in some other view and when it appears we go ahead and initiate
00:36:15.520
a uh a network request uh here i'm using app.delegate that's
00:36:20.560
actually a bubble wrap feature um one of the nice ones there and i'm asking the back end to get
00:36:26.480
objects at path slash people and i'm not passing any extra params although i could just be a hash and i get a success
00:36:33.200
lambda and a failure lambda and once once those callbacks trigger then i can modify my view to uh to have all the
00:36:40.000
rest of stuff there and it returns your models like magic so
00:36:45.760
inside that success lambda you have operation and result i don't even know what you're supposed to do with
00:36:50.800
operation but the result if you call i think the operation is the operations queue i think it is the
00:36:56.240
operation queue so then maybe i could re-cue it say you know i want to do it again or something like that i don't know
00:37:01.359
um but the result.array returns the array of person objects if i know that i'm getting what should be a collection
00:37:07.920
that i'm going to call result.array if i know that i'm getting what should be a single uh instance then i call
00:37:13.599
result.first object and it just returns to the first one if there's any in there
00:37:19.280
and that's that's the basics of rest kit um you can also that's that's for just
00:37:24.880
reading you can also go into full crud and here how much time do i have seven minutes so that's not good okay i'll
00:37:30.880
speed up a little bit for full crud uh we have to so first we told it how to map stuff when i did when i get a
00:37:37.680
response now i need to tell it how to map back if i'm doing a request right
00:37:42.800
so we say add request mapping which is a method down here that uses that same person mapping this is the same method
00:37:49.040
we had before and reverses it saying we'll just map it backwards right
00:37:54.480
and tells it what what the key should be which is person and that's it and from
00:37:59.599
that point on we can also do well and then also sorry
00:38:05.280
because now you're doing a full crud you could just have your app embed all these arbitrary urls throughout the
00:38:10.720
application that gets really messy so rest kit includes a routing system as well so i could set up a get route a put
00:38:16.480
route a delete route and a post route for um for the person class and i tell it what
00:38:22.640
the pattern is for that url and it'll it'll ask the person for remote id to
00:38:28.079
fill out that url when it needs to and i just add them all to the router and then
00:38:33.760
it's as simple as saying if i want to create a new person then i just say post object person and it'll post it with the correctly
00:38:41.359
nested attributes for a rails application to consume or i can update a person
00:38:47.920
and again because this is the update method we told it that the the path has remote id so it'll ask um it'll ask the
00:38:55.200
person what its remote ideas and figure it out so it works really well
00:39:05.760
oh no because you don't need to with rails rails only has underscore method in the forms because browsers themselves cannot
00:39:11.839
understand put but once you hit rails as uh no this is a put but if you're but
00:39:17.680
this is via an api so once you if you do a put to rails you don't need underscore methods it's actually talking about the
00:39:23.359
typo or do you have a type yeah because we put post on the bottom oh thanks jackass uh yes so sorry typo supposed to
00:39:31.200
say put down there thank you we told you shut up questions i was going to show a demo but i'm really
00:39:36.720
running out of time and i want to get into the more important rest kit can do the demo is really
00:39:42.880
simple just a table view reading writing it'll actually be available later
00:39:48.720
rescue can do more it can do object relationships so people have have many tasks and you can you know do full crowd
00:39:54.160
on those it does core data it does some caching you can do image uploading and all kinds of stuff like that it's a
00:40:00.079
really powerful library the big question probably everybody really came to talk about is is ruby motion worth it
00:40:07.119
so first let's talk about some of the bad aspects of ruby motion so
00:40:14.640
rich kind of talked about this but honestly i kind of felt it was danced around a bit you don't use
00:40:20.640
ruby gems most of the time you don't wanna because they're huge and they're not designed
00:40:26.560
for a vented callback like things they'll block and also and all sorts of things but even if you did you can't so
00:40:33.119
things like active support uh pluralizations and things like that you can't use that
00:40:38.800
um because ruby motion does not support the require statement because ruby motions you
00:40:44.640
mentioned that maybe it will require support required well
00:40:49.760
yeah okay but not but not to to pull in third-party gems
00:40:57.119
okay yep um and and i say like again it's not necessarily a bad thing but it does mean
00:41:03.599
you end up having to re-implement some methods to get some conveniences that you might be used to
00:41:09.119
and there's so there's no require there's no eval you probably wouldn't want that anyways
00:41:15.760
this has gotten a lot better but we have seen while we were developing ruby motion apps some seriously interesting
00:41:21.440
bugs um so this one wrong number of arguments no negative what is that 13 billion
00:41:27.200
something for zero so clearly i didn't pass enough arguments into that um in that
00:41:32.520
method um it didn't give me a method name or a line number or a back trace
00:41:38.079
um but you know it was fixed uh laurent fixed it i think that one was fixed
00:41:43.839
within a week you know but that kind of roadblock because it's a closed source system i couldn't just dig in and figure
00:41:50.480
out what's going on so that that is you know something you should be aware of that you might end up having blockers for a short short amount of time
00:41:57.760
and it's moving fast so um when
00:42:02.800
we gave a presentation similar to this there was more just the basics of remotion over at uh barcelona byruco
00:42:09.520
and at that time um there were a lot of these bugs since then working on this i
00:42:15.200
think i've encountered two one was actually rest kit and the other one lauren fixed within a day so it is a
00:42:21.839
fast-moving system and there was no debugger support at all originally right you pretty much you were on your own now
00:42:26.960
the debugger sport which showed some of it so we're looking at things they're adding features still as of this very moment there's a
00:42:33.760
lack of what i would call strong debugging tools there is now gdb
00:42:39.040
which is good but how many people have actually used gdb how many people join
00:42:45.520
with no okay good how many people enjoyed it hey yeah of course you did brian brian
00:42:50.960
yeah um so i mean it's much better than it used to be you can use gdb but you don't
00:42:56.319
get even even the rudimentary xcode debugging is way above and beyond what
00:43:01.920
that gives you right so now like rich said there is a company working on uh a gui
00:43:08.079
uh debugging tool is that part of the ruby mine okay so ruby mine is working on the the gui debugging tool if you
00:43:14.160
want to use review actually one other question does that debugger include the symbol support because that was a big deal okay it does include simple support
00:43:19.200
that's good um okay i jumped through like three okay the
00:43:25.440
other one is that coco is huge when i first heard about ruby motion i'm like great i can write ruby apps it'll be so
00:43:31.760
simple and i can just you know call whatever i can use nokogiri and stuff no no no
00:43:37.200
you're still writing a coco app and that's the bulk of the pain yes and i actually basically laughed at him and
00:43:42.400
went back to writing stuff in xcode he likes to write it in c plus plus something was an m um the other thing is
00:43:49.119
it is closed source uh so that does mean that you know it is
00:43:54.640
a liability but it is an amazing team that's doing it go ahead
00:44:09.680
right so we i'm i'm fairly certain that rich actually has a medical team following lauren at all times
00:44:16.880
actually did i hear something about the code being an escrow rich yeah so what happens if if ruby what
00:44:24.400
happens if hip bike goes under okay i appreciate that because there are situations when you're when you're a
00:44:29.839
larger company licensing somebody else's code you'll have it in escrow with the knowledge that if that company goes under if they get bought something like
00:44:36.079
that you get the code be really interesting to see if hip by could do something like that for open sourcing the code afterwards right
00:44:43.599
apple it is possible to tell that this is a
00:44:49.440
ruby motion application apple you know i can't imagine why they would but they do other things i can't imagine either so
00:44:55.760
like break maps it's just a small liability right away realized
00:45:04.000
yeah absolutely no of course no no ios itself is a closed source system uh even after steve jobs died
00:45:12.240
he's not dead okay but here's the good parts the glory you get the expressiveness of ruby and
00:45:17.839
it is expressive this is um an example of a couple of lines of
00:45:23.280
objective c oh my god do i hate the syntax of objective c i actually like the coco framework because i think it's
00:45:29.839
a well laid out object-oriented framework for development is consistent it's nice objective-c is so ugly and painful so
00:45:37.119
you've got like header files yeah about once a day i just see tamar pull off his headphones start screaming and cursing
00:45:42.960
i'm like what's going on did something die what happened he's like this makes no sense and i'll look
00:45:48.160
at his screen and i'll have some he's trying to type a ruby method but it's an objective-c method like you know we'll call application with delegate and
00:45:54.240
animation plus your mom and he's basically sitting there cursing at
00:45:59.280
him like dude it's just it's this is where you have to remember it's still objective c you're writing no matter how
00:46:04.480
much you think you're writing in ruby it's still objective c right and here's another example this is that
00:46:10.160
same table view thing with the with the reuse of cells i am not going to go through how this works because it hurts
00:46:16.480
right but it's just it's so less expressive it's so hard to understand what's going on um no more xcode this is
00:46:22.880
my favorite as well uh this how many people have followed the the tumble of uh um text from text from
00:46:30.079
xcode it's hilarious it's great
00:46:37.280
this this happened to me on a daily basis and i xcode crashes so hard that
00:46:43.520
people are like well you need to wipe your xcode directory and reinstall xcode hammer still believes that your devtools
00:46:48.560
shouldn't troll you right i've used dmacc so i'm not quite sure if that's true and and so you can use
00:46:54.880
whatever editor you want put that slide in didn't you um so you could
00:47:00.400
no i mean frankly you're going to code it in vimeo and drive it with rake that's how a unix kid does i mean
00:47:06.240
come on and it feels great to not have to launch xcode the only time you have to launch
00:47:11.440
xcode is to do that storyboarding stuff and it's not very painful but this is this feels good
00:47:17.040
um and you're using the same language as you use on the back end you're not going to reuse a lot of components because like we said you can't use gems you
00:47:23.680
might be able to like cut and paste some stuff that's about it but more importantly you've got the same skill set on the front and the back end and
00:47:29.599
that's actually really important for building a product and building a team um it smooths things out right
00:47:35.599
and you've got the ethos of the ruby community very interesting that in objective c you can actually basically
00:47:41.760
do anything you can do in ruby with the exception of the fact that apple won't allow you to avow stuff at runtime right
00:47:48.400
but the objective-c community is just they're so against anything that's at all magic they want everything uh very
00:47:54.880
wet just very laid out like repeat it over and over again because they don't get just boilerplate they don't care um
00:48:00.160
ruby's not like that and so it's interesting to me to see where some of these libraries are going to go in terms
00:48:05.520
of making things much easier yes in the back same token i find it odd that you guys
00:48:10.880
are talking about like avoiding abstraction and just using the straight
00:48:16.800
uh ios calls as much as possible i kind of think you're already you already have a lot of code that's going to need to be
00:48:22.640
migrated regardless if you need to go to your ios so so let's just say everybody else could hear you're saying what
00:48:28.559
you're saying is that why would we be advocating this level of extraction when you already have to do this well no he's saying we've already said that we would
00:48:35.920
not encourage this level of distraction now we're talking about how it's a benefit oh well see okay here's the difference what we're not encouraging is
00:48:41.440
a level of not understanding what your extraction abstraction is and when it breaks so the perfect example of this is
00:48:47.280
how many people remember the off by one errors like in active record originally where people would pull back all
00:48:52.720
and then you'd see all dot first you know or all that and then you have an array index and they'd use the first one
00:48:58.319
that's a breaking abstraction because people don't understand what they're doing when they do that it's before scopes of course right um and before
00:49:03.920
april yeah um and and also importantly um uh i'm just conservative so i think some
00:49:10.480
of these abstractions will become good maintainable abstractions but it's
00:49:16.079
always the case that the first ones are abstractions that you cannot build upon and so we're going to avoid that stuff
00:49:22.079
that's how we are but go ahead and rich what's interesting is the entire talk was about the extractions built on top
00:49:27.359
of the built-in ios apis yes so you went through all of those and there are okay abstractions to use
00:49:33.760
but you don't want to use the pure ruby abstractions which you can actually see the source code for the same reason that i just said because i'm conservative
00:49:40.000
rest kit is a very mature library no for 4.20 but you could still use the
00:49:46.559
previous version of rest kit because it's totally stable and you're right though rest kit did make a big change and i wish they had
00:49:52.079
bumped it to a major version when they did that they should have when they do semantics between what are you trying to do you're
00:49:58.559
trying to build a prototype or you're actually trying to flush and not in production and you're gonna make a lot of money
00:50:04.000
right because for instance i would disagree with what you said about opera i think override is actually what you should be using at the beginning the
00:50:09.520
first time but as you get something more complex and you might need more you're not going
00:50:15.280
to see more users using the libraries you might want to do something that's between objectives yeah that's a decent
00:50:22.400
point can you summarize yeah his summary is he it is possible to view ruby motion as a
00:50:29.520
prototyping tool um and then maybe it will build with you but if you're doing that you should start with the simplest
00:50:35.599
thing and and uh he posits that his library is the simplest thing bubble wrap who's speaking over here
00:50:42.640
so no and so the other thing is to remember is that objective c has a much longer history in terms of its level of
00:50:47.680
abstraction um than ruby just bear with me on that i know that's a little contentious right but the
00:50:52.960
delegate patterns and the way they use mvc is literally hard-coded into the cocoa apis you have to remember
00:50:58.480
objective-c is the language in which you write a coco application right you can write one in c plus right
00:51:04.240
you just flip the switch and can actually do an scplus plus you know it will be upon your head if you do it but you could um so the thing
00:51:11.839
to remember is that you actually have to learn coco and you have to understand what coco expects your abstractions to be and if you fight against it you're
00:51:17.359
just going to have a world of hurt so which is one of the reasons why for instance you go you basically use the abstraction that
00:51:22.400
coco provides much more often than use the extractions that ruby or even something like rails would provide
00:51:27.680
all right so right so the question is production versus demo or internal tool now when we
00:51:34.480
gave this talk three months ago i said um i think this will be production ready like thunderbolt labs a very
00:51:39.920
conservative development shop would use this for a client application in maybe six months and that's how things are
00:51:45.440
progressing that was about three months ago right and at this point it's it's actually progressed faster i'm still not
00:51:51.359
sure if we would use this for a client application where we had to hand it off to client developers at this point but
00:51:57.200
it's certainly getting closer so um right uh
00:52:02.400
so we also we're writing a book uh an ebook on doing ruby motion with rest kits it's going to be done in about
00:52:09.040
two weeks to a month if you want to see example code and more in-depth details of how to do
00:52:16.480
some of the more advanced stuff with rest kit just follow thunderbolt labs on twitter and we'll announce it there
00:52:21.520
and that's it i don't think we have any time for questions we're a little over but actually maybe we could take one
00:52:26.800
yeah okay nobody's gonna stop me go ahead do you know optics respond with quietly the movie motion do they
00:52:34.079
follow that pattern yeah do null objects respond quietly
00:52:40.240
with ruby motion no it will raise us if you try and call a method on a null object you'll get um the normal ruby
00:52:47.599
exception on that so it tries to stick to ruby as much as possible just so you know the the pattern in objective c is because you can dynamically attach
00:52:53.760
methods using selectors and objective c if you call on a null selector it's not considered an error right
00:53:05.520
on your laptop um that's the same uh it's the same ruby semantics as uh ruby
00:53:11.040
motion any other questions sounds like that's it so thanks thank you very much
00:53:50.240
you