[ Silence ]
>> Today, we're going to be looking at Mobile Local
which you of course have already seen.
But basically over the last few days what I did was I rewrote
Mobile Local in my own interpretation
as iOS application.
And I'm going to use that as a demonstration
of what your iOS application might look like,
some advanced topics that you might want to use
as you're developing your application.
I just want to walk you through how you might take some sample
code that you seen and sort of deconstruct and learn from it.
So, let's jump over to the slides.
And actually I'm just going to present like this
so it doesn't mess with me if I can find my cursor.
Here we go.
All right.
So, with this example app, I've got several things that I want
to sort of present and give you sort of high level of overview
of how you might use them in your applications.
I've started by using a tab bar controller.
They explicitly use models to store some of my data.
I used a singleton patterns so it give you an idea of what--
how you might use design patterns
in your Objective-C code.
I've got a view that uses table views.
I'm going to programmatically instantiation
which is basically just creating a view dynamically in the code
and then presenting it rather
than pre-building it in interface builder.
We're going to look a little bit at blocks and callbacks
which I think was one slide in the lecture so far.
Tonight we're actually going to use them
to use asynchronous HTTP calls.
I'm going to use a little call location.
I just did reverse geo location
to translate my current location to a zip code.
We're going to use storyboard constraints.
So, you can look at how you can pin things dynamically
to your interface and then, for example,
when you rotate the display,
things end up in a logical location as supposed
to just some are random.
And then I quickly show you how you can use unit test
to help test your application as you're going along.
Is that sound good so far?
You got a question?
>> In our project does it matter if we did this programmatical--
>> Instantiation.
>> Or just use the interface building?
>> So the question is for the project should you use
programmatical instantiation or interface builder.
And you can certainly use interface builder.
This is just-- if you find yourself in a situation
where you think it be better to dynamically generate stuff,
you'll at least have an example of how to do it.
I would do it in one small place.
Any other questions before we jump in?
All right.
Now, the first I want to do is just show you what the app
actually looks like.
If you're interested in check it
out that slides will be posted online,
the links will we posted online, but I've just throwing it
up on GitHub under my personal account gerbercj
and it's simply called Mobile Local.
If you haven't used Git, it's a great software development tool.
I have not fully exploited in this project
but you can do group development very easily.
You can do revision histories over time.
I've just got a single snapshot of my code
but it certainly worth checking out.
And if you install the command line tool is part
of installing Xcode, the get command should already be there.
So, let's look at what this app is.
All right.
So, I've got my standard project.
I'm just going to hit the run button.
[ Pause ]
And I'm going to bring the simulator to the right screen
and make it little bigger.
100 percent might be too much.
[ Pause ]
All right.
So, I've got my standard iOS app.
It's already started running.
You can see my location is changing over time.
This is actually one of the standard pathways
that Apple's predefined.
If you've gone into the debug menu and then location
which you can't see here, you can actually see
that this one is called Apple Stores and it just moving slowly
from location to location visiting every Apple Store.
So, as it's going, you'll see the zip code is also changing.
I've got some tabs setup here at the bottom.
I've got location, whether and news which you will remember
from the previous project.
>> Sir, how do you going to change the--
'cause in mine it defaults to Cupertino,
California or something.
>> So, the question is how you get it change location.
And the way I've done is simply under the debug menu
when you choose location I've pick one
that does move automatically.
So, they have things like custom location which is a fixed spot.
Apple Stores happens to be one that travels around.
If you want something out of smaller scale,
they have one that is bicycle ride.
So, it's a slower pace but it does move around the city
and you could play around with the ones in there.
>> Where is that?
>> In iOS simulator under debug and then location.
OK. And where's my cursor.
So, the weather tab.
I had to brand it.
I use whether underground as part
of their agreement to use their data.
I have agreed to put their logo on my page.
Well, you'll see it's currently sunny in wherever this is 85320,
it's 103 degrees so I'm happy to be here
in Boston, much better today.
And I've thrown out the same temperature in Celsius.
And I can also pull up the news from my current location which--
I though I fixed this last night.
But I happen to pick a location that doesn't have any news
so I got an exception.
So, for the proof that I can [inaudible] code just
as well as anyone else.
But you people get the basic idea
of how the app works how close.
All right.
Let's look at how some of these things are actually implemented.
[ Pause ]
All right.
So, first I want to talk about is Tab Bar Controller.
I've put it-- in each case I put a link
to the Apple documentation where its applicable
so you can actually go back
and see how I learned how to do these things.
For this the only part we really need to look
at is the storyboards at least at this level.
So, we can go to my project.
It's around here somewhere.
There he is.
So, you see broken things out to model view and controller.
In this case it's part of the view.
So, we look at the storyboard for my app.
And we can hide this for now, we can hide this for now.
So, the tab bar controller, I've just dropped--
actually, I just created by default
when I did the file new for my project.
I chose this as my name type of controller.
And it created two of these views for me.
And you'll see it's automatically created
the segways.
When you create an additional view,
you can actually do the same thing we've been doing all
semester where you can control click and drag,
in this case it's already in there.
But it will drop your new view into the tab
for you automatically.
It's surprisingly easy to get setup.
So, theoretically if we pick another
like table view controller rather
than we could-- where do I do that?
[ Pause ]
Add that to the controller as well.
I'm going to take that back out.
Some of the interesting properties
that have used here is you'll see I've added icons
to each thing.
Theses thing are simple as going into the properties
and putting an icon in.
I've changed the name.
This was actually one of the easiest parts of the app for me,
it was basically all drag and drop, GUI stuff.
The magic of using interface builder.
So, this is the e exciting part of using a like Xcode
where you can drag these things together
and make your UI very quickly.
Basically all I wanted to show you in that.
We'll get to things that actually have more code
and those get a little more interesting.
So, models, we've talked about models.
I saw some of you in your Evil Hangman, did a good job
of [inaudible] some code out in the models.
But I want to talk about, you know, how it might work
in an application like this.
So, broken out of few ideas that we're going to look at,
we obviously have the concepts of the news,
the weather, the current location.
So, consider those to be sources of data, and therefore,
made them a model in my application.
News is actually composed of a bunch of articles.
I made news article class as well.
And we can start to look at what this look like.
So, in my models, you'll see the same things we just
talked about.
If we look at a news article, I probably going
to have to zoom this in.
[ Pause ]
Let's makes it easier and start with header file.
So, we're used to the interface.
I think that should be straight forward.
I simply got two properties and news article has a headline
and a URL, that's all I cared about in this case.
And I've built a constructor
where I can create a new news article with init
with headline and URL.
And behind the scenes, this should then make articles
that I know how to ask them what their headline is,
ask them what their URL is.
And ultimately it should read-- lead to more readable code.
Just at this level, does it sort
of makes sense what this thing is, what it looks like,
what this might feel like in code?
Getting at least one head nodding.
All right, it sounds good.
As we move on to-- let's move to location neck, well,
let's move to news next.
So, news should be all the news articles right.
So, this one is actually pretty simple as well,
it's going to have some sort of collection
in this case a mutable array that contains articles.
So, I'm not thinking about this is an array
of strings and stuff like that.
All I'm thinking about is news is composed of articles.
So, I feel like this already has in a layer of obstruction
that makes it easier
to understand what's going on with the app.
It's also got this refresh with location
with call back call back, I don't want to worry too much
about that yet but refresh with location, location sounds to me
like when I know there's a new location,
refresh your data right.
It's-- that will get a little more magical with call back,
we'll come back to because that's
where things get a little weird in this example.
Whether it's going to look very much the same
but we've got a lot more data.
So, we've got temperatures, conditions, observations times,
we've got image name and image URL.
Not too bad.
Those should feel pretty logical.
We've got the same sort of refresh load location.
I want to make my code mirror self as much
as possible for consistencies.
So, when you see refresh load location,
you get the same idea again.
I've also got this sort of help of function down here.
Is night time and this was a function that I wasn't sure
that it really was part of the weather.
But I didn't want to make another class it was getting too
late last night.
So, I stop here and the weather knows what time
of day it is for some reason.
Does this feel OK so far?
OK. And the last one then is location.
And location is the weirdest one.
All it's got is a zip code and a class method that is singleton.
And this probably does not look at all familiar
and probably seems a little odd.
I'm going to mute my sound again now that we don't need it.
[ Pause ]
Actually I was also going to look
at the details of one class.
So, we mentioned news article was just the headline
in the URL.
We've got a quick and meet with headline in URL.
[ Pause ]
Does this pattern look familiar to folks?
We've got the basic idea of it.
Initializes its super if that worked.
We can set the headline to the headline, the URL to the URL.
Do folks remember why I'm using an underscore here.
Yeah.
>> All of this by default [inaudible] before the name
of the property.
>> Exactly.
So, the answer was the property is
by default are putting it underscore
in front of the property.
Sort of behind the scenes, I was magic stuff
but that basically says I'm accessing the property directly
without going through its setter,
directly manipulating the data.
>> Sir.
>> Yes.
>> What's the difference between this underscore
and where is this with a self dot?
>> So, the question is what's the difference
between using underscore and using self dot?
If you use underscore, you're going to get direct access
to the variable and you can manipulate it.
If you use self dot, it's actually going
to use the setter method, so a lot of times
when you create a property you don't bother setting--
creating a setter method.
It just uses the magic one which doesn't do anything special.
But you could have a setter method that does things
like check to make sure the data is valid before it actually
makes a change to it things like that.
So, by using underscore, I'm making sure
that if there's any other magical stuff going
on I'm ignoring it in this case.
>> Is this a set of function here?
>> This is the constructor.
So, at this point, I know I'm in charge
and I'm doing everything I want to do.
So, I didn't want to kill that.
>> So, we are setting the header lines rather than (inaudible)
and this four header line goes for heading?
>> Yes. So, I'm still just setting the headline value here.
>> And self dot headline also give the setter right?
>> Yes. If I had used self to headline
in this example it would have done the exact same thing.
[ Pause ]
All right.
I'm going to stop, I thought I muted you.
[ Pause ]
Apparently I can't mute, that's interesting.
All right.
So, I wanted to look at singletons.
So, you saw I had that singleton in there.
So, this is the idea of using a designed pattern.
So, the one design pattern was seen a lot already is the
delegate pattern.
That's pervasive in objective C especially in iOS development
where you can say that another class is going
to handle a method for you.
The singleton pattern as for Wikipedia is a design pattern
that restricts the instantiation of the class to one object.
So, what this basically says is I ask to create the object
and it gives me the object.
I ask to create the object again,
no matter where I am in my code.
It gives me back the same exact object as the first time.
Now, you might start thinking why would I want to do that like
in the idea of a string that doesn't make any sense.
I want difference strings within values.
Where I'm going to use it is in location.
And the reason I'm going to use it there is it's an example
of how I can have my news controller
and my weather controller and my location controller,
all ask for location object that has a zip code.
But they all get the same objects.
So, if the location controller is changing my zip code.
When the news controller or the weather controller asks
for the zip code, it's going to get the same point in memory
and therefore get the shared piece of data.
So, in a way creating a global variable,
I don't like global variables but this is an example
of how you can use a designed pattern
in your code more than that.
So, let's see what this looks like
and this is I hope the ugliest code I show you tonight.
And it's not my code, it's attributed in here.
And that was in location.
[ Pause ]
So, this came from a guy who told me
that I'm apparently doing them wrong and this is the right way.
And I trust them.
This is actually a pretty good approach to how to do it.
So, remember its class level.
And the reason it's class level is we can only have
one instance.
And if I'm first trying to get that instance
if I don't already have it, you sort again to this sketch 22.
You need some way that you can get to this.
So, the class let's me get there no matter
where I'm starting from.
They're creating a predicate
and a shared instantiation of the class.
Don't get too bugged down in how much this makes sense to you.
It took me a few reads through last night
when I was looking at this.
But understand that this works.
And what it's doing actually is it's creating a block
that allocates the location and initializes it
and then returns the shared value.
The bottom line is when you call this function,
it checks if the location has already been instantiated,
if it has it gives it to you.
If it hasn't it makes it and gives it to you.
Bottom line, no matter what,
it always gives you the same exact object.
Does this make enough sense?
You don't have to use this in your code.
It's just awareness of how you can start applying these ideas
in your code.
OK.
>> So, the shared in there never change?
>> So, the question is shared can never changed.
Exactly, shared, once it's set to value because of the way
that this dispatch once set
up it will always evaluate to the same thing.
[ Pause ]
All right.
I'm going to try to go relatively quickly tonight
because I figured the best use of the most
of our time is helping people with projects.
So, we're just clausing over some
of this but we'll keep going.
So, table views, table views are list of data.
You might have seen it on your phone as contacts
or something like that.
I'm going to show you where I've used it for the news
and then we can look at how-- how do we get there.
There it is, so this time we actually got news.
So, the Table view has a number of rows.
Those rows are coming from some sort of data source
and in this case, I also have disclosure indicators.
By conventions, those say when you click on this,
it is going to take you somewhere else.
Additional details should be provided at that time so it's
like your list of contacts, the details for each contact,
the list of songs, the actual details for that song.
In my case it's the list of news articles
and the actual article will pop up.
[ Pause ]
So, I've got the documentation.
Let's look at story board and [inaudible], OK.
[ Pause ]
So, this is my news controller.
It's got something that's apparently a giant table view
and prototype cell and the way this works
in any interface builder
with story boards is you basically tell it how
to build one cell and it can reuse that pattern
to build the rest of the cells.
So, if I know what one piece of news looks
like on the screen it can replicate
that for every piece of news.
[ Pause ]
This stuff-- I didn't use the built-in table view controller.
I took an existing controller actually
and there is a table view control somewhere--
there it is, somewhere in this list.
Just drag it in and then I drag the table view cell in.
I've got this.
I'll set up with the title in separately
but that's not a big deal.
If we look at some of the properties
of the Table view itself,
I don't think I set any properties for what I was doing.
For the prototype cell-- this is
where things got a little more interesting.
So, the first thing I had to do is actually name this cell
so you'll see this is a new cell.
So, in my code I can then say,
"I want another new cell to put news in.
I want another new cell."
You could have tables with different types of cells.
I don't know if a single table could have more than one type
of cell but if I have multiple tables,
those would certainly want different types of data.
This disclosure indicator came from the accessory.
I picked the one that looks like a little gray arrow.
There's one that has a blue circle with an arrow.
That generally-- it means if you hit that button specifically,
it will do something different than if you hit the text.
And there's one other whatever you have-- oh, check mark.
So, if you're doing some sort of task list or something,
that you could use that.
I also dropped the cell on and the one thing I had to do
with the cell, so actually I did a couple of things
with the cells so we can look at all these.
[ Pause ]
I chose for line breaks truncate tail.
So, basically what that does is if there's too much text
in this cell, at the very end it will just do dot, dot, dot,
which I thought was useful for this project.
Slightly up from there I set lines to one.
If I didn't have lines to one, it would actually try
to wrap the text and do multiple lines
so I could have used s smaller font and set lines two.
I could add two lines of text there.
The other thing I had to do is I used a tag.
So, I set my tag to one just as an arbitrary number
and I'm going to use that later in the code
to actually reference the cell.
And I think that's the quick tour
of everything that's in the story board.
If we look at the actual controller for this,
so we're finally getting down to the controllers.
[ Pause ]
We can look at the header first
and there's really not a whole lot here.
Nothing-- nothing too interesting.
But one thing we do notice is I've got some protocols
setup here.
So, chosen to use the UI Table view delegate
which basically gives me added functionality
around manipulating that table,
and its cut off here by UIWebViewDelegate.
We don't have to worry about that yet
but we'll just remember that's there for now.
[ Pause ]
The code gets a lot more interesting now.
[ Pause ]
Let me see if I can get this closer.
There we go.
So, I've got a few things.
So, I've moved my-- what I'm calling my private properties
into the interface here.
Certainly, we can do this is the dot h file no matter what these
properties will be exposed to another object
that knows about them.
But I sort of like the idea of when I get my header file
to someone else, they only know about the things
that I want them to know about.
So, I've included them here.
I've got a few things.
I've got my location which is a location object--
we saw that before, and my news which is a news object,
which we know will then later be composed
of news article objects.
I've got two IBOutlets.
One for the title, I sort of gloss stuff
that there was a title at the top but obviously,
if we want to change the title, we need access to that,
and access to modify the table itself.
Any surprises there so far?
All right.
We've got some standard stuff when view loads--
I create a new location with my special singleton method
which is probably not a new location.
It's probably the same location
that someone else already requested.
And I allocate some space for my news.
I broke-- a part view will appear from viewDidLoad just
because they are suddenly different.
When the view loads, that's a great place to do manipulation
of your data to get things into a configured state.
When viewWillAppear happens, that is great
as the views about to appear.
So, wait to that point of my code to actually do my updates.
And I've written a separate method for that because I want
to call that from several places.
You could, in theory call viewWillAppear from other places
in your code but it's really poor practice so I've factored
that out into its own method.
[ Pause ]
The update has this magical news refresh complete block.
We don't know if that is
yet so we're not going to worry about that.
There's some stuff about refreshing the location.
We'll come back to that.
Setting the title doesn't seem too bad.
We-- at some point, a zip code is going to be set.
We can set the title to news for zip code or unknown zip code.
But this is where things start to get interesting.
These are functions that we don't normally see
in our code, right?
We've got number of sections in table view, number of rows
in sections, [inaudible] index path.
I knew we looked at this quickly in lecture.
Do you folks remember what number of sections
in table view does or number of rows in section?
[ Pause ]
Ray [phonetic].
[ Inaudible Remark ]
>> Yes. The first part of the answer--
sections are groups and I've got mine set to one
which basically means I just have one group
for all my records.
The other one was number of rows and section.
So, this is going to be--
[ Inaudible Remark ]
>> Yeah. The number of rows in that section or in this case,
the number of news articles that I want to display.
So, that will be as you might read, my news articles count
so this is another place where I see the idea
of using these classes,
these models upfront gives you some readability in your code.
I sort of like the idea
of return my news articles, their count.
That sort of reads to me almost like a sentence.
I don't know.
It makes me happy.
[ Pause ]
For the actual cell at any given row, it basically--
I'm getting a call through this delegate where it says,
"I don't know what to put in these cells as I create them."
You tell me, for example row three, what goes in row three?
So, it comes to me and I say, "OK, I will make you a cell
that is a new cell and I'll populate it by setting the--
so, I will get my headline which is my-- from my news articles,
the object at index, index path row.
So, there's a lot things going on right there
but it's not too bad, right?
We've been told I want row number three
so get me the news article at index three
which should be the third news article.
I'm just telling it for sure that yes,
this is going to be a news article.
And in news article, I know has a headline.
So, let's use that as my headline.
So, it's a lot in one line of code,
but hopefully it still make sense what's going on there.
Does-- do people sort of get what that's doing?
All right.
And then find the label in my cell,
this is where I mentioned I had to tag the cell.
So, I find cell 1, tag 1.
And then I can set for that label, set the text
to the headline I've just looked up, and then return that cell.
So, they've asked me what does cell 3 look like, I say,
"It's this cell with this headline filled
in here, here you go."
Does that feel good to people?
All right.
The other side of that is, you know, I click on these cells,
I want the news to show up.
We're not going to get into this part yet,
but upfront you can see that an article for an object
at index row also has a URL.
I want to be able to show that URL.
And we'll get back to how I actually did that shortly.
Do people see how the table view controller is roughly working?
Those four methods are sort of the core
of what you need to know.
How many sections, how many rows, what's in each given row
and what happens when I click on a row.
That's 90 percent of your used case right there, right?
All right.
[ Pause ]
So, let's jump to the next topic.
So, programmatical instantiation which I just love typing out.
It even comes up as spelled wrong even
if I swear that's got to be right.
It may not actually be a word.
I could be making things up at this point.
So, when we quickly looked at my story board, I don't know
if you noticed but there was nothing continuing on from here.
When you got to the news controller, that was it.
But when you actually click on a news article,
this window pops up, the web page renders like this,
this is magically happening.
Where does this come from?
And this is the code we were actually just looking at.
Let's come back to this.
[ Noise ]
Shift my thumb by one.
All right.
So, how did I do that?
Basically, I'm going to build a web view
because I want to show web content.
I'm going to build a controller to put that web view in
and then I'm actually going to show
that controller on the screen.
So, on a very basic level, do those three ideas make sense?
Get the view, put in controller, controller pops up.
To do this, basically, all the things I would've done
in the gooey, I'm doing here manually.
So, I create a view, so that's just the same
as dragging one into the pane.
I'm going to set the size to the full size of the view.
So, that's just going to be as big as my screen.
I'm going to set my delegate to myself
so I can send messages back to this controller
which is the same as drawing, holding down control,
dragging back to the files owner.
I'm going to set my view.autoresizingMask.
This is just something that I found helpful.
It makes sure that the view is exactly the size--
full size of the display.
So, if I calculated my view run before, this will stretch it
down to make sure it fits.
And this view, because it's a web view, needs some content.
And the way I do that and the way you would do this even
if you had created a web view
in the interface builder is just tell that view
to load a request, it needs an NSURL request,
and the request is for a URL.
So, we knew my URL is the http:somenewsite/somearticle.
I just passed that along to load request in the view,
will load that content and deal with rendering
and all the magic for me.
Does that work good?
Okay. The controller is this wrapper that's actually going
to handle everything else.
And it's pretty straightforward.
I'm just going to initiate a new view controller.
I don't have a nib file.
I could have a nib file but this is--
I'm just creating one dynamically out of nowhere
and there's no content.
This is just an empty view controller.
I'm setting the view to view.
Let's see if I can get that to scroll back.
[ Pause ]
Too far. But I'm setting that controller's view
to the view I created so it knows to plug that in.
I'm also setting a controller navigation item left bar button
to an init with bar button systems.
Basically, at the top of that controller,
you saw there's a title bar.
A view controller will have that title bar.
I want that title bar to have a done button in it.
So, in the upper left, there was a done button.
That means my left bar button item is a done button.
It says, system item done.
And what happens when I hit that button?
It's going to look to me as the delegate to do something
and that something that's going to look for me
to do is execute a method called dismiss URL modal.
This is how I think about it.
It probably would have been easier
to call it close the window or something like that,
but we're dismissing the URL view and it was modal,
it was on top of the screen.
I've probably been doing this too long.
Except for the naming of that selector,
does the idea make sense?
I'm programmatically creating a button in that bar
on the left that runs the method.
All right.
And-- yes?
[ Inaudible Remark ]
>> Yes.
[ Inaudible Remark ]
>> So, the question is you can do all of this
in interface builder, right?
You could.
There are times when interface builder ends up being more work
than you want or where it just doesn't makes sense in general.
So, this might not be the ideal example,
but let's say I wanted to, say, make an array of 26 buttons
with the letters of the alphabet.
I didn't want to drag them all
onto display and wire them all up.
Things like that, Evil Hangman,
you could have done those buttons by creating a loop
that looped and made 26 things for you and does it
in a consistent way, make sure that it gets A
through Z specifically, they all get the exact same properties,
it's not copy-paste, though I changed one now
that they're out of sync.
By doing it programmatically,
you can do things more consistently and do things
that might not otherwise be possible.
So, actually, where I do this at work,
my company serves mobile ads, we download the content,
we create things on the fly
and we dynamically create the ad for you.
So, that's the case where we don't know what the content is
going to be until it gets downloaded to the device.
You had a question?
[ Inaudible Remark ]
>> So, the question is does it show
up as a connection in interface builder?
It does not.
So, interface builder will create a nib file
and the nib file will get instantiated into your runtime.
This code only exist at runtime so it doesn't exist
until you hit play and it doesn't exist
after you terminate the application.
So, there's no way to like persist it.
It's just a-- at runtime-created state of the world.
All right, any other questions?
I think-- I think there's only one last line here.
So, the last bit is I'm just allocating a navigation
controller, initializing it with the web view controller,
and I'm saying animated so it pops up live in the screen.
But this is sort of like template code,
this is like how you do it.
There wasn't anything special about me doing that.
There are few things I schemed over.
So, I mentioned, it's going to callback through the delegate.
This dismiss URL modal, I've implement
that because the protocol says I will.
The implied protocol appears as I will do that
and it's just going to dismiss the view controller.
The other things I have down here,
you don't necessarily need.
I did it for completeness because it's a table view.
There's a method for can edit row at index path.
So, if you wanted to have a list of things
that someone could edit.
So, we did a grocery list and someone spelled eggs wrong.
They only put one G in.
And they want you to edit that cell.
This is how you would have to implement that sort of content
and it will give you a pointer to the actual path
and then you can think about how you want
to manipulate that content.
The other one is can move row at index path.
Moving rows gets potentially convoluted.
If you're interested in it and you're working on it
in a project, I'm happy to sit down with you.
For this project, I said no, you can't reorder the news.
But if you had a to-do list, it might be a useful thing to say,
"This is now a higher priority, I want to put
that row above another round."
And that's the start of how you would start to promote that.
You would say I'm turning that functionality on
and then I would have to continue adding methods
that implement those parts of that protocol.
Does that rough idea makes sense?
All right, moving right along.
[ Pause ]
So, blocks and callbacks.
This is probably as much as we showed you in lecture
and it's the very rough syntax.
I'm not going to spend a huge amount of time here
because it's probably easier to see it
with real syntax even though there it probably will still
look a little foreign.
I more want you to know that they are there,
give you an example of how they would work.
You won't necessarily need to use this anywhere in your code
but I did find a few APIs
where to get what I wanted done, I had to do this.
And this is the same sort of idea as we used
in our JavaScript, right?
jQuery would go out, it would create an Ajax request,
it would go out to a site to download some JSON,
but we didn't know how long that would take,
when it would come back.
So, we would actually set up an anonymous block of code
that would run at some point in the future
and then our method would end
and this would eventually come back and run this code for us.
This is the same sort of idea, I can set up a block of code
and in my particular examples, I'm using it
for the same asynchronous case.
I want to request the content be downloaded from the internet
and whenever that's done, I'm going to leave you a block
of code that will do something with that data.
So, in my case, when you get the JSON back, hey,
here is information and how you turn that JSON into a property
that is a zip code or a property that is news articles
or a property that is weather information.
The way these are syntactically laid out is a lot--
I find a lot more like traditional C. We have some sort
of return type, it could be void.
You have in parenthesis, a caret and a name.
So, this is sort of like a function name vaguely
and then you have a list of parameter types.
So, in a hello world type of thing,
you might have traditionally seen void, hello world,
and you might have passed in your argc
and argv something like that.
That sort of maps into the same sort of thing,
they look more like this.
So, you have, well, this is what I'm actually going to do it,
so I have a block type, so I've created my--
that should have been a block type up here and give it a name
and that is essentially assigning a variable to code.
Now, we're used to assigning variables to an object
or to an integer or things like that.
This expands that idea to the idea that you can store blocks
of code in a variable which is kind of a neat idea.
It's common in a lot of other languages
and it's a really powerful concept.
We've got perimeter types, we've got perimeter names
so whatever perimeter names I give this,
those are the variables I have access to.
So, you know, pram type int, this is some sort
of value X. I can then manipulate that value X
and return a value back to wherever this block came from.
>> What's the difference between [inaudible] a new function?
It is not as [inaudible].
>> So, what's the difference
between defining a new function and defining a block?
A function-- a function can only exist
in the space affronting in, a block you can send
to another scope and it will run using its previous scope
in that new location.
>> So, basically like I said the copy paste does interact just
the same code you copy to different places [inaudible]--
>> Is it the same as copy paste?
It's more a runtime situation, so it's--
I can write a function that knows how to-- for example sort.
If I have a function called sort, I could say it's going
to be passed A and B and I could pass it a block.
So, I could have sort something--
some set of values and tell it how I'm going to sort those
so I can create a block that is alphabetical,
reverse alphabetical and I could pass the function, the values
and the sorting method and that same sort function would use the
different block functionality to do different things.
Does that concept make sense?
The sort of [inaudible] with my idea
in my head as I was talking.
[ Inaudible Remark ]
Yes, so this case I'm thinking
about now is you could tell a sort function,
what sorting algorithm to use.
You could have a function called compress that takes some data
and takes an algorithm and that algorithm could be zip
for zip files or uuencoding or all sorts of different things.
And then in the future, if you wanted
to add a new compression scheme,
you would just create the new block and pass it
to the function and your old code would be unchanged.
>> Consider to something like class [inaudible].
>> It's similar to a class.
You could potentially use a class in similar ways.
It's more of the idea that you can package up that code
and deliver an entire bit of code to someone else.
Yeah, the class would be code and data
so it could do a similar sort of thing.
The other big thing, I'll try to-- if there's any things.
I don't have any more good answers, it does carry scope
with it which is interesting.
Well, let's take a look at what this looks like,
so we got the documentation--
[ Inaudible Remark ]
Yes, so the question is, is it like passing a function
in JavaScript and yeah, it's the same sort of concept
where you can pass functions around there.
Ruby [assumed spelling] uses the same ideas,
Liz [assumed spelling] uses the same idea as we can use lambdas,
things like that to pass code around.
All right, so this is the second scariest code I will
show tonight.
[ Pause ]
So, this was blocks.
I put the storyboard there, I don't think we actually need
to look at the storyboard for this.
We can go right to news view as an example.
[ Pause ]
So, here is the function that we sort of schemed
over before for update display.
If we start-- if they ignore that this block is created,
it's going to set the title as the first thing.
It's going to check if zip code is set.
Why did I do that?
I did that somewhere else.
Yes, so it's getting-- locations are responsible
for setting zip code.
So, at this point if I want to update my display,
I need to know if the location has actually found a zip code.
So, first I ask location A, do you have a zip code?
If it does, I want the news to refresh itself with the location
that the zip code said and this callback, news callback.
So, I'm asking the news model to do this for me
and when it gets done, I want you to run this code,
news callback which I have to find here.
So, news callback is a news refresh complete block,
it's going to take-- it's going
to pass me a parameter of success.
So, the news block, news is going to call me,
it's going to say, "Hey, success was this."
This is the sort of true case.
If it was successful, reload my data.
Reload my data is basically just going to ask the news object,
hey, what's all the data.
Does the idea make sense that I am going to say,
when you get done, run this code and that code is--
tell me if you are successful and if
so I'm going to rule out my data.
Does that basically make sense?
[ Inaudible Remark ]
>> So, this call back I've specifically said
for this function is going to be a news refresh complete block.
So, I specified that as the type of data just like I've specified
that this is going to be a string, I think.
>> So, can callback call other type of things
like callback and call function?
>> Callbacks can only be of the type that you specified.
So, I defined a method signature
for what these callbacks will be.
And that's because I need to know things
like this will pass success as a [inaudible] to me.
[ Pause ]
So, let's see what's going on in this news model
to make this actually happen.
[ Pause ]
In news.h, I've defined
that a news refresh complete block is going
to be given a parameter of success,
which is what we just saw in that other code.
So, it makes sense that this exist as a thing.
It also doesn't have a return value, it's just void.
Is that OK?
OK.
[ Pause ]
And this is where things get good.
So, refresh with location is going
to take a string for the location.
So, that's going to be my zip code, that 02140 as a string,
something like that, and that's going to take a callback
of type news refresh complete block
which we just defined is call the news professional complete
block and it's going to pass you a value called success
that will be a Boolean.
If I've got a location and I'll just skim
over how it knows whether it has a location.
It is going to do-- I'm sorry, location was just 02140.
So, my escape location is going to be a string
by replacing percent escapes using encoding.
So, this is the basic idea that we saw
in JavaScript before we need to escape our strings
or URI and code our strings.
If I've passed into something that has sketchy characters
in it, I want you to replace those with things
that I can send out to a website as part of a URL.
So, if my string was actually 02140 dash, number, number,
number, number, that dash would have been translated
to whatever the percent to whatever character is
that was safe to put over the wire.
That might not be a good example.
Spaces are a good example.
If this was actually accepting city names
and I wanted New space York, then it would replace
that space with percent 20.
So, similar to what we saw when we did this in JavaScript,
longer method name but same idea.
I'm going to build up the string
and this string probably looks very familiar.
We're going out to the Yahoo APIs, we're using YQL,
we're doing a select of the string that was built
up that's going out news.google.com,
it's going to return me some RSS.
[ Pause ]
I'm going to append in my location.
So, I'm building this string by appending pieces together.
So, after it says G-O equals, it's going to put
in the 02140 in this case.
And at the very end, it's going to include format equals JSON.
So, this was almost probably identical
to what you were building
up when you built your mobile local.
Does that look familiar?
Everybody remembers that this happened?
And then, I'm going to turn that into an NSURL
which is just how Objective-C likes to talk about full URLs
and it's just going to build that by taking that string
and turning it into whatever data structure it needs.
I'm going to build a request off of that which just takes the URL
and factors it up into an actual HTTP request.
And then I'm going to send it asynchronously.
So, I'm going to send them my request.
I'm going to send it to the main queue which is all we need
to know about at this time.
This came right out of template code and you could just assume
that in this case, the main queue is the main queue.
And this is going off the screen so let's get a little more code.
And it's got a completion handler.
By completion handler,
if you notice the caret again is another block which is going
to apparently have parameters of response, data and error.
So, I need to run-- I need to give it the code
to run when it gets done.
So, we've now got a block inside of a block.
But this one we sort of done anonymously,
the last one we said was a news block completion handler
or something like that.
I had a name type, it was well structured, we knew what it was.
Here, this is anonymous.
It's just-- these are the parameters I can expect back.
I don't have to create a block externally
and assign it to variable.
I can just build one on the fly.
[ Pause ]
So, it's got its types,
it's actually got its own pair of curly braces.
So, you see the square brackets were still inside one
giant message.
One of the parameters I happen to be passing in is this block
which has this code as part of it.
So, it gets visually a little weird to look at having blocks
of code inside my whole message and everything.
But basically, the code is simple when we look at it.
I'm going to get back some sort of JSON data that I'm storing
in a dictionary called JSON payload.
We are going to basically take the data that we got
and we are going to use this JSON serialization
to parse it into a dictionary.
So, it's doing all the magic for me.
It says, here's your data, mash it up,
here's my new value JSON payload.
And I am going to call the callback--
[ Pause ]
I'm going to give-- I'm going-- all right.
So, now, that's the things in a very weird way.
So, I'm going to take that payload and send it
to my method called process payload.
That's going to return a Boolean
that I can pass back as the callback.
So, if this method succeeds, that other piece of code
over in my controller will know that, hey,
new data is available.
If it doesn't succeed, it will know that it shouldn't bother
to update display because there's no other data.
This is some of the really scary code tonight.
How does that roughly feel?
Does the basic idea make sense?
I mean, its like inception at this point, we get the dream
within the dream, blocks going everywhere,
code jumping around, yeah?
[ Inaudible Remark ]
Sure, so the syntax of the pipe here.
So, basically, Options is expecting a value
which is some sort of probably giant number essentially.
And these are flags.
But they are basically just two values and this is a binary or.
So, if this was the number two and this was the number one,
I or them together, I get the number three and I've built
up some sort of bit patterns probably what really is being
used here.
Does that make sense?
People are comfortable that if they had to,
they could unravel this close enough.
Yeah, OK. So, the last part,
we go ask over was how is it actually processing
this payload.
And that's kind of important.
[ Pause ]
So, that is just this function which expects a dictionary,
returns yes or no for whether it was successful.
And if you remember the data structure, and I won't blame you
if you don't, for mobile local,
when we go out to the Google News API, its got query
at the first level, results at the level under that,
item under that, and then each
of the items is it's own little dictionary that has a title,
a link, probably a bunch of other stuff
that I don't really care about.
Can you sort of visualize how that maps back to that data set?
All right, cool.
So, I am basically just unraveling the layers
of that data here.
And the reason I broke it out like this is to try
to do error handling which as we saw at the beginning
of this night, apparently still doesn't work
but I'm getting there.
[ Pause ]
So, we check for the query object and forget that.
We go to the result object, we get that.
We go to the items object, we're finally at a level
where we've got data where we want to work with.
For each item which is an NS dictionary in that collection
of items, I can go through and get the headline
out and set that-- sorry.
Yeah, get the headline out, store that temporarily
for the title, create a URL from the link and store that.
And then I can add to my news, because we're--
[ Pause ]
Yeah, I can add an article which is an allocation
of an article initialized with a heading URL.
So, I take this news article, build it up and then use--
I've got an ad article function below that takes my news object
and depends that to my list of news items.
I've got a little gray there.
Does that make sense?
This is just another method I've got written
down at the bottom of my code.
All right.
So, if you were actually doing something
where you're reparsing JSON data, this is the kind
of template you can sort of cut and paste from my code and work
with to get data from some external service.
The actual add article function is not super exciting.
If I don't have any articles or I don't have an object
for the articles yet, I'm just going to create one
by allocating initializing array.
And once I've got it, I'm just adding the new article
to the end of the list.
All right.
We're almost through it.
[ Pause ]
Whether is going to look exactly the same, the code is going
to be mostly cut and paste all over.
So, I wasn't going through that.
And four more slides.
So, core location.
[ Pause ]
You remember this dot is moving around
and it's automatically doing the reverse look
up in finding me a zip code.
And I'm just going to show that portion
of how I did the reverse geocode.
So, this is all in our location controller.
[ Pause ]
Just looking quickly at the header,
you'll see I've got two imports here.
So, I've got core location and Map Kit.
I also had to include this in-- I should show you that as well--
core location of Map Kit that I include.
And the only thing in here really is the actual MapView is
a Map Kit MapView.
The other place that I had to include this is when you go
to your targets and go to-- what I get-- targets and build faces.
We don't worry much about this section in this class
but it's important to know that you can link with libraries.
And a lot of the magic we're getting for free
that Apple's provided for us comes from these libraries.
You remember the foundation.framework?
We use to see that all the time.
I've had it specifically that I want Map Kit support
and I want core location support.
There are all sorts of other choices, you can get access
to the accelerometer, address book, audio,
all the really cool prepackage functionality,
the APIs that you need.
This is where you're going to get them
if you do not have them included by default.
I don't know if anybody has got to a point
where they've had to this yet.
But if you haven't, that would be helpful.
If we look at the code for what we're doing here.
[ Pause ]
We will roll a little bit.
You see, one of the properties I'd created was a core location
geocoder, just a convenient place to store, I'm going to use
in couple places of my code.
As my view is loading, I'm actually going to allocate that
and initialize it so it's just available when I need it.
But where does this actually start coming in?
I've made myself-- I didn't point it out explicitly
but I made myself a delegate of the Map Kit MapView.
So, there's a protocol for that that gives me like the set
of tables your control or additional methods
that I can choose to implement.
The one that I chose
to implement is this MapView did update user location
and it will tell me which MapView
and what my new location is, which is perfect,
that's exactly what I'm looking for.
What I did with the geocoder is I do a reversed
geocode location.
From the MapView I can get my explicit location,
scroll over to the right here.
And we get to this completion handler again where it's going
to pass me an NSArray--
[ Pause ]
-- of place marks and something for errors.
So, we're back to this idea of blocks and callbacks again.
So, this callback, it says, when you've figured
out where my location or when you're don reverse geocoding my
location, give me a list of placements in any errors
and I can look at those placements,
actually do a center map on this location not just refreshes my
display for me.
So, the dot has been moving.
This is what actually makes the map move underneath the dot
and that's just a method I have right below here.
But the actual geocode-- reverse geocoding is--
my zip code is going to be look at the first place mark
and just tell me what the postal code was.
So, this place mark array that its handed back is a list
of things that map to that latitude and longitude.
I'm just using the first one.
You can get other things other than zip code.
There is things like street address,
approximate street address, at least city, state,
things like that, all the information,
it knows about that latitude and longitude.
I just needed the zip code and if it happened to get one,
if my function was successful, I'm going to update this--
what we member was a singleton,
a shared locations zip code to the current value.
So, now, that's globally available across my application.
And I'm going to tell it to update the display
which if you remember pretty much just updates my title bar
to have the zip code in it now.
All right.
And we're back.
So, the question, we'll just ask is-- next question--
oh, the code is available up on GitHub as I mentioned
at the start of the slides.
If you download the code now and try to run it,
there are two things that are moved from the code.
One is the images that I'm using for the weather icons,
those are from Weather Underground.
You can get them by searching for Weather Ground API icon sets
or it should automatically fell over
and pull them off the internet as needed.
The other thing that's missing is a weather underground API key
which is freely available from their API site as well.
Go in, create an account, they will give you a code
that you can plug in and it is at the top
of location.m. No, at the top of--
[ Pause ]
It's probably weather.
At the top of weather.m, you can provide your own API key here.
So, uncomment this and fill in the blank.
The reason that I don't need to do that is I actually cheated.
Oh, I didn't cheat-- I did the way--
things the way I would expect developers
to actually do them for the longer term.
In your project build settings, we saw all these stuff.
You probably haven't looked through it.
You probably never needed to look through it
and you may never need to look through it again.
But, I've set up preprocessing directives for the bug.
Normally, it just says the bug equals one.
If you look beyond here,
I've actually added a weather underground API key
and it's valued directly in here, so,
it's configured external to my code.
In theory, you could then--
if you're building this from the command line you can plug
that code in on the fly rather
than having it permanently embedded in your project.
So, it's just a nice way to do things
when you are committing things publicly in one place--
the one place but have private secrets you need
to keep somewhere else.
Probably not a big deal for this course
but in the professional coding world,
things like that actually become important.
All right.
We were looking at-- where are we again?
What were we looking at?
Core Location.
[ Pause ]
I don't think there's anything else--
were there other questions on what I did
with the reverse geocoding?
All right.
I'm going to move on.
I want to get to office errors.
[ Pause ]
All right.
Two more topics and we're done.
First one is storyboard constraints.
So, I mentioned that when you rotate the device,
you don't necessarily want things to be laid
out in the exact same way that they were.
So, here, this one is rather straight forward,
everything is full screen.
When I rotate the device, everything is still full screen.
Likewise, news has built
in graceful handling of what to deal.
Weather got interesting now.
By default, interface builder doesn't know how I want
to rearrange stuff when I change the orientation here.
If I didn't do anything, it would try to take all the stuff,
squish it up and have lots of white space on the side.
And I didn't think that was particularly useful.
So, I came up with this which is I think is a lot more
interesting, still required zero lines of code and was all done
through interface builder
which I thought was actually kind of neat.
And if you look at it, you can sort
of tease part what I'm doing.
You can see that the sun is still
in the same location relative to here.
And the temperatures are still
in their location relative to over here.
I didn't do upside down of your phone.
So, this still works and this still works.
And this actually is still under the sun when I rotate.
But it's too far down on the screen and gets it.
I was OK with that they got the burning on one screen,
so that was pretty good.
So, how does this actually happen?
All right, when you build things in storyboards
and you drop things on, remember,
like if I drop the button on,
you start to get these little helpers.
There's a line here, there's a line there.
If I drop something in the lower right corner here,
we know that we're a certain distance from the right
of the screen and certain distance
from the bottom of the screen.
But how does interface builder know whether this is relative
to the top of the screen, or relative to where it's going
to show my temperature or what's going on here?
How does it know what to glue things to?
If you come over here in the size inspector,
you'll see it's got this idea of constraints.
And right now, it's saying that this,
we see this little blue strut here
and this little blue strut here,
it's saying that the trailing space, so the space to the right
of the bottom is relative to the super view
and it equals the default.
So, I want the edge of the screen
and give me the default space from the side of that screen.
Likewise bottom, it says it's relative to the super view
and the default space there.
If instead, I had put this for example here, they'll say, "OK.
I think what you want is your top space compared
to the image view which is this little line here, this default
and you're going to be center aligned on this label.
I would have thought it would have guess centered
on the screen but it also happens to be centered
on the temperature of that time.
So, let's come up with that as the possible constraints.
So, that is a valid possibility.
But what I can do is also do other constraints.
So, there's this little toolbar down here, little hard to see,
we've got alignment options,
struck options and resizing options.
So, for example, if this button should be the same distance
from the bottom of the screen every time, I can have a struck
that is bottom spaced to super view.
So, now this button has-- should have three constraints.
So, now it has three constraints.
The purple ones are the ones that--
it has come up with on its own and it thinks have to be in.
There's no-- you haven't given that any other criteria,
so it's doing the best I can.
The blue ones are ones that you can manipulate and are the ones
that you have already created yourself.
So, it's still keeping track of the distance here,
and the distance here,
but if this button is really only relative to the bottom
of the screen I don't need this top constraint anymore.
And because it's blue I can actually go ahead
and delete that.
And now, all it knows is that the button is centered compared
to this label in this distance from the button
of the screen all the time.
[ Pause ]
So, if we look at something like my temperature,
you'll see I've got a fixed width and a fixed height,
so that gives it part of the constraints.
And I've specifically said that the right edge should line
up with the right edge of this,
and the bottom spacing should be relative to as this as well.
So, this location, the Fahrenheit is based
on the location of the Celsius.
[ Pause ]
The Celsius--
[ Pause ]
-- is actually a certain distance
from the bottom of the screen.
And I think there might be one other constraint on that one.
Yeah. And it also knows its distance
from the side of the screen.
So, iOS can figure out how far up to put this,
how far over to put this, and then once it knows
where this is it can figure out where
to put the temperature relative to that,
so they end up stuck on top of each other.
And it can sort of extrapolate this idea and see that, oh,
this UI image view was going to pinned to the left in the top.
And we can see that that has a fixed width, a fixed height,
formal spacing here, formal spacing there.
I'll let you play with that more but does
that basic idea make sense
of how you glue things relative to other things?
Cool. So, the last thing I want to talk
about is the one I find most interesting but it's the end
of my talk and it's probably the most boring to everyone else.
[ Inaudible Remark ]
Oh yeah, question.
[ Inaudible Remark ]
So, this-- so the question is if you switch
to landscape view do you have to respecify the constraints?
>> Yeah.
>> The-- and the answer is no.
The constraints are always the constraints and based
on whatever geometry of screen it gets it will build
as best it can with that layout.
[ Inaudible Remark]
I don't think I can switch it in interface builder.
I've only been able to switch it, if you got a thought on how
to do that I'd be happy to try it but.
>> So, how do it know what it looks like when I [inaudible]?
>> So, the only way I found to know what it looks
like when you switch it is to run your app and switch it.
There's got to be a better way.
I saw some articles on stock overflow
that were basically titled how do I re-orientate my storyboard
in interface builder?
I wasn't finding a good way to do it, but I'm happy
to look into it further.
Any other questions on constraints?
>> But when you switch why the logo just disappear?
>> So, the question is
when I switch why does the logo disappear?
The reason is I've made the image view a fixed height
and I made the logo appear under the image view.
And the amount of space that this takes
up is too much for the screen.
So, the screen bottom bar here is just overlapping
and this is pushed off bigger than the screen fits.
As an extrapolation if I took the same geometry and dropped it
on like an iPad that would probably end
up with something crammed up over here and something way
down here, it would be kind of a diagonal display.
So, the last thing I want to show you is unit test.
And very few people get excited about testing
but I think it's one of the most powerful
and interesting things we can do.
And they don't look that difference.
So, this basically looks like header files,
we've seen everywhere else, right?
I've got my mobile local test.
They happen to be of this class type which is a send test case,
but that could have in other cases been as simple
as UIViewController or something like that.
We've seen this basic structure before.
The method file is going to look a little different
but not much different.
I've moved by interface here again,
and I've got a property for weather.
So, I'm going to instantiate a weather object to some point
and I've got three methods, set up, tear down, and my example.
So, set up is sort of like how we've been using
[inaudible] load.
It's the first thing that's going to happen, and it's going
to create whatever variables I need for my tests,
so to do whatever the super class says,
and let me get in here.
And in this case all it's going
to do is allocate a new weather object.
Tear down would be if I needed to tear anything
down in this case I don't,
but let's say you were using some sort of local storage
in someway where you created some test records
at the end you want to delete those test records.
You could use the tear down methods
to undo whatever you've done there.
And then the mid of it is this test example.
So, I'm going to create some helper stuff here,
but I'll create an NSDateFormatter
that basically makes a date out of an hour.
And what I'm going to be testing here is this concept
of is night [phonetic].
So, we haven't necessarily seen it yet, but at nighttime instead
of a sunny sun up on the display
and clear weather you'll actually get a moon.
And the way I did that is it says from 7 p.m.
to 7 a.m. that's considered nighttime and from 7 a.m.
to 7 p.m. is then daytime and I can switch
between my icons that way.
Well, how do I know that actually working other
than trying to set all times of day which is not practical,
I don't have 24 hours to do my testing.
What I can do is I'm creating a quick array just 'cause I wanted
to try a number of things at once of 19, so at 7 o'clock,
8 o'clock, 6 a.m, these are all things
that should be nighttime according to my app.
And there are all things that touch near the boundary.
I know 7 is the magic number, but I want to make sure
that 6 a.m. is nighttime and 7 a.m. is daytime,
and 8 a.m. is daytime, likewise 6 p.m. is daytime as soon
as it hits 7 p.m. that is definitely nighttime,
and then of course 8 p.m. is nighttime as well.
So, I set up some test conditions for night.
So, I'm just creating as NSDate based on that hour.
And then, this is the actual magic.
I'm asserting that this will be true.
If weather is night is called with any of these times,
that should be true, right?
This is what nighttime is defined in my application.
And just for my own description it is night when hour is blank.
So, if the test fails I know what test was being run is
night, when hours whatever.
Likewise, I can repeat that same bit of code for 7 a.m., 8 a.m.,
6 p.m. and these are days, so I'm going to assert
that is night going to be false this time.
And there number of different assertions, you can check
for null, you can check if things that are exceptions.
True and false is a nice easy one.
Theoretically, I could comeback
and say what happens if we pass in null.
Oh, you have a question?
>> Yeah, is the reasons that's been showing a sun so far
because it is like in a different location?
>> Yes, the reason this been showing a sun
so far is the zip codes happen to be either Western--
Pacific or Mountain Time.
I don't know which but yeah,
we haven't quite hit 7 p.m. according to the app yet.
So, I got my test, theoretically I could say, you know,
what is the case for null,
like I actually don't know what their function should do
in that case.
Maybe you should throw an exception
because that doesn't make any sense.
It can only return a Boolean value.
So, if I give a time of null is that true?
Four is night, is it false first night?
I don't know.
But I could write the next test
that tells it what it thinks the situation should be and then see
if it's doing what I think it does.
And using this test is actually really easy.
So, we've been using the run button.
There is a tiny little arrow next to the run button.
So, if you hold down run it's actually a drop down menu,
and it's a simple as just using test at this point.
And I would build my app.
It will tell me I still have my assimilator open
and it wants to use it.
[ Pause ]
So let me put that, it still knows I'm testing.
I run my test again.
[ Pause ]
It will pop-up assimilator.
And apparently nothing happen, but that is not true.
It said finish testing, no issues.
So, in this case life was good.
If I change my test and I said rather than 7
and 8 p.m. being nighttime, if I said that was also false,
my function is going to return true.
I'm expecting false.
[ Pause ]
And for those three conditions it's going to say no.
These are the failures that you saw when you run your test.
So, I can go in and see whether is night,
night should be false is night was one hour is six.
So, I can quickly see these things
and know how my functions are testing
without having to run the whole app.
I can do all sorts of automated stuff.
So, you know, if I refactor my-- is night method to do something
in slightly different way I can see
if it's still working the same way as it work before.
One of the great approaches to development is the idea
of test driven development.
We actually write all your test first before you write any code,
so you know what-- how things are supposed to work
and then you make code to make it work.
Sometimes it's called red, green testing where everything starts
out red, because you run the test and there's no code
and it's broken, and you continually work towards getting
green and as tester green you get to the point
where everything is green and then
in theory your code does exactly what you thought it was going
to do.
So, does the basic idea of testing makes sense
on how you could actually implement some test?
[ Pause ]
All right.
So, that was everything I have tonight.
I'm sorry we've gone so long.
It's 8 o'clock now.
But we'll wrap things up and shift over to office hours
and we'll get you some help with your projects.
Thank you so much.
I really appreciate it.
[ Applause ]
[ Silence ]