字幕表 動画を再生する
[MUSIC]
Stanford University.
Okay, well, welcome to CS193P, Stanford CS193P.
This is Developing Applications for iOS, winter
of 2017. Today we're going to talk a little bit about what
this class is about, and the prerequisites you need.
Then I'm, really fast, gonna go over iOS and what's in it.
And then, I'm gonna dive into a big, long demo.
And this demo is gonna really quickly let you see what it's
like to develop an application for iOS, so you can decide,
is this for me, or not? So, what are you gonna learn?
Well you're gonna learn to build cool apps, all right,
that's, that's what we're here for. Why are these apps in iOS
cool? Well for a number of reasons, okay?
One is they're in your back pocket,
you can pull them out and show your friends on your phone,
a lot of them are networked so there're kind of social
apps and a lot of that can be a lot of fun.
Also if you decide to turn your app into a product it's
really easy to get it out to customers via the app store.
You don't have to wrap it in a box and
put it on a shelf somewhere anymore. You can get it out
there real quick. And also you're going to see,
today even, it's really easy to build pretty complex
app pretty quickly. So you get a lot of instant gratification
from building iOS apps. For those of you in
computer science there's also this huge benefit, you're
gonna get to see a real life object-oriented programming
system. And not just object-oriented programming,
but we're going to use databases in this class, and
graphics, and multimedia, multi-threading, animation,
networking, all these things. And
you're going to see it in a real world environment.
So you take a lot of classes on these subjects
and sometimes you get maybe a little disconnected from
what's this like in the real world, well,
you're gonna get to see it all in action here. Prerequisites,
just boiling it down really easily. The prerequisite for
the class is object-oriented programming.
You have to know object-oriented programming,
I'm not gonna teach that in the class, I completely and
utterly assume it. And not only do you have to know it,
you have to have some experience doing it.
So that's why here at Stanford CS106 A and
B are a hard prerequisite. You have to have taken those two,
those are object-oriented programming classes. And
then I just want to make sure you have some programming
experience, so either you've done something outside
of school, or you've taken CS107 or CS108 or CS110.
CS108 is a particularly great prerequisite,
that's object-oriented programming.
So if you have a chance to take CS108 and
you haven't taken it yet, yeah, maybe taken it, and
then take this class the next time it's offered, all right?
So let's dive through what's in iOS really quickly here.
I've divided it here into four layers.
These layers are roughly close to the hardware.
And then up close to the user. So that bottom layer close to
the hardware, that's actually a Unix operating system, okay?
Just like macOS, iOS is a Unix operating system at
the bottom. None of these APIs are object oriented or
anything, they're basically C, okay? For
the Unix pretty much written in C, these API's are in C.
We're gonna do no work at that level in this class, okay?
This is an object-oriented programming only class,
so we're not gonna be doing anything there.
So there's another layer right on top of that called core
services. Sometimes people refer to this as foundation,
but there's other things in this lever, layer,
besides foundation. And this is an object oriented layer
on top of those things that were lower down. Okay, so
now you can do networking, file system, things like that,
using object oriented API. But this is still non UI layer,
right? It's still kinda closer to the hardware. So I'll
definitely be teaching you a lot of stuff at this layer,
'cause you just need it to do the things you're gonna do.
Now, there's another layer here, the media layer here I
call it. This is a huge layer, which has 3D graphics, and
audio playback and recording, image processing, video,
all that stuff. Unfortunately I'm not gonna have a lot of
time to spend here, even though it's a huge part of
what an iOS device does. iOS devices all pretty much have
iPods in them, video iPods if you wanna think about it.
And so there's a lot here. Unfortunately I can't cover it
all. Because I'm gonna spend most of my time up here,
which is the Cocoa Touch layer.
This is where buttons and text fields and things are, but
also much more powerful objects like maps.
There's an object in Cocoa Touch which is a map object,
it's pretty much the entire Maps application on
an iOS device, that you can drop right into a rectangle
in your app. With almost no work.
So, very powerful object to this layer. This is where
we're gonna spend the vast majority of our time,
building user interface apps at this layer.
That's a rough overview. Trying to explain all
of iOS in two minutes is pretty much impossible, but
that's kind of what we're doing in this class. We're
gonna use all these components to get our work done.
Top level there, Xcode 8, is gonna be...
everything we do is gonna be in Xcode 8.
The debugger, the editor, everything, building,
it's all in Xcode 8. There's a little app, Instruments,
that goes along with it, for performance and stuff, but
pretty much it's all Xcode 8. Two, I'm gonna teach you
a new programming language. So if you're computer science
people, you know that learning different programming
languages, really valuable skill.
Not because you're necessarily gonna use all of them,
some you might or might not use. But just the process of
seeing how language designers pick and choose their syntax
and, and the feature set, is really valuable.
So you'll get that I would think. It's a great language.
It was just invented in the last two or three years, so
it kind of incorporates the best of a lot of different
languages. So I'm gonna kind of blitzkrieg teach that to
you in the first couple weeks. Frameworks: That's essentially
things like the Cocoa Touch UIKit framework.
It's where all the buttons and stuff are.
Foundation is that, kind of,
mostly that core services layer.
But there's a lot of other ones like Core Data framework,
object-oriented database,
we'll be doing that in assignment five.
Also I talked about that map thing, that's in a framework
called MapKit. And there's also things in core motion,
like the accelerometer and the gyro in the device.
All those things, I'm gonna be teaching you many,
many of these frameworks as we go on. And
last, but definitely not least, and very,
very important, is the design strategy for
how to build apps, it's called MVC, model-view-controller.
How many people already know MVC, have,
have learned in a different class?
See, so maybe half of you. I will spend the first part of
Wednesday's lecture telling you about MVC and what it is.
We 100.0% have to use MVC when we develop apps for iOS.
There's really no other way to do it, if you do it any other
way, you're swimming so up stream against the current of
iOS, it's... You'll end up with a mess of an application,
okay, so we'll be going over that as well. This demo
that I'm gonna do, we're gonna build a calculator.
A calculator's great because it's got a fairly simple UI,
but it's got a little bit of guts on the inside,
the actual calculating part. So
it's just complicated enough to start showing you MVC and
a lot of language features and things like that. But not so
complicated that I can't do an entire calculator, basically,
in two lectures, okay, start to finish. All these topics up
here, you don't have to look at them now.
This is the slide to go look at after my lecture today and
say, hmm did I learn that, yeah,
I think I got that. So
it's kind of a summary of what I'm gonna do. Since I'm not
gonna get back to the slides from the end of my demo,
it's just gonna be the end of the lecture.
I'll tell you a little bit what's coming up.
On Wednesday, I'll be continuing this demo, but
not until after I give you this talk about MVC,
because what we're gonna do in the calculator is apply MVC
to it, on Wednesday. And your first
programming assignment will go out on Wednesday, which is
pretty much to replicate what I'm doing today and
on Wednesday, okay? And I'll give you a video of the demo,
so you'll see it, and you'll be able to watch it. And
then on Friday, we have an optional section.
So the Friday sections in this course,
you don't have to go to if you don't want to.
But a lot of times, they're very valuable.
Feature so if you have not used the debugger in Xcode 8
you really might wanna go to Friday's lecture.
The location and time of it will be posted on the class
forums hopefully tomorrow. I've asked for the room and
haven't quite got it yet so hopefully tomorrow. And
then don't forget next Monday is a holiday so we're not
meeting on Monday. Our next class after this Wednesday
will be next Wednesday. So let's hop into the demo...
I said we were gonna build a calculator, let me actually
show you a calculator. This is the MacOS calculator and
our calculator is gonna look very similar to this, right?
It has to display along the top, it has the keypad for
typing numbers in and it's got these operation buttons. And
then you can just multiply, times eight, you hit equals,
it does the operation,
that's pretty much what our calculator is gonna do.
It's not gonna look exactly like this. It's gonna have
a look that's a little more appropriate for a iOS device,
but it's generally this. And I promised that Xcode would be
your one-stop shop for doing all development, so
we're gonna spend our entire time here working in Xcode.
Now Xcode is an app that you just go to the Mac App Store,
and you download it. It's free.
When you first launch it, it's gonna put up this splash
screen like you see right here.
And all of your projects are going to start accumulating
here over on this right side where this gray area is. And
you can basically do three other things here. You can use
a playground, which I'll show the playgrounds on Wednesday,
it's kind of a little play area for iOS programming. You
can check a existing project out of a source control
management system which we're not gonna be doing.
Although we're probably have a Friday section
on doing a source code control. So we're gonna be
doing this option right here, create a new X code project.
And in fact, when I do demos in this course,
I almost always start from scratch.
Cuz I don't want you to have to like,
come up to speed on some code that I give you first, and
then, learn from there. So we try to start from scratch, and
see what we can do that way. So I'm gonna click on this,
to start a new app. It's asking, what kind
of app do we want to build, or what kind of project, and
here you can see, we can do Watch apps, Apple TV apps,
even Mac OS apps, but we're doing iOS, and in fact,
we're always going to choose this single view application
template. It's the simplest template, and
some of these other templates have code in there that I
actually want to show you how to write yourself instead of
having the template just make that code appear, all right?
So we're gonna do single view application.
Now it wants some particulars on our application,
most importantly at the top its name. Well,
we're building a calculator so we're gonna call this
Calculator, okay, that's gonna be the name of our app.
Now this second line here, team, that's the team of
developers who are gonna work on this project, that's gonna
be a team of one, which is you. Okay, when you launch
Xcode, this is probably not going to be a pull down list.
It's gonna be a button that says Add Account or
something like that, Add Team. You click on that, all you'll
need is an Apple ID, any Apple ID will do, won't cost you any
money. And go through the dialog there and
it'll add a team for you, and you use that here. Alright?
This organization name can be anything you want.
It's just gonna appear on the copyright symbol at the top of
your source code files, that's it. But this one,
it's super important that this be a unique identifier of you.
Okay? So I strongly recommend doing edu.stanford.cs193p.
You're SUNet ID here, okay? If you put that in there,
you're almost guaranteed, if you're a Stanford student,
for that to be unique. If you're not a Stanford student,
you're watching this on iTunes U, pick something else that
uniquely identifies you. Hopefully,
reverse DNS notation will work in your circumstance as well.
The language we're gonna use like I said is Swift.
iOS was originally written in a different language called
Objective-C. Turns out you can use Objective-C and
Swift in the same application.
They use the exact same underlying iOS API. So
everything you're gonna learn in this class in Swift,
if you later went and learned Objective-C, all that learning
would be valid, okay? Cuz it's the exact, in fact,
it's the exact same code base, it's not just same API.
Swift was designed in a way to be quite compatible with
Objective-C's APIs. And in the last couple years,
they've even enhanced Objective-C to catch up with
some of the advanced stuff that Swift does. Our app that
we're going to build, our calculator is going to
be universal. That means it's going to run on iPhone and
on iPad. First couple weeks, it will be iPhone only but
then, eventually, we'll add iPad support, as well.
We're not gonna be using a database in the calculator,
but we will in your assignment five. And when it comes to
testing, which is super important, again, I'm hoping
to have a Friday section to tell you a lot about testing,
especially the UI testing framework is really awesome,
okay, so hopefully we'll get a chance to show you that. So
I'm just gonna click next here to create my app.
It says, where do you wanna put this project? I recommend
you put it home directory in a folder called Developer. Okay?
Then all your apps will just pile up in here.
This is pretty much a canonical place to put it so
I strongly recommend it. And
then again source control is more for teams working on it.
You're gonna be working this by yourself so
you can leave this switched off.
All right, here's our, there's your load.
There's your first IOS app,
okay? Now let me explain a little bit about Xcode and
how it's laid out here. So if you haven't seen it...
How many people have worked in Xcode before? See, so
again probably half of you so quite a few. For those of you
who haven't, it's divided into these three main sections
here. This main section in the middle is the primary place
you're going to do all your source code editing and
things like that. That's where you do most of your work.
This section over here on the left, this blue section is
called the navigator. You use it to navigate your project.
And here you're seeing it in a file based view,
where I'm looking at all my files. And we'll look at
those in a second. But you can navigate by searching,
okay, there's a search panel. If you, if you're debugging,
you can navigate through all the break points that you
have, etc. So, you'll learn all about the different
ways that you can navigate, as the quarter goes on.
On the right hand side here you see this little area,
this is called the utilities window.
And I'm gonna talk all about this in about five minutes,
okay, we're gonna use this in great detail. I want to
show you a little bit how you can manage your space here.
If you look in the upper right you see these buttons here.
You can click this one over here to hide and
show. That utilities window. And same thing over here for
the navigator. So that can make more space for you.
All right, and there's another one here, this middle.
That hides something from the bottom.
This is your debugger window on the left and
your console, which is a place where you can log
strings out to while you're debugging, on the right. And
we'll see that in a moment as well. All right, so
let's go look at these files, right?
We're in the file navigator here on the left. And
there's six files here but
four of them are really just supporting files, and
we're not not even gonna look at them in the calculator.
We'll look at a couple of them as the quarter goes on but,
they're not primary files.
And for example, this one Assets.xcassets, Xcode assets.
This is images and videos that might be embedded in your app.
You can see it's the app icon,
I haven't set any of my app icons, you can see them. But
this xcassets and the Launch Screen and this Info.plist and
this AppDelegate here. By the way, I'm pulling down command,
you see in the lower left you can see any command keys that
I press right down there cuz I'm gonna use command keys for
various things that we do. So
I use command to select all these. And
I'm just gonna right click and
go down to here, New Group From Selection. And it's gonna
put these four files into their own little folder.
There, it did it, I'm gonna call it Supporting Files,
okay. And I can move these around in the navigator.
See there they are, hidden in there. We're not gonna look at
those. We're gonna focus in these two files right here,
okay? This file, is your first look at Swift. Here it is.
It's got some very important methods right here, which I'm
gonna delete. Okay? They are important, but the fact that
I deleted them doesn't make them not important.
It's just that I'm not gonna teach you about them for
another couple weeks.
So we're not gonna use them in the calculator. And in fact,
I'm gonna go into detail about this Swift code more
in a moment. But before I do that,
I wanna focus on this file right here, Main.storyboard.
This is your user interface. This is calculator's user
interface. And one thing you notice when I click on that,
there's no code here. When you build your user interface
in iOS app in Xcode, you do not write code.
We're just gonna to build it with the mouse. We're gonna
drag some things out. We're gonna use some inspectors to
set the objects we want. The way we want them. That's how
we're gonna build our UI. That code that you saw.
That is only gonna control the behavior of the UI.
What happens when you touch on a button? Things like that.
That's what's gonna be controlled by that code. But
the actual layout of all the buttons and all that stuff.
Is gonna be done here in this graphical view.
Now you can see there's this area here on the left, okay?
This is like, this is called document outline.
If you're down here you'll see a little button there.
The document outline. The document outline has
all the things in the user interface in an outline form.
And that's gonna be very useful for
us. Later in the quarter. So, I'm gonna hide that.
That's this little button down here is. It hides and
shows it. We're gonna hide that to make more space.
We're not gonna use that in the calculator either. So
that leaves this space here in,
if I zoom in on a little bit here,
or zoom out rather. You can see I start to see something
that looks like an iPhone. Okay, it's kinda iPhone
shaped, I can also by the way hold down the option key and
use my mouse wheel to zoom in here. Okay, so this is like
an iPhone, in particular it looks like an iPhone 7.
You see down here at the bottom it says view as iPhone
7, all right? And if I click on view as iPhone 7,
you'll see all the other iOS devices appear- iPads,
for example. Or old iPhone 4s, they're really kinda little.
And not only are they there but you can switch their
orientation, okay? Now when you build an iOS app,
you want the UI to look good on all these devices. And
you don't wanna have to write a lot of special if,
then code all over the place to make them work. So, this
whole system that, of building our UI, which by the way,
is call Interface Builder. This part of Xcode is called
Interface Builder, is oriented with a lot of functionality
to make you, make it so you can build your UI once and
it will work on all these devices. Now, I'm not gonna
actually start doing that until the end of the lecture
on Wednesday. So, for now, we're just gonna build our UI,
it's gonna be kinda a mess. We'll throw buttons anywhere
we want. We're not really, really working in
landscape mode like this vs portrait or small
device or large device, ok? We're not gonna worry about
that right off the bat but you just wanna preview the fact
that we are eventually gonna build this universal UI
that works on all of them. So here's our iPhone 7.
We wanna start building our UI. What do we need? We need
buttons and we need a kinda a display across the top.
Let's start with the buttons. Where do we get these buttons?
Well, as promised. I'm gonna talk about this utilities area
right here. Now, this utilities area has a top and
a bottom. You see that? And in the bottom,
right here, under this region called the object library, is
a library of IOS objects that you can build your app out of.
And it has things like buttons. Text fields,
it has more complicated things like image views and
text views, which are multi line and editable text ,and it
even has things like that map thing I was telling you about.
Or a web view, which is basically Safari in a little
rectangle. So it's got a lot of powerful things and
there's a lot of them in here. And we will try to cover
the vast majority of these in the course of the quarter.
But it's almost really too much to cover. So
we're gonna start though simple with a button. And
if I want a button in my UI, I just pick it up with
the mouse, okay, and drag it in. Now when I drag it in, see
these blue lines are trying to help me put it in a good spot.
You see that? Now, we're not gonna pay attention to that
right now because I told you we're doing this thing where
we're building the app that'll work on all devices. But
when we start thinking about
putting it on an app that works on all devices we
really wanna use these dashed blue lines. Okay, because if
you say something like I want this to be in the center.
Well now it'll be on the center on every device,
no matter what this size of the screen, you see? So
these blue lines help you communicate that to interface
builder, that you wanna it in the exact center. So again,
we're not gonna worry about that for now, so
I'm just gonna drop this in the middle of nowhere. But
again, those blue lines are gonna be very important down
the road. All right so we've got this button here.
It's not [LAUGH] a very good button,
because it's kinda small and it says button on it.
And we want it to be let's say one of our number buttons.
Okay, so how are we gonna do that?
Well, we can double click on it. And
type one of our numbers, I'll make this be my 7 button, so
this is gonna be my 7 button on my calculator. And I can
resize it, you see when I select it I get these handles.
So I can just pick it up by a corner and resize it.
And when I do, it even tells me exactly what size.
So let's pick maybe a size like mm, 64 by 64?
That's a pretty good computer science size can be
a little tricky then. Do it there, there, there we go.
Okay, so we get 64 by 64 now.
Actually the size is not even gonna matter in the long term,
because on a smaller device like an iPhone 4 it's gonna be
shrunk down and
on another device it's gonna be shrunk out. But for now,
will pick some that's kinda using a reasonable amount of
the screen real state on an iPhone 7. This is still
kinda a small seven. We want it larger. So when we wanna do
things like that that's when we go to the top half.
I'm just gonna get rid of this bottom half by scrolling it
down here. We're gonna the top half of this utilities pane.
And this is inspector and there's different kinds of
inspectors. We're gonna be using the attribute inspector
here, but there's also, for example, a size inspector.
And when I click on that, you see that there's the 64 by 64,
I could have just typed it in instead of trying
to get it exactly on there. Okay. The attributes inspector
is kinda an object oriented inspector.
You can see that it knows a button is selected, so
it's showing you button things.
Things that you can set about a button. But
a button is a class, object ordinate class that inherits
from control, so you're seeing control things, and
that inherits from view, so you're seeing view things.
So this inspector is object orientated and
shows you all the things that can be inspected about this
object even using inheritance. So if I wanna change something
like the font, I just look down here, title, here it is.
Font. Right here. I'm gonna click on this and
I'm gonna change this to 30 point let's say. Okay.
That looks pretty good. Now, maybe I wanna have
a background for this button. So, if I look in here there's
that background image. I don't want a background image.
I actually want a background color. So
there's nothing in button that does that.
But, If I go down to view. I can see background right here
that's a color. And if I click on this, I can pick a color,
one of these pre-defined colors, or other colors, let
me choose from Color Picker a little crayon box or whatever.
So I'm just gonna pick from here the light gray.
That looks like a good background color. So
now I've got a button, okay? Here's a nice button.
In fact, we could even run, see what our app looks like.
Just with one button. Now when it comes to running,
the way you decide where you wanna run your program,
because you can run it on your device or you can actually run
it on a simulator. Okay, and for the first few weeks in
this class you can use the simulator.
Towards the end of the class I'm gonna
ask you to start running on your device so
you get used to doing that as well. But the way you do that
is you go up here. You see it says calculator iPhone 7 plus.
If you click on that you'll see a whole
bunch of simulators. These are all simulators of all those
different devices that can run iOS 10. And then right up at
the top here, you could pick, if you had an actual device
connected to your Mac, you could pick a physical device.
And I'll be showing you that in a couple of weeks,
as well. So, let's run it on iPhone 7, okay,
so I just picked iPhone 7, now I'm going to press this little
play button right here to run it. Okay, now it's going to
launch the simulator. Now that simulator is a full iPhone
simulator, so it's not just running our app in a window.
Let's go find it here. It's over here, and
it's kind of big here, we'll make it small in a second. So,
this, and in fact, there it is. You can see it zoomed in,
now the iPhone 7 has very high resolution, and
I'm running on a small resolution screen. But
you can actually go down here to scale, and scale it
down a bit. Maybe that's too much. Let' scale it to here.
Yeah. So we're seeing 50% size here of an iPhone 7.
And there's our 7 button right there. Okay,
now, you can press the Home button
on this iPhone 7 by going to Hardware > Home. And
when you do that, look. This looks just like an iPhone.
You've got settings. You can go in and set some settings.
Okay? Do home again. Cmd+Shift+H is home.
And then you can go back to your app,
which is the calculator right here. So
if you're writing an app, for example, that uses GPS and
you need to go to the settings to enable GPS location.
You can do that here on your simulator, okay?
All right, so we got the 7 button, let's click it. Okay,
well, It's flashing, so it looks like it's working, but
of course, it's not doing anything. We haven't told our
7 button what to do, so it's doing nothing, all right? So
let's go make it do something. Now I told
you that the behavior of the UI is written in code. So
that's what this guy over here is, this ViewController.swift.
That's the code where we're gonna do the behavior. And so,
how do we hook up this UI to this code? Well to do that,
we need to get them both on screen at the same time,
all right? And the way we do that is with this button,
right here, assistant editor button.
So I'm gonna click it, and we get both. And I can click for
example, on one side to show my UI. And
it's automatically going to show the code on the other
side. Okay, cuz it already,
it knows that I probably wanted to do that. And
it does that because, up here at the top you see it says,
automatic. It's automatically picking it. Now you can go to
manual and manually pick the file you want to appear here,
but most of the times you're leave this on automatic. And
it's gonna pick automatically the thing that makes the most
sense to be on the right hand side. Okay,
we'll make some more space there. All right? So
let's zoom this in a little bit so
we can see the whole iPhone 7,
all right, so let's look at this code first because this
is the first time you've seen Swift.
Swift is really nice, because it's kind of succinct and
kind of very obvious in the keywords it's chosen, etc. So
import is like include in a lot of languages, it's
just basically saying I want to use this framework UIKit.
Now, this is our UI behavior controlling code.
So of course, it needs to use UIKit,
okay? If we were to write an object that's more of like
the internals of the calculator that's
UI independent,
then we would probably import foundation here.
Foundation to kind of get to that core services layer,
not UI. You would never want to import UIKit in one of
those non-UI kind of classes. And you'll see that when we do
the MVC on Wednesday. There's of course other things we can
import too, like map kit, things like that. All right,
so here you're seeing your first declaration
of a Swift class. Okay? Keyword class, of course.
Name, this is the name of the class. ViewController is
name of class, it's kind of a generic name.
Probably would have given it a better name if I had had
a chance, but this is what the template gave me.
You can't unfortunately just rename this by typing,
because it's linked up to your UI. I will show you how to
rename this class later. But for now, we're going to stick
with this generic name. This colon UI view controller is
the class that view controller inherits from, okay? This is
object oriented programming, this is inheritance.
Again, you have to know object oriented programming to be
sitting in this room. So you know what that means?
Swift is single inheritance. So you can only inherit from
one class. And view controller inherits from this class.
This class' capabilities are, it knows how to control a UI.
That's why it's called a view controller. We call this our
view over here, and it knows how to control it.
So this view controller is inheriting all the capability
of how to control this. Which is great,
because that's exactly what we want it to do. And
then inside the curly braces, here we're going to put all of
our instance variables and methods. Okay?
Hopefully everyone knows what an instance variable and
An instance variable is like storage of variables inside of
a method is, right?
our class, and a method is just a function in there.
By the way, we call instance variables in Swift properties.
So if you hear me think properties,
I mean like instance variables. Okay,
we call methods, methods. So what I really want now
is that when this button is touched, I want it to invoke
a method in my class, right? I want it to call a method.
That would be perfect cuz then I could put whatever
code I want in there. And
that's exactly what we're gonna do.
Now the way we link that up is kinda kooky. Here we go, I'm
gonna hold down Ctrl. You see I'm holding Ctrl down there.
I'm going to drag from this button into my code,
okay? This is how I'm gonna connect it. And when I let go,
it says you wanna make a connection between your UI and
this code, what kinda connection do you want?
And there's really two choices.
There's Outlet, that means make a property or
an instance variable that points to this thing, so
I can talk to it. And then there's action,
which means make a method, and when the buttons touch,
call this method. Everybody got that?
All right, so here it's asking for the name of this method.
I'm going to call this method touchDigit.
Okay, touchDigit. And this method, it can have arguments,
it could have no arguments, or one argument which is,
the button sending me this message. Now I need
that argument because I want to have one touch
digit method that all my buttons set. So I'm going to
ask the button who's sending it to me, who are you?
What title, are you the 7 button?
Are you the five button, what are you? So
I want that sender. This type right here,
it says Any, that's the type of the argument. Very, okay,
wake-up if you're taking a nap right now, and when you're
doing your homework, you cannot lead this to any.
Because we know what kind of thing is sending you this
message, it's a UI button, so you're gonna wanna change this
to any to UI button. If you miss that step and
when you go in there, your code's all gonna be messed up,
because the argument type of the sender is gonna be any,
which it just basically means untyped, almost. So
that's no good. So make sure you change this to UI button.
Now, when we connect this, it creates a method. So
you're getting your first look right here at a Swift method.
Now, this is actually not part of Swift, okay.
This is something Xcode drops in there. And it does it so
that it can put this little circle in the gutter.
You see that circle right there?
If I mouse over that circle, look what happens.
I didn't click on it, I just put my mouse over it. You see,
it tells me what this method is hooked up to.
In other words, what user interface element. Sends me
this message, okay? So this is purely not a Swift thing,
this is purely an Xcode thing. So this is a Swift method,
okay? So let's look at the parts of a Swift method,
the syntax of it, so you understand a little better.
And I'm gonna use a different method that I'm just going to
make up for this. Let's say I had some
function called a drawHorizontalLine and
it draws from some starting position,
which would be a Double to some ending position,
which also be a Double. And maybe it does it using
some color, which would be a UI color. Okay? So
there's an example of a Swift method. Notice that it,
this has three parameters. You see? This one, this one and
this one. This ": Double" is the type of this parameter.
So it's a double-precision floating-point number. That's
the type of that parameter. This one's also Double.
This one is a UIColor. Okay, which is a different type.
Now what's really interesting about parameters is that you
have two names for each one. See, from startX,
to endX, using a color, each one has two, so what
the heck is going on there with those two? Well this one,
the first one, is the external name of this parameter. And
this is the internal name. So these internal names,
like startX, endX, and
color. You would use those in your code inside this method.
Like, I might say, distance = endX- startX, or
something like that. See I'm using endX and startX
inside this method, right? Part of it's implementation.
These external names are used by the callers,
the people who call this method. So I'm gonna call this
method from touchDigit here, drawHorizontalLine.
Now, by the way, Xcode loves to type for you.
So I just type drawH and now I'm hitting tab. And tab, and
it's not only filling out drawHorizontalLine,
but it's showing me all the arguments and
tabbing to the first one so I can type it. So notice that
when it said that, the from, the to, and the using
were put in there for me. So if I say from 5.0 to 8.5 using
the color UIColor.blue let's say, okay?
These from and to and using are what the caller uses.
Notice also, that these things are mandatory. They have to go
in here. You can not call drawHorizontalLine like this,
drawHorizontalLine 5.0, this would be, look like most other
languages, you know, blue. You can't call it like that.
You have to put these external names in there.
Also notice that the external names are picked so
this reads like English. Draw a horizontal line from 5.0
to 8.5 using blue, okay? Swift endeavors
to be as kind of conversational in the language
of English as it can be. So
that's kinda crash course. You're gonna be reading, your
reading assignment's gonna tell you more about that, but
that's the crash course. But now let's take a look at thi-,
by the way, if your function returns something,
you just go like this, okay? -> String. It's kind of like,
the arrow is saying, out of this comes a String, okay?
So this would be the return value, okay?
All right, now, let's look at touchDigit though,
touchDigit is weird. Look at its two things here, okay?
The external one is_, okay?
So does that mean I call it by saying, touchDigit_:
whatever? No, underbar means there is no external. So
you would call touchDigit by just saying,
touchDigit (someButton) cuz that's the argument,
it's a button or whatever. Okay, there's no, you won't,
you don't put anything in here, it's not like a foo.
If we had this it would be foo, okay?
That's not in there. Instead, it's this underbar, so
you have nothing. Okay? Now, why do we sometimes have
nothing? Because sometimes, it's implicit in either
the name of the function or the type of the argument,
what you're supposed to pass, so you don't need that little
thing. By the way underbar, we almost never use that for
the second, third, or fourth argument.
It's occasionally used for the first argument, not always,
occasionally. But never for second, third, fourth, fifth,
okay? Or next to never. Now in your reading assignment,
I'm also going to have you read a document that explains
how to do this naming. What the rules are,
when do you use an underbar,
when don't you. You're gonna wanna master that document by
the end of the quarter if you wanna call yourself
a professional iOS developer, okay?
It's key to understand that. But this touchDigit, okay, so
this function, okay methods, I, just to be clear, methods,
we use the keyword func. Okay, cuz it's
a function on a class. This is the name. Parameters go
in parentheses like this, they can be separated by commas if
we have multiple of them. This is the first parameter here,
first and only. It's type is a UIButton because of course,
a UIButton is sending this messa-, method. Right,
it's invoking this method. So the sender is this UIButton.
And sender is the internal name.
So that's the name we'll use inside here to access it.
All right? But before we start doing that, let's just
have this do something simple like print out to the console.
So I'm gonna say, print "touchDigit was called",
okay? We're just gonna print that out on the console.
Whenever someone touches a button,
it's gonna evoke this method.
It's gonna print that on the console.
So let's just do that.
All right? So there's our UI, iPhone 7. Click and touchDigit
appears in the console down here at the bottom, okay?
Now the console shares space with the debugger,
this area on the left is the debugger. So you can kind of
separate this space back and forth, you can also completely
hide this space by using these buttons right here, okay?
So we'll just do console only right here. Let's go back to
our simulator. And so every time we press this,
we get touchDigit was called printed out again.
Does everyone understand what's happening here,
how we've hooked up this method to the button? Really,
really straightforward. All right, now that we have that
working, we know we need more than just this one button,
we need a whole keypad's worth of buttons. So I'm gonna,
I want these other buttons to look exactly the same, so
I'm gonna copy and paste. So I just copied and pasted that,
paste another one here. I can even select three at a time,
and copy and paste, okay? Paste another one.
Now notice here I'm using the blue lines to line them up
okay, really nicely. Blue lines are great for
doing that. Okay, and now I can just rename these buttons
by just double-clicking on them.
All right, so I've got an, a beautiful keypad right here.
And what's really great is that this method is hooked up
to all of them. Okay, that's because when you copy and
paste a button, it keeps it's connections to any methods
that it has, okay? So that's cool. So
now all these buttons are going to send this touchDigit.
So now if I run, you'll see that if I press any of
these buttons, not just our 7 button. Right, here's 7,
that worked, but also 5, 0, they're all calling,
this touchDigit was called. Okay, so that's awesome.
But of course, we want to know which button was called,
was sending us this message, right?
And we know that because that's the argument,
is the sender, okay? So let's add a local variable here.
So now you're seeing your local variables in Swift for
the first time. It looks like this, var digit, okay?
Var means this is a local variable. Digit is the name.
Now if we wanted to type it, we could put a type here like
maybe type string. Just like we put a type of our parameter
here, we can put a type right here of our local variable.
But, we don't usually do that in Swift because while Swift
is very strongly typed language, in other words,
you have to specify the types of everything.
It wants to know the types of everything.
it will infer what type you want from the context.
Very often. Ok? So that's the trade off,
if you have a really strongly typed language, you have
to type everything. It's really nice if the compiler
will just figure out for you what the types of things are.
So, normally, we will leave the types off wherever we can.
Now, we can't do that in
a method parameter because we got to know what That method
is expecting. But for local variables, we definitely can
leave it off almost all the time, okay? So we got this
digit, and I just wanna set it equal to something.
What does it wanna be equal to?
It wants to be equal to the title of the button
that's sending me the message. So this guy,
which is a button I want to ask what its title is.
Now, how do you send a message to another object in Swift?
Well, you just type the object you want to
send the message to and you press dot. Okay, so this is
like Java and a lot of other languages, just the object and
dot, that's how you send the message. Now, unfortunately,
XCode is helping me here by showing me all the methods And
properties that button can do. Look at this list,
I'm only in the Fs, okay, I'm still scrolling,
still scrolling. There's a lot of methods. It's like how am I
ever gonna figure out. I just want the title of the button,
please. Okay, well, of course I could get the documentation,
start reading through it,
trying to figure out, and
in fact I want to do that eventually.
there's kind of trick here in Xcode.
Which is, just type the name of thing you want,
Type what you think it might be and see what happens.
So, I'm going to type Title. Now there's no method or
property in button called title.
But you can see that Xcode has showed me all the methods and
properties that start with the word title Or
that have the word title in it. Or even that have "t",
"it", "le" in it, okay? So it's doing everything it
can to show you every possible thing that might match what
you typed. Now, let's look through these and see if we
can find one that will give us the title of the button, okay?
Title label That doesn't look very good. How about title for
control state, that looks good,
returns the title associated with the specified state.
Mm, that looks pretty good but let's keep looking because I
don't really know anything about the state,
that looks pretty good, but let's keep going.
No edge insets, no, add color, no, shadow, no. Current title,
the current title that
is displayed on the button,
victory that sounded exactly what I want. So
I'm just gonna pick that by double-clicking on it.
So I'm just gonna double-click on it. There it is,
it filled it out. And so now we're sending currentTitle
to sender. Now let's find out more about currentTitle, okay?
We know that one-liner that is the currentTitle displayed.
I'm gonna hold down Option.
See Option down here on the left, okay?
I'm gonna hold down Option, and look.
When I do Option things that I mouse over turn blue
with a little dashed underline.
And if I click, I get a little help, okay? So
I'm getting that current title display from the button,
but I'm also getting more detailed description and
I'm getting the declaration of this thing. And
you could see that this is not a func.
This is a var. So now you're seeing for the first time,
the declaration of a property in Swift, okay?
An instance variable. So this is an instance variable,
in UIButton, okay? Called var, makes sense, right?
It's a variable, var. It's called currentTitle,
of course. It's type is, string?
Not sure, maybe button's not sure what the type is.
No, I think button knows but,
we're just gonna assume this is string, for now. And
we'll see, where that takes us. Also notice this little
syntax means that, you can only get the current title,
with this property. You can't set the current title. Now,
what if I was like, well I'm interested. How would I set
the current title? So you would want to, let's say,
go look in the documentation. How would you get there?
Well, if you look down at the bottom, it says more.
This property reference right here. If you click on that,
it brings up the documentation. Okay?
And here's the documentation for CurrentTitle. Now what's
cool about this, is from here, I can click on things.
Like String, I could find out about String. Or, look,
I can click on the class that this is defined in, UIButton.
And here's the UIButton, and look at this section at
the start of UIButton called Overview. These are awesome,
and I strongly recommend Every class you go to use
take the five minutes or
ten minutes at the most to read through these overviews.
Then you'll really understand how these classes work.
Look at this thing. It tells us for
example how to configure the button's appearance.
It tells us all about this button's stage.
Remember, we had that title for state.
And we didn't really know what the state was. Well,
this tells us about that. Tells you about the content of
a button. And you can put an image on there, evidently, and
text. Those edge insets, whatever those are, explained.
Even an interface builder, all those things in the inspector.
Look, those are all explained, in detail.
So this is a great thing to just read through this,
understand this for all the common classes. And
of course, all of the methods are listed here as well. For
example, look at this one,
setTitle. Hm, that might be a way to set the title. And
if I click on that, I get a full description of this. And
I even see that the state thing is here, so I can click
on that. And now I can see the control state, of course,
there's normal, highlighted button, disabled button,
a selected button. They can each have their own title,
cool. But you see how I'm navigating by just clicking
through the various types and
all that you really want to get faster with doing that
okay it's really important to be a good IOS developer to be
able to use the documentation effectively. All right, so
we're back here, we got this thing currentTitle. It's this
type string question mark. And I told you that swift would
infer the type. And sure enough, look, a digit. It's
type is string question mark. Of course, because I just set
it equal to something that was string question mark, so
it knows it's string question mark. So, let's go ahead and
print this digit out. Okay,
it's saying touch digit was called. Let's try and print it
out. Now in another language, you might use printf.
And you might say something like %s was touched.
And then you would put digit right here,
okay? Now unfortunately, you can't do this in Swift, okay?
There's no percent s business, okay? And no printf. Instead,
we still say print, okay? But, instead of doing percent s.
We can actually use the very magical\\() parentheses.
If you put that inside a string,
then you can put anything you want inside there that can
be converted to a string. And
it will include it there. Including,
a string itself. Can obviously be converted to a string. So
this way, you can embed strings in other strings.
Or even embed more complicated objects that know how to turn
themselves into a string, into strings. Okay, so this is how
you do the print f business of printing things out. Okay,
now also I notice, we have a warning. This yellow thing is
a warning, okay? And they can be yellow which are warnings
in which case it'll compile and run. But, you still got to
fix it cuz you cannot submit any homework in this class
with warnings. You hear me? Or they can be red.
In red's case, it won't even build. So this one's yellow.
How do we find out what it is? Well, we just click on it.
When we click on it, it says here the variable digit
was never mutated. Means it was never changed.
Consider changing to let constant, it says. Okay? And
you can see it even saying do you want me to fix it? I can
replace var with let and it's even showing what that would
look like to replace var with let. How helpful of it. So
actually, I'm gonna have to do that. I'm gonna click,
change it to let, warning gone. Now what is all that
about? It said digit was never mutated, it was never changed,
okay? So digit essentially was a constant.
We gave it an initial value. It never got changed.
When you declare a constant you always want to use let.
Now why do we have a different word for a constant than for
a var? Well, because a constant isn't var.
It doesn't vary, a constant is constant.
And let is a great word because read this. Let digit
equal sender's current title. Okay, reads really nice.
Now why do we care about distinguishing these two?
Two reasons. One if you're a reader of someone's code and
you see let you know that this is not going to change, okay.
You know the digit is going to be, never going to change.
And in fact if someone did change it or
if you tried to change someone else's code and change it,
compiler's gonna generate an error, okay. You can't change
something that's constant. But even more importantly,
it tells Swift that it's a constant and
that you intend it to be a constant. And so later,
if you try to modify it, even if it's an array or
a dictionary and you're trying to put something in the array
Okay? Or add something to the dictionary.
It knows, you intended that to be a constant. So,
you know, error. So it's a way to tell Swift what you intend.
Now, the difference between a mutable array,
an array that you can add stuff to, and
an immutable one, is huge. Because if you pa, arrays and
Swift are passed around by copy. Arrays are passed by
copy. It's very unusual compared to other languages
where an array would just be an object in the heap and
you just pass a pointer to it. You were passing them it
copies them every time you pass them to a function.
Now that'd be very inefficient if they were all mutable. Cuz
you have to actually copy them in case someone changed it.
But Swift knows which ones are mutable and which aren't.
And when you pass an immutable one it only- But
doesn't really efficient copy, okay,
it doesn't actually copy the element. And in fact, until
you assigned it to a mutable variable by saying var equals
that, it doesn't even have to worry about that. And then it
can just do copy on write when you actually change it. Okay,
so that's the var/let thing, get used to it,
always do let for constants. All right, so let's run
this now. See what's going on here. This should work, right?
We're getting the current title. We're saying, it,
well, whatever that title was was touched.
This should be good to go. Here we go. Seven. What?
Okay, well, it's kinda working.
I mean it's definitely doing something different And
it kinda knows which button.
But what's all this optional quote business?
What's that about? >> Well, that's because
digit is not a string, it's a string?, okay.
So what is String? String? is a totally different type
from String. It's called an optional. Alright? This
is super important. So again, wake up if you're napping.
Okay? This is super important. Very few languages have this
concept. It's a great concept. It really makes the API really
understandable throughout all of iOS. But it takes a little
bit of getting used to, okay? So what is this type optional?
A type optional has only two values, set and
not set, okay? That's the only two values it has.
There's no other values. However, when it's in the set
case, it can have an associated value. Okay?
A value that it kinda keeps on the side and
you specify when you create the optional or
you declare it what type that associated value is.
So this, the associated value is a string.
We're talking about the value of a button of course. So
we would say the type
of this digit is optional strength. Which means
an optional who's associative value in the set state is
a string. Okay? Now, in this case that's all fine and
good but we want the associated value here.
Give me that associated value, that title, okay?
How do I get it out of here? And the answer for
that is exclamation point. Okay, if you put
the explanation point at the end of an optional then it
will, if it's in the set state grab the associated value and
give it to you. So now look at the type of digit.
It's a string. Okay, Swift able to infer that since you
unwrapped this optional right here. You've got a string over
here. Now what if you do exclamation point and
that optional is in the not set state? Because
there's no associated value when it's in not state, that's
only when it's in associated. What happens to your app?
Anyone want to guess what happens? Crashes. Okay?
Kaboom. Now, I'm sure some of you conservative
folk out there are like, okay well that's it for
me, an exclamation point! I'm never using that.
I don't want my app to crash, that's horrible.
But actually having your app crash during development
can be great, because you'll find bugs really
fast and you'll be dropped right into the debugger
where the crash happened so you can figure whats going on.
How could this have happened?
So in this case were talking about the title of a button,
that means the title of the button was never set and
this is touch digit. That should never have happen. Okay
if that happened in something I shipped to my customer,
customers would be complaining left, right and center.
There's a button that has no title on it,
nothing on it and I click what,
you know what I'm saying?
So, you want to find those in development.
So crashing can be good sometimes.
Now of course you don't always want to crash when you unwrap
an optional and I'll show you in a little bit how to unwrap
an optional and get it to associated value. But test it
first to make sure that it's in the set state. Okay, but
for now we do this. Let's run and see what this looks like.
It should work. But now we've unwrapped this thing,
grabbed its associate value.
And we know the current title should always be set so
we'll not have to worry about crashing here. And
sure enough seven was touched, nine, whatever, three,
five, six, okay? All right, so we're rocking and
rolling here. We're able to collect the digits from user.
Now let's put them in the calculator display.
So we need to add a display to our calculator.
So we're gonna go back to our area here.
Go down to the bottom half. Now be careful not to grab
text field here because that's editable text and
in a compilator you can't click on the display and
edit it. You type the numbers to put your numbers in. So
we're gonna use this one up here, which is labeled.
By the way, if you click on one of these and
leave your mouse there for a second,
it'll give you a detailed explanation of each of these
objects in the list. So I'm just gonna pick out a label
and drag it up here to top,
maybe make a little more space for it. Move out a little bit.
So we've got this label. Once again just like I did for
the buttons I'm going to change the size.
Maybe I want to start with zero in there. Bigger font.
Let's go over here maybe even really big font, like 40 or
something like that. In a calculator the text is right
aligned. Right? Text comes out from the right, so
we want to use this alignment right here.
Right aligned. Okay? Maybe with some colors.
Let's put, let's make the background be blue.
But I don't really like black on blue, so
we'll go up here and change the color to be white. Okay?
So that's a pretty decent looking display
right there, for now anyway. Now, if we have these
buttons being pressed, we need to talk to this display, and
tell it what the digits are.
So how are we gonna do that? Well again,
we need to make a connection between that display and
our code. But this is not the same kind of connection.
Because we don't touch on that label, and
it calls a method, We need to have an instance variable, or
property, that points to that thing, so we can talk to it
whenever we want, cuz we gotta put these digits on it.
Okay? So we're still going to use the same mechanism to
make a connection, which is control. And we're going to
drag in here. Okay? And this time we're going to use
outlet. Outlet means a property that points to this.
And I'm going to call this display. It's our display.
It got the type right here. This weak and strong, don't
worry about that. I'm going to talk about that next week.
Okay. So don't worry. So, here is
our first instance variable in our class. Woo hoo! Okay?
This right here, is again just some stuff that Xcode
throws in there, so you get this, right? This,
I told you ignore, okay? So
this is the declaration of our property and
of course it's a var and that could be let. If you want
an instance variable that is set at the beginning and
never changes, you can use let. It's pretty rare, but
you can do it, okay usually they're var. Display,
that's the name. ": UILabel" is the type,
okay? So as you might guess, this has something to do with
optionals, okay? This is kinda confusing to
start off the bat, but that exclamation point,
which normally means unwrap an optional. Obviously we can't
unwrap here, we're declaring this thing here.
This is pretty much exactly the same as a question mark.
In fact, I'm gonna change it to a question mark for
now, and later I'll change it back to an exclamation point,
and you'll see the difference. But, the type of this display
is optional UI label. Now, why is this an optional UI label?
Why isn't this just a UI label?
Why does it have to be optional? Because when this UI
first comes up, iOS needs a few nanoseconds to hook
that up for you. So when this UI first comes up,
it's not set to an optional not set case and then UI hooks
it up for you, and now it's set forever after that. And
that's important that it's set forever, and we'll see it has
to do with that exclamation point I just got rid of. But
for now understand that display is just an optional
we'll have to unwrap it every time we use it, okay so
as simple as that. All right, so now instead of printing
the digits on the screen let's go ahead and
put these digits into the display,
and really every time a digit is pressed we wanna append it
onto the end of the display like if there's 56 in there we
wanna append 2- it's 562 and 8 it's 5268, right? So we're
just gonna keep appending. So we need to get the text so
it's currently in the display and add the digit to it.
So I'm gonna add another little local variable.
It's a constant also called textcurrentlyInDisplay and
I'm gonna get that by sending a message to the display,
which I have to unwrap,
and now I can send your message. And
here's all the messages that label responds too,
again, hundreds, okay? So I'm gonna do the same trick, I'm
gonna type text because I want the text out of there Look at
the very first one, the text displayed by the label.
It's an optional string. Excellent, I'll take it, okay.
So, now I've got the text but it's optional. So,
I need to unwrap it, okay? So now textCurrentlyInDisplay.
If I option click on it you'll see it's a string. So,
now I can just say, set the display, unwrap,
text equal to the text that's currently in the display
plus the digit. Now, notice when I set an optional, text
is an optional, right? When I set it equal to something- by
the way this optional is get and set unlike currentTitle,
which was get only- so I can set the your label's text here
and get it. When I set this optional right here,
I don't have to unwrap it first, okay?
So you don't have to unwrap an optional to set it,
you just set it. And optionals know okay,
this must be the associated value of an optional string,
so I will set it, okay? So that's it,
let's see if that works. Okay,
so we got our UI, looks good, got a display in there, mm-hm.
Let's try 8, well 6, well, it's kinda working.
It's definitely doing the appending thing,
but that 0 at the beginning,
that's wrong. That zero is not part of what I was typing.
That zero just happened to be there at startup.
So, it shouldn't be put in in the front there and
the problem here is really simple.
It's just that we haven't taught our calculator to know
when the user is entering,
in the middle of entering a number,
versus when it just started up.
Or maybe, the result of an operation just appeared
there. Obviously when we type we wouldn't want that to
have more, thanks to it. So, we need to teach our
calculator brain here to know the difference between whether
the user is in the middle of typing or not.
And we're gonna do that, by creating another property
called userIsInTheMiddleOfTyping.
Which is gonna be a Bool. Now, I typed a long name here. Kind
of for effect. We probably could have called this typing.
You know, there's trade off between clarity and brevity.
Okay, brevity is valued, but clarity is even more
important. So, maybe isTyping would have been enough.
But I would err slightly on the side of clarity. So I'm
using this long one. The other thing, the reason I typed this
long is to show you that I'm never gonna have to type this
again, because Xcode is always gonna escape complete this for
me, as you'll see when I start using it. Now when I added
this beautiful var, this Bool. Okay, a Bool, by the way,
is just something that can be true or false,
of course. I got an error. Look at that error up there.
This little thing here- it's on a line that had nothing to
do with what I just did. What? That's not fair.
What is this? It says Class 'View Controller'
has no initializers. Okay well, what the heck is that?
That has nothing to do with the var either?
Well, here's the deal here. In Swift,
all properties have to be initialized. Every single one.
No exceptions. Now there's two ways
to initialize your properties in a class or struct.
One is with an initializer.
An initializer is a special method, it's called init,
I-N-I-T. You can have any number of arguments that your
class requires but, in its implementation it has to
initialize all uninitialized properties. Okay? Now,
we're not gonna talk about initializers today.
I'll talk about it a little bit next Wednesday,
actually. So, we're not gonna use an initializer. Because
there's a second way to initialize, which is to just
give it a value. Okay, is false, right? The user's
obviously not in the middle of typing at the beginning, so
is false. And that got rid of the error.
Okay? In fact, we don't need this either. Do you see why?
Because false, can only be a Bool, So
Swift can infer that this must be a Bool. And again,
we do not want these things in here, if we can help it. Now,
what about this guy? That's not initialized. How come he's
not complaining, okay? How come he's not getting that?
Must be initializers business going on. Well, because he's
an optional. And optionals are special when it comes
to initialization. They all get this automatic treatment.
Equals nil. nil means not set optional. Okay.
That's the only thing nil means in Swift. It means
an optional that's not set. So optional will automatically
get this treatment at all times when you declare them.
And it makes sense right, if you have an optional
it's gonna start out not set until you set it.
Now you could set this equal to some UILabel of some sort,
and have it be set from the start, that's possible too.
But if you don't say anything it gets not set. Alright, so
we've got that. Now we can use this userIsInTheMiddleOfTyping
thing. We'll say if the user is
in the middle of typing then we can do,
this business that we just did here, okay?
What if it's not in the middle of typing? Then we're just
gonna set the display's text equal to the digit, cuz we're
starting a new number then. In this case of course,
the user is now in the middle of typing Okay,
everybody got that? So that's just how we're going to make
sure we do the right thing. So let's go ahead and run,
see if that whole 0, leading 0 problem is fixed.
Should be, because when we start off,
we're not in the middle of typing. So
when we start typing a new number, boom,
we get a new number. But if we're in the middle of typing,
we keep getting the appending deal. All right,
we are just rocking and rolling here.
Next, let's put some operation buttons in this baby.
We can type in numbers, now let's start operating.
I'm gonna do that by doing a very bad thing,
which is I'm going to copy and paste the 7 button.
You're gonna see why that's bad in a moment. And
I'm gonna do a very simple operation, pi, okay?
So pi is just an operation that's gonna put pi in my
display, that's all it's gonna do. So I'm gonna control drag
to wire it up to a method. It's an action, not an outlet.
It's an action, just like touchDigit was.
I'm gonna call it performOperation,
cuz that's what it does, it performs an operation.
I'm gonna make sure I switch this to button like you
guys all are in your homework assignments. And
then I'm going to connect. So now I have this new method
right here, and it is hooked up to pi, so that's good.
And what do I want to do in here?
Well, I could do the same thing of asking the button
which operation it is. How about let mathematicalSymbol,
because that's what these things are in these operation
buttons, equal the sender.currentTitle!, okay?
Great, now I've got the pi, but I wanted to show you,
I promised I'd show you how to do this unwrapping without
crashing, so let's do it here. Let's decide that if we do
have a blank button, a button whose title is not set, let's
say we won't crash. Instead, we'll just do nothing.
We won't do any operations.
Like you didn't even click a button, okay?
So, again, optionals are so important. You can see,
look how minuscule the syntax is for these things, right?
Question mark. Exclamation point. You barely have to type
to use an optional. Well, it's the same thing if you want to
test the optional before unwrapping.
Instead of putting the exclamation point at the end,
you put two characters at the beginning. if. So
read this. If I can let mathematical symbol equal
the sender's currentTitle, then. So,
if I can unwrap this optional, get its associated value,
then I'll do something, and
then you can just put whatever code you want in here,
and inside here,
mathematicalSymbol will be a string, the associated value.
The unwrapped optional, right? Outside of these curly braces,
mathematicalSymbol is not even defined, so it doesn't matter.
It's not even defined. So
inside this mathematicalSymbol, I could
say if mathematicalSymbol equals, pi, then do something.
Else if the mathematical symbol equals something else,
okay? But, if then else, if then else, if then else, that
would be really bad code. So I'm going to use a different
one here. A different little expression.
I'm going to use switch. So a lot of languages have switch.
So I'm going to switch on the mathematical symbol.
Not all languages can switch on a string. Some can, but
you can in Swift. And I can just say, in the case that
it is pi, then I'm going to do something. Now,
unfortunately I'm getting an error here.
So, what am I gonna do? Let's just put in what I'm gonna do.
I just want the display. Woops, the displays, text to
equal pi. Okay. This is pretty bad to type it in as a string,
we'll get back to that in a second.
But that's basically what I wanted to do, right?
Is set the display to be pi. Now I'm getting an error.
What is the error? It says switch has to be exhaustive.
And that's true. When you have a switch, you have to have
every possible case. So unless we want to spend the next few
lectures I guess going like this, case a-a-a, and
typing any possible string, okay, this is no good. So
luckily though, there is a default case. So
default just means all other cases.
And here I'm just gonna break out of the switch.
I'm gonna use this command break. Now notice that my
indentation's gotten a little messed up here. This should
really be the same indentation as this. A really cool feature
is select any text you want, even the whole file, and
do Ctrl I for indent ,and it will re-indent everything for
you. And I recommend you do that on all your source files
when you turn in your homework. Just select all,
indent. So we got this pi here. Let's see if this works.
Got the numbers are still working.
And pi. Okay. That's weird.
I got that pi that I typed in right here. Okay, but
what, how come I got this pi symbol added on there?
That seems weird. Let's try a new number. So, no, okay.
When I type more numbers, it adds it on to the end. So
even if that pi symbol wasn't in there,
I'd be able to change the value of pi,
evidently by adding more digits to it. That's no good.
And look at this. When I type more it puts an ellipsis,
and it stops taking numbers. Okay, this is a mess.
We got three big problems here. That pi.
The fact that I can add on things to the end of it,
and the fact that I get these ellipses.
So how are we going to fix those?
Let's go fix all three of those real quick. Okay. So,
first the pi coming on the end. Well look,
where do I ever set the display sets? I set it here.
Well, so clearly the pi's not coming from this.
I set it here. This only sets it to one digit so
that can't be it, cuz I've got multiple.
This is the only other place I set it. Maybe
this is the problem. Do you see the pi button right there?
It's hooked up to this method. And to this method. So
it's doing both. It's doing this and putting this on here,
and then it's calling this, and doing this. And
the digit is the pi, okay? So, that's bad. Now, how are we
going to fix that? Question? >> How did you set
the order range? >> Yeah,
the question is how did it decide the order?
And the answer is the order is undefined.
In my experience, it's usually alphabetical, but
it's undefined. So you would never wanna depend on that.
But yeah, perform comes before touchDigit.
I don't know. But you're almost never gonna have two
things hooked up like this. This is obviously an error.
This is causing a problem. So let's fix it. How do we do
that? There's another way to know what's connected other
than using the little circles, which is just to right click
on something in the UI. So I right clicked on pi, and I got
this big window that shows me all the connections to pi.
This would be all the instance variables, all the methods,
etc. And we can see that for the event Touch Up Inside,
which means a touch of the finger went up inside
the bounds of the button. It's sending both these messages,
touchDigit and perfomOperation, and
we clearly did not want touchDigit for pi.
Why did I get it? Because I copied and pasted that 7.
Remember I said that was a bad idea? Yeah, that's why. So
let's disconnect it by just clicking this little x, okay,
boom. Now this only is sent by this, and not by this.
So that fixed that. What about the fact that
I could type extra numbers on the end of pie? Well, that's
a pretty simple neither. When am I allowed to type other
numbers in? When the user's in the middle of typing a number.
Well as soon as I hit pi,
is the user in the middle of typing a number? No, they
just typed pi. So they're not in the middle of typing pi.
And in fact, they're typing a number.
And in fact any time we perform any operation,
the user is in the middle of typing a number is false.
They are clearly not in the middle of typing anymore.
Whatever's gonna be display is gonna be the result of that
operation. Okay, so that fixes that. How bout the little
ellipses, and the numbers getting cut off. Well here's
a kind of a cute fix to that. In label, there is a cool
feature called autoshrink, you see it right there?
So I just selected label, brought up this inspector.
There's autoshrink, and you can have it shrink down, for
example to a minimum font size, let's say 9 font.
And now, when we get too many numbers,
it'll shrink down instead of doing ellipses, right there.
Now, this probably isn't the best solution to this.
A better solution would be, have our calculator only show
a certain number of digits after the decimal point.
Probably would be really better. And
that's extra credit for you in your homework, okay?
So good luck with that. Right, so we got this.
We fixed all these problems, let's take a look.
All right, so got our numbers here. Pi, alright no pi and
it didn't add them on to the end and
what if we had a lot of numbers in here.
Yeah, look at that, it's autoshrinking.
Okay, we're not losing any numbers.
Yeah, probably not the best solution but
I get to show you autoshrink. Okay, what's next?
We're gonna attack this little problem right here. Okay?
This is really ugly, really what I want this to be is this
really cool feature in Swift, Double.pi, which is the double
precision floating point value of pi. Of course, I can't say
this because- Cannot assign value of type 'Double' to
an optional string because the only way you can assign
anything to an optional string besides nil would be something
that's a string. So we can set that associated value. Now,
does anyone know, from what I've shown you today,
how we could convert this to a sting? No brave soul?
Back, exactly. Backslash, open parentheses,
close parenthesis, that little trick, right?
You can just put Double.pi in here.
Doubles can be converted to strings, bingo.
Now, this is kinda ugly, okay? This really doesn't look good
because this is more meant to embed things in other strings.
It's not really the way to make something a string.
The way to really make a new string is to create
a new string. And so, here you're seeing what the syntax
is to create a new object, a new struct or a new class,
okay? The name of the class, and then parentheses.
Now, inside these parentheses, can be anything the class
can take to create one of itself, right? Anything that
class can take. And remember I mentioned those initializers?
These are the arguments to the initializer. And initializers,
you've got multiple initializers.
String has a whole bunch of initializers.
One of the initializers that a string has,
takes a double. So this would be the right way to
convert from a double to a string and
it looks a lot better in the code as well, right.
It's more obvious what we're doing, okay?
All right let's add another operation here,
I'm gonna make this one be square root. So underneath
the square root symbol, from the edit menu, emoji and
symbols, you can actually search. We could pick a smiley
face but let's go square root. Square root, here it is, so
we're gonna use this square root symbol in code there. And
let's go ahead and copy it so we can use it in the code.
All right, so we have this,
it's nicely hooked up just to this and not to this.
So that's good. We just need to say case of square root.
What do we wanna do? We wanna set the display's text
equal to the square root of something. Okay, well what do
we want this to be the square root of? Well we want it to be
the square root of whatever's in this display already. So,
display!.text, okay, will that work? No, because this
is a string and we can't take the square root of a string.
And not only that, the square root returns a double, okay?
And we can't put a double into a string, so we at least have
to do this again, put a string around it. Okay? But
this is still a string. So I'm gonna get this out of here and
make a little local variable so
we can work on this, okay? So, we need this operand,
which is currently a string, to be a double. So
can we do this, double? You think we can do that?
In the same way that we went this way? Can we go this way?
The answer is yes. Or yes! One of those.
The answer is yes because, what if that string is hello?
What do you convert hello to? It can't be converted.
So this initializer for double that takes a string,
it returns an optional double. Do you see why? Cuz if you
give it a string that it can't convert to a double,
it returns not set. Couldn't do it, basically.
So if we look at operand right here, it's an optional double,
okay? Whereas when we did this string up here,
string didn't need to return optional string,
because it can always convert a double to a string, always.
But you can't always convert a string to a double,
it has to look like a double. Okay?
So, we're gonna do that and I'm gonna go ahead and
force unwrap it here with the exclamation point, assuming
that I never have anything in my display that can't be
converted to a double. Maybe that's a bad assumption but
I'm gonna assume that for now. I'm also gonna Ctrl+I again,
to get my indenting right. Okay, does this make sense?
So now all is well. Operand is a double.
So I can take the square root of a double.
I'm gonna convert it to a string and go to here.
All right, wow, that's a lot of mess. Okay,
that's really messy code, I'm gonna have to fix that, but
conceptually you understand hopefully what's going on
there. So let's do this, let's try 81 square root. Square
root again. Square root again. How about pi square root?
78 square root? All right, this is working perfectly.
But, our code is really a mess here. Can you imagine,
if we have to do another case and another case.
And we're always doing this double this, string that,
back and forth, exclamation points everywhere. Okay,
there's too many dang exclamation points in here for
the first thing. And the second of all,
I'm tired of all the strings and doubles. So
I'm gonna fix all that. Let's start with the exclamation
point thing. Look at every time I use the display.
I use it all over my code.
And every time I have to put an exclamation point,
every single time. Even though I know that display,
once it's set up by iOS in the beginning, it never is not in
the not set state, it's always set. So
let's go back up here to this question mark.
This is what exclamation point in a declaration
of an optional means. It means yes, this is an optional,
just like a question mark. But, everywhere you use this,
I'm going to automatically unwrap it. Now,
it's still unwrapping it, so even if I go down here and
I take away this exclamation point,
it works because of this automatic unwrapping.
But if this were not set, it would still crash. Okay?
Because essentially, implicitly unwrapping.
That's why this is called an implicitly unwrapped optional.
Got that phrase? Implicitly unwrapped optional. But
it does mean, that we can go around to all of our
display question marks, and change them to display.
And that makes our code look quite a bit nicer. Okay?
Now we're still having to unwrap text. Sorry about that.
Bottom line is we have to do that.
That's not an implicitly unwrapped option on that text.
Okay, what about all this double and string thing?
The way I'm gonna fix that is imagine I had a var.
We'll call it displayValue.
And it was a double. Okay, show me this var.
Imagine if this var, all it tracked, what's in here, but
as a double? Cuz what's in there, we can only get it as
a string, we can only set it as a string. But
wouldn't it be cool if I had a var that just was always what
was in there but as a double? Because I need it as a double
all the dang time, and I need to set it as a double too,
okay? So how can I do that? Well, turns out Swift
has a really cool feature called computed properties.
And all I need to do is put code after the property, and
you can compute the value. Instead of storing
it, right. The user is in the middle of typing a value that
storage somewhere. This one we're gonna compute. And
you can compute both a get case, right? And,
oops, sorry. And a set case. So you can have some code that
deals with getting the value and with setting the value.
So we're not gonna ever store displayValue anywhere.
We're gonna get it and set it.
And where are we gonna get it and set it from?
From the text on the label. Right? So what does the get
look like? Well, we're just gonna return a double of
the display's text, you don't have to unwrap display, but
I do have to unwrap text. And I'm gonna force unwrap that.
Again, I'm assuming there's always a string that
can be interpreted as a double in there.
Maybe I wanna change that assumption down the road, but
for now I'll do that. How about the set case?
In this set case, I'm gonna display, set the display's
text equal to a string that is the value that
people are trying to set the display value to.
So somewhere in the code, we write displayValue equals
five. And here we have to put a five,
a string five into the text of the display up here.
So what do we put inside this little string here. Well, for
this set case, okay, of a computed property,
there's a special variable called newValue, and newValue
is always of the same type as what you're setting, and it is
the value on the right hand side of an equals if someone
says that this var equals something, okay? Awesome.
Now that we have this displayValue and
it's always tracking that, we can use it down here.
Look at this code, displayValue equals pi.
Done, get rid of all this mess. displayValue equals
the square root of the displayValue. All of a sudden,
the code down here has become essential, right?
This is about the minimum you could possibly type to say
that you wanted pi into the display. Right? And so, when I
do this display value equals, this code gets executed.
When I get the display value here, this code gets executed.
These are called computed properties. You're
going to see them all over the place.
You've already seen one. It's right here, currentTitle
is a computed property. It's computed by the button class.
It figures out what the current title is on there and
returns it. So there's this is implemented with some
code that says return whatever.
How do I know that? Because it's read-only. The only way
to make a read-only var is using a computed property.
All right, let's make sure we didn't break anything with our
code clean up there. All right, 89 looking good,
square root, 81, square root, square root, square root.
Pi 78 square root. Okay,
it's working. Okay, so that's a lot of stuff to digest,
I know. Let it all sink in. On Wednesday at the start,
I'm gonna talk to you about MVC, this design paradigm, and
then we're gonna add MVC to this and
we're also gonna make sure that UI works on all devices.
Okay, see you then. >> For
more, please visit us at stanford.edu.