Transcripts
1. Introduction: Hello and welcome. In this 14 day
beginner challenge, you're going to start your
journey off with a bang. You're going to learn
how apps are made and how they end up
on the app store. You're going to get
familiar with Xcode and hence start your very
own app project. You're going to
learn how to build user interfaces with Swift UI. And you're going to learn Swift programming basics so that you can read and write
simple Swift code. Now in the next 14 lessons, you're going to gain all
of these new skills. And you're going to have built your very own app that
you can install on your device and show all of your friends and
family what you've done. More importantly
than that, however, you will be extremely confident
and excited to continue growing your app
development skills beyond what we've covered here. This really could be the start
of something new for you. Okay, So if you're
ready, let's roll up our sleeves and get started.
2. 01: The Apple Developer Ecosystem: I'm going to walk through
this diagram and then after, I'll tell you where to
get all of the pieces, it all starts with
the Xcode IDE. Now, IDE stands for Integrated
Development Environment, which is a term for
the application and all of the tools a developer
uses to build something. For the rest of this course, we'll simply call it Xcode. This is where we build our
app by writing Swift code, building the user
interface or UI for short, and connecting it
with all of our data. Swift is the programming
language we use to express our logic and to tell the
system what we want to do. We can even build the
UI through swift code, as you'll soon see. Now, Swift UI is a UI
framework that makes it easy for us to rapidly build apps for all the
apples platforms. A nice benefit of
learning Xcode, swift and swift UI is that
they're the same skills and tools used to build all apps for all of
Apple's platforms, including iOS, iPadOS, tvOS, watchOS, and Mac OS. And in some cases, your app will be able to work on multiple platforms without
much changes at all. Now, once your app is built, you could distribute it
with Apple's App Store. This is done by joining the
Apple Developer Program, which requires an
annual enrollment fee. Once you're enrolled, you get access to multiple benefits, including the App
Store connect portal, test flight, and the
provisioning portal. There are some more benefits
including access to beta software and support
from Apple engineers. And I'll provide a link
to the full list below. The provisioning portal
gives you access to tools for identifying and
code signing your app. It's like putting your
signature on the app so that Apple can
identify who built it. And this is important
for the safety of the end users
downloading your app. And it's also important
for you because it stops malicious coders from
pretending to be you. Once your app is in
a testable state, test flight allows
you to invite people to download and
beta test your app. There'll be able to send
feedback and bug reports directly to you through
the test flight program. Use test flight to
ensure that your app is as polished as it can
be before launch. And finally, App Store
connect is where you'll create the atlas
thing for your app, including all of the
metadata and screenshots. If your app has
in app purchases, this is also where you
would configure them. Once your app is tested
and the listing is ready, you can upload the
app from Xcode to App Store connect from there, the certification team at
Apple will review your app to ensure that it meets the App
Store quality guidelines. This takes a couple of days and don't worry if you
fail because you can fix whatever they point out and resubmit it for review. If everything looks good, they'll approve the app
and your app will be live. Congratulations. All right, so where can you get these different pieces of the
Apple Developer Ecosystem? You can download Xcode for
free from the Mac App Store. I'll provide a link below. You don't need to get
Swift or Swift UI. Those just come with Xcode. As for the Apple
Developer Program, I'll provide a link to the
Enrollment page below. I want to mention that joining the Apple Developer
Program is completely optional if your goal isn't to distribute apps into the
App Store, don't join it. You'll still be
able to learn how to build apps for yourself. So that's the Apple
Developer Ecosystem. It's the process that I'll
be taking you through if you continue on
with this app journey. Now by the end of
this learning path, you'll be building your own apps using all of these tools
that we've covered, even if you don't have any
coding experience right now, I promise you, you'll
be surprised at what you can do by the
end of this challenge. In the next lesson, we're going
to dive right into Xcode. All right, I'll see you there.
3. 02: Xcode Tutorial: Hello and welcome. In this Xcode tutorial, you're going to
get familiar with the development environment that you'll be building apps in. I'll show you where
to download Xcode and how to start a
new app project. And then we're going to go
through the major areas of Xcode and then what each of the files in your
app project is four. And then finally, we'll
wrap up the lesson with some quick tips on how to
navigate around in Xcode. Alright, with that
said, let's dive in. Let's start by talking
about where to get Xcode. It's free, so you don't
need to pay for it. Just launch the Mac App Store on your computer and
then search for Xcode. You're going to get to a page like this in the search results. Click into it, and you're going to be able to
download it for free. So I've already
got it downloaded. So that's why it
says update here. I want you to just
ignore the warning here. It's actually a very large app with a lot of
different features. It's understandable that
there are a few bugs. And if you look at the reviews, there are people
complaining about other things
unrelated to the app. They're complaining
about the way Apple is running their business
and so on and so forth. And some of these
are very, very old. Okay, I want you to take note of this important
information. Click on this just
to make sure what the requirements are
to install Xcode. And also double-check that you have enough free
hard-drive space. Now in my experience, it actually takes more hard
drive space over time. Then what it says here. So if you have something
like 12 gigs free, it might not let
you install this because during the installation
process it actually takes up more space and
then I think it gets rid of a bunch of files and
it stops at this size. However, over time,
when you download additional developer components and additional iOS simulators, this can actually
get even higher. So make sure you have
sufficient hard drive space. All right, so if for some reason you can't get access
to the Mac App Store, you can also visit the official Xcode page on
the Apple developer site. So the URL is developer
dot apple.com slash Xcode. And you can immediately click on the Resources link up here. And then you'll be taken
to a page where you can download Xcode here it just takes you through
the Mac App Store. Actually, you can also download
beta versions of Xcode. Now I wouldn't
recommend this because oftentimes it actually
is pretty buggy. There beta software. So I would recommend to stick
with the official releases. If for some reason you want to download an older
version of Xcode, you can scroll down here and you can click
this link here. Now just a note, in
order to download beta versions of Apple software, you need to be enrolled in
their Apple Developer Program, which we talked about
in the previous lesson. To download older
versions of Xcode, I don't think you need to be
enrolled in that program. I think you just need
a free Apple ID. And lastly, if you are on a
PC, you're running Windows. Check the resources
in the beginning of the course for options for you. Alright, so now take
the opportunity to download and install Xcode
if you haven't already, and then launch it
for the first time. During your first launch, it's going to ask you for your administrative password to install additional
development components. You're going to want to do this. So go ahead and enter
in your admin password. After you've done that, let's continue on with the
rest of the video. All right, so now let's
talk about how to start a brand new Xcode project. This should be the
first welcome screen that you see when
you launch Xcode. If you don't see
this, don't worry, you can always go to File
New and choose project. Otherwise, from this
welcome screen, you can go ahead
and click Create a new Xcode project from here. From here you're going to choose a template for your new project. You're going to configure the project properties for this, and then you're going to
choose a place to save it. So let's start by
choosing a template. The most basic one for our
purposes is under iOS and app. So go ahead and choose
that and hit Next. And then here you're
going to configure the properties for your project. So if you don't have a
team here, don't worry. Later on you can add
your Apple account here and then you can configure
the team for the project. One thing that you will want
to make sure of though, is to set your organization
identifier here. If you have a business
or a website, you can use reverse
domain style name here, com dot, whatever that may be. And you can even use your first and last name
here if you'd want. And then here you'd
fill in the name for your app or the product name. So here, if I put it in test, you'll see that this
bundle identifier is a combination of the
organization identifier plus the product name. And this together forms this
unique bundle identifier. This bundle identifier is used in different places
to identify your app, such as in the app store or
in the provisioning portal, or in App Store connect. So this is very important. Don't worry, you can change the bundle identifier for
your project later on. I just want to draw
your attention to how it's formed and
what it's used for. All right, next up. Your interface,
you're going to make sure that you have
Swift UI selected. And for lifecycle,
you're going to make sure you have Swift
UI app selected. And then finally for language, choose swift and
for these options, just leave them all unchecked or if they are checked,
just uncheck them. Now a brief note on these
drop-downs right here. Over time, as app development
for iOS has evolved, there have been a couple of programming languages and also a couple of ways of
building user interfaces. The latest and greatest
is swift UI and swift. So that's what we
want to be using. Let's go ahead and hit Next. If you're happy with all
of your selections here, and then choose a
place to save it. I'm just going to
save it on my desktop so that it's easy to find. Since I've already got
her project there, I was just going to replace it. All right, Welcome to your
brand new Xcode project. Now it might seem
overwhelming with all of the different
panels and areas, but it's actually not so complex once you know how it
gets broken down, there are actually only
four major areas of Xcode. Let's start from the
very, very left. Here we have the navigator panel or the Navigator Area in, as you can see here, we have a file listing of all of the different files
in our app project. The navigator area actually has different tabs to navigate through different
things as well, which we will get to in
future lessons for now, it's set to the first tab and we have a listing
of our files. When you click on a file, it changes what is shown
in this big main area, and this is called
the editor area. It allows us to
edit the files that we choose it in the
file navigator, you can see that it adapts to the type of file
that you choose. Choose a dot swift file, those are code files. If I choose this XC assets file, this is an image library, so it's showing me
something like this. The editor area is a place to edit the file
that I choose here. So the last tab is on the very right-hand side and this is called the
inspector area. And it either shows me additional supplemental
information on what I selected the editor area, or it allows me to configure
or edit the thing that I select in the editor
area depending on what sort of editor
I'm currently working in. So for example, this is a code editor because I'm
looking at a dot swift file. When I hover over or
select the key word here, if I'm on this Quick Help tab, it's showing me some
quick information about what that piece of
code or keyword is for. The inspector panel also has a couple of
different tabs up here. For example, this one
is an identity tab. It shows me information about that file that I've
got selected about where it's located and which app it's included in an if we were building
our user interface. Now if I were to select one of those elements and
go to this tab, it would allow me
to configure it. So to sum it up, the
inspector panel here is contextual to what you
select in the editor area. And the editor
area is contextual to what you select in
the navigator area. So it all stems from what you select here on the
left-hand side first. And then across the top, we have the toolbar here. Let me explain to
you what this is. There's a button here on
the very left and very right to hide and show the
navigator and inspector. These are handy if you don't have a lot of
screen real estate. Next thing I want to
draw your attention to is in the middle here. This is the status bar. It tells you what's
currently happening. What is Xcode doing? Do you have any errors? Do you have any warnings, and so on and so forth. To the left of that, you have a drop-down
to select a simulator. And this iOS simulator
is basically a virtual device that appears on the screen where you can
run your app and test it. You don't actually need
a physical device. If you do have one,
however very new, plug it in and you want to run your Xcode project on
your actual device, you'll find that it will be selectable from here
once you plug it in. And then to the
left of this menu, you're going to see a couple of buttons here to
run your project. Hitting this button
will actually run your project in this simulator. And hitting the stop button will stop running your project
in the simulator. And then all the way on
the right-hand side, there are also two more buttons. This is the library button
where you're going to find different user
interface elements, different ways to
modify those elements. Code snippets in the assets
you've added to the project, the colors that you've specified for your
project and so on. This little library panel
is useful to do a search. And to quickly select and add things into the editor area. We're going to get to
that in the next lesson. But for now, that's
the library area. This, you probably won't use
too much in the beginning. This is a revision
or code review sort of button that will show you if you're
using source control, how your files have been
changed through time. So those are the
four major areas of the Xcode user interface. All right, now let's go over the files in your new project. Let's start from the very top. This is the root node, or it's your project file. If you selected, the editor
area will change into this configuration screen
for you to edit some of those details that
pertain to your project. For example, here's the bundle identifier
that's changeable. You can configure device
orientation in which devices and which platforms that can run on,
things like that. If we go down a level, you can see that there
are two folders here. This one is containing all of your code files
and project files. This products one
contains the output. When you build your
app and compile it, it gets turned into this app, which ultimately is that
little deployable bundle or package that we send
into the App Store. You don't really have to do
too much here with this, but that's where it's stored. All right, let's take
a look at this file. This will be named after your product name,
app dot swift. And you can see here
with this main tag here, this is the entry
point to your app. At this point, there's not
too much to configure here. All it really does is create that first view
that the user sees, which is content view. And you can see that this name maps to content view dot swift. So let's take a look at this. This file represents the
view that the user sees. Now you can create
additional views, but by default you get this
content view to start with. And yes, it's all code here. So that means that
the user interface is generated by code. But also there is a visual way to customize
the user interface, which you'll see in
the next lesson. Let's move on with
our other files. This one, as I mentioned before, is our asset library. This is where we can store
the colors for our app, as well as the app icons, as well as any other images that we want to
add to our project. We just drag it and
drop it in here. And this is our image asset. Well, not just images
but Asset Library. And then we have an
info.plist and this is some additional configuration information for the project. Here we have preview content, and this is another
asset library, but these are only for
pre-production assets. So only images and text
and colors and things like that that
you're testing with as the name preview suggests, if it's an asset that
will ultimately make it to the app that you're going
to push the App Store, then you can put it in the
asset library here instead. So that's a quick
explanation of all of the files in your
project in a nutshell. In the future lessons,
we're going to dive deeper into
each one and you're going to see how each
of these files play a part in the
construction of your app. The last thing I want
to do in this lesson is to give you a
couple of quick tips on navigating around Xcode in terms of going
through your files, and also in terms
of editing code. So first of all,
let's talk about navigating around and files. You'll notice these
two arrows here. These are really handy
because it's going to let you go to the last file
you were looking at. And although it seems
a little trivial now, when you're jumping
around editing and files, this becomes really handy. Instead of having to go and re-select that file
from the navigator, you can just hit back and jump back to that previous file. You'll also notice that you
can have multiple tabs here. So you can hold down
control and you can click on a file and you can always choose open in new tab. You can also open in a
new window if you'd like. So since I already
have that as a tab, then it's not going to
open a second tab for me. Now, if you want to have
things side-by-side, you can do that as well. So let's say I wanted to look at both these files side-by-side. So I can close this. And then I can go
ahead and I can add another editor pane
on the right-hand side, so I can split my editor
area into two Editor areas. You can see that
here I'm looking at content view that
swift in for here. Let's look at the test app. So they're independent areas. I might want to get
rid of my canvas. And then I can see
both PFOS like that. If you prefer them to be
horizontally stacked, you can hold down Option. And you can see that
that icon changes. Right, if you hit
this button again, it's going to add another
editor area to the right. So you're going to
split into three. Or you can hold down Option and you can add an
editor to the bottom instead. So you do that. You can also do that here, hold down Option and do that. Now a quick way to launch a file into a split editor view. So let's say I'm looking at
test app and I want to open up content view as a
separate editor area. I can hold down Option and
click on the file that I want to open in a
separate editor view. So those are some of the ways that you can work
with your files. Just to recap, you can navigate. You can go back and go forward. You can have different tabs. And then also you can
split up your editor area into multiple instances
of the editor. Now I want to talk
about editing code because this is a lot of
what you will be doing. And the code looks
pretty short right now, but it can get longer. So it's handy to know a couple
of ways to deal with that. At the top here,
you're going to see this sort of breadcrumb menu. And you'll notice that that is the root node corresponds
to that, right? This is a folder or
group, can see that. And then this is
the content view, which is the file that
you're looking at, which is here inside tests. And here, we can actually click this and you can jump to
different sections of your code. You can see that content
view matches that. Body matches that, right? So this is a great
way to jump to different sections
in your code file in case your code file
gets pretty long. You can also add different
comments in here that will correspond to
what you see up here. So you can see
here, I've created my own documentation
and it adds it here. So this is a great way
to organize your file. We're going to talk again
about this in the future. So don't worry if this is
going a little too fast. All right, Now we're gonna talk about this little button here. You've seen me use this
to open up the Canvas, but you can also open up
this minimap right here. And this minimap will show you an outline of
your code file. You can drag this to
scrub through your code. Unfortunately, I can't
do it very much here because this code
file isn't very long. But if you had a
really long code file, it would show you the outline of that code file down here. And you can navigate really easily by clicking
and dragging this. You'll notice that
even as I highlighted, it's gonna show me the
different parts of my code corresponding
to what we have here. Again, those were just
some quick fire tips. Don't worry if that flew by
too fast because we will be using all of these things together in the
upcoming lessons. So that's a quick tutorial
to get you started. Not so complicated once you
know where things are right, Just to recap, you
found out where to download Xcode and how to
start a new app project. You learn what each of the
files in your project is for. And you learn the major areas of Xcode including the navigator, the editor, the
inspector, the toolbar. Finally, you'll also
learn some quick tips about how to navigate
around with that Xcode. Now, don't worry
if it's a little bit overwhelming right now, you'll feel right at home with Xcode as we use it more often together in the upcoming lessons to help you get settled in, I actually created an Xcode cheat sheet
which you can print out and keep by your side as you're learning to use Xcode, I highly recommend
that you try to create your own Xcode project on your own computer just
for extra practice. In the next lesson,
and we're going to use Xcode to build our
first user interface. All right, I'll see you there.
4. 03: How to Build User Interfaces: Hello and welcome. In this lesson, you are
going to learn how to use Xcode could build user
interfaces with Swift UI. We're going to first learn
how to preview the app so you actually can see what the
user interface looks like. They're not show you how
to use Xcode to visually construct the user
interface or UI for short. Now up until now, the learning has been
pretty much passive, meaning that you can just sit
back and watch the videos. But starting now, we're going to switch into
more active learning. I want you to do what I do, replicate it on your
own Xcode project. And I want you to attempt
any of the challenges you, this is the best way to learn. And quite frankly, if
you're just going to sit back and watch the lessons
and not do any of the work. You're not making the
best of your time. This has been my
personal experience and I think it'll be
the same for you. So if you're ready, we're going to start
getting our hands dirty. Let's do it. Let's start by creating a
brand new Xcode project. We're going to choose iOS app. And I'm going to call
this one UI test. Just make sure interfaces Swift UI lifecycle is swift
UI app and language is swift. Other than that, you can
name it anything you want. Let's go ahead and
save our project. And like I mentioned in
the previous lesson, content view dot Swift
represents your view. But as you can see,
it's all code. So how do you actually see
what your UI looks like? Well, there are two
different ways. The first way is
to launch your app in an iOS simulator,
like I mentioned before. So let's go ahead
and do that first. Select one that you fancy. So I'm going to
select iPhone 11. And I'm going to hit this
build and run button. Now it's the first time you're launching
the iOS simulator. It's gonna take a
while to boot up, just like it would be to boot up a real device for me because I've launched
the simulator before. It's happening really,
really quickly. As you can see, by default, your project has a
Hello World label. We're going to talk
about that in a second. But first, let me show you the other way you can
preview your app. So let's go ahead and
stop our project. And that's going to stop the app from running in the simulator. The second way is to preview your app in this
canvas right here. That's part of the editor area. If you don't see this, you can click on this
little button here and make sure that there's a
check mark beside Canvas. And if you're looking
at a dot swift file, which is a view, you're going to be able
to see this Canvas. Otherwise, if you're looking at this entry point file here, you can see that
there's no preview. So let's go back
to content view. Make sure we have our preview
here and click resume. It's going to build and run it. And then you're going to
see the preview here. Again. If this is the first
time you're doing it, it might take a little while. Let's use the zoom
controls down here and zoom out a little bit so that
we can see the whole thing. Now just off the bat, there are a couple of things I
want to mention here. This is simply a preview, whereas when you launch
that in the simulator, you're actually
installing that app in a virtual device so that you can interact
with it and test it. Here, this is a preview that
you cannot interact with, but there is a way that you can. So if you click this
button here, live preview, it goes into a mode
where it's just like the simulator
that you saw before. But it's in this preview canvas. So you can go ahead
and hit Stop. And then again, it just
becomes a normal preview. That's only for
previewing purposes. Another cool thing about using this preview canvas is that you can hit this button here and you can choose
a different device. You can choose a layout, you can choose dark
mode or light mode, and you can pick a number
of different things. This is the preferred
way to preview your UI because as you're building your UI through
code on this side, you're going to be able to see things change on the right here without having to relaunch
the app in the simulator. All right, now let's dive
in and talk about how we're going to actually
build the user interface. So make sure you have content
view dot swift highlighted and go ahead and hide
the file navigator. Now there is a bunch of code
here that make up the view. But we're going to go
through it in depth later on when you learn some of the Swift programming basics for now, to avoid confusion, I just wanted to draw your
attention to one thing, which is this piece
of code right here. What I've highlighted on
the screen is what is generating this label here
that you see in the preview. Notice that we have
a text keyword. We have the helloworld piece of text that you can see here. And we also have this
padding element here, which gives the padding
around the word. Let's take a look at this piece of code and break it down. I'm actually just going to
go ahead and delete it. As you can see,
Xcode is going to throw all sorts of
complaints and errors. But don't worry, we're
going to fix it right away. Now, our user interface
elements have to live in between this opening bracket
and this closing bracket. And you can only have one
user interface element. Now obviously that doesn't
make sense because our user interfaces are made
up of more than one element. But that's where container
elements come into play. And I'll show you a couple of those in this lesson as well. For now, let's recreate
that text element. So what we write is that
text keyword followed by a pair of brackets like
that, rounded brackets. And then inside there we have
a pair of quotation marks. And then we put the piece of text that we want to display. So here I'm just
going to put hello. But you'll notice that
this blue frame ramps very tightly against
my hello text. If you wanted to add
the padding back, then you would write dot. And then you would just type in padding and using autocomplete, you can just select
that one right there. And just like that, we've recreated that
label with padding. This right here is the
text element or the label. This part with the dot padding. This is called a modifier. And you can think of a
modifier as an attachment to an element that changes
the look and behavior of it. In this case, this
padding modifier adds padding to the text elements so that if there is an
element right beside it, there will be some space
surrounding our text element. And there are actually many
more modifiers that we can add to our user
interface elements. For instance, I can add
one called background, and I'll just add it to the
end of the padding one. And I'm going to say that the background for
this label should be blue. So you can see that our
preview canvas very nicely represents what we're
writing here through code. If there's any time that
things get out of sync, maybe the code you're writing here is saying the
background should be green, but you're not seeing it here. The code is
considered the source of truth because ultimately, the preview canvas and
even what you see in the Inspector panel are just visual representations
of the code. And that brings me
to my next point, which is when you're
building the user interface, you don't have to write code. There are so many visual ways
for you to build the code. Let's erase this text
element and again, and let me show you some
of the ways in which you can visually build
the user interface. I talked about the
library panel before. So you can see here that
we can simply select, search for the text
element selected, and we can drag it into our
code editor right here. And then we can change
the placeholder text, but we don't even have
to change the text here. If you click on
this text element and you go into the
inspector panel, you can change it
here like that. And then also in this
inspector panel, you'll see that
there are a bunch of modifiers that we can add. So the add the padding, I could click this to
add top padding only. And you can see that
the code changes. And it's specifying that it
only one padding on the top. And you can see it
reflected here. Or I can click this one here
and turn padding on or off. And you can see now I have
padding on all sides. So in addition to some of the modifiers that you see here, down here, there's a
text box where you can search for more modifiers. So I can search for the
background one and click that. And then select that
blue background, as you can see here. And then I can also
add that padding. Now, in addition to using
the modifiers that you see here and using this
Add Modifier textbox, you can also use the
library to add modifiers. So this first tab gives you all of the user interface
elements that you can add to your view here on
the second tab or modifiers. So as you can see, there's the padding one, there's the background one. So how do you go about
adding these modifiers? Well, you just click
and you drag it. But here you have to
make sure that you drag it to the end of the code. Because if you accidentally drag it in the
middle of your code, it might not take, or you might get
something like that. That clearly is an error. So let's undo that. So as if that weren't enough, there are a couple
more ways I wanted to show you on how you can modify your user
interface elements visually instead
of writing code. First of all, let's finish
configuring this background and we're going to select blue right there,
or maybe green. Okay, that's not changing that. So it is changing that, but it's not changing here. So I'm gonna go ahead
and select the color, and we're going to do
green, lowercase g. All right, so you can
hold down Command on your keyboard and
then you can click on the user-interface element
from your preview right here. And then there are a
number of things you can do with that element, including this one, show
Swift UI inspector. And then again you get
this Add Modifier, TextField, what you can
search for modifiers to add. So I'm going to add
one called Blur. You can see that it is
blurring the color green. And you can see that now my
background is a blurry green. Now you can do the same thing
on the code editor sides. So you can hold down
command and you can click the text element and
you get this menu. You can, again click
Show Swift UI inspector. And from here you can see that this menu looks like
the inspector here. And we can also add
modifiers as well. So to illustrate my point, I've shown you a whole bunch
of different ways for you to modify your user
interface visually. You don't have to
write the code. But over time, as you're doing
this in the visual manner, you're seeing the code that is generated over and over again. You're gonna get to a point
where it's so familiar, it's going to be faster
for you just to type it out rather than
clicking everywhere. So it's a really neat way to learn the user interface code. Isn't that pretty cool? Xcode has come a long
way in the past. It used to be very fussy to use the visual interface
builder with Xcode, but Swift UI has really
changed things for the better. Now in this lesson,
you'll learn how to use the text element and had a modify its look and
behavior using modifiers. In addition to that,
you also learn that the UI is actually
generated from Swift code. However, there are a
multitude of ways in Xcode to build your UI visually. And as you construct
your UI visually through the previous Canvas or
the inspector panel, as we demonstrated,
the swift code in the code editor updates automatically to
reflect those changes. So this is a great way
to learn the swift code. The next time we sit together, I'll introduce to you additional views and
containers that you can use so that you can build more complicated
user interfaces. All right, I'll see you there.
5. 04: SwiftUI Views and Containers: Hello and welcome. In this lesson, you are going to learn how to use a variety of different user interface
elements and containers. And then at the
end of the lesson, I'll show you a couple of
user interfaces that I'd like you to try to build
yourself as practice. Remember, you're
going to get a lot more out of this course
if you stopped throughout the lesson and tried
to replicate what I've done on your
own Xcode project. All right enough talking.
Let's get to the fun part. Alright, right, so you've
learned about the text element. Now I want to show you
the image element. So we're going to go
ahead and erase this. And why don't we
use the library to look for the image element. So let's go ahead and drag
and drop the image there. Now the problem is that we don't have any image to display. But before I tell you
how to specify that, just noticed that It's sort of in the same format as
the text element right? There is the image keyword here, and then there is a
set of round brackets. And in the middle, we're going to put
our image name. Now, this image name maps to whatever graphic asset we've
put into our asset library. So if we open up our
file navigator and we go into our asset library, you can see that it's all empty. We don't have anything here. So let's go ahead and
put an image in here. If you go in to the
lesson resources, you're going to see a zip
file called Logo assets. And let's go ahead
and unzip them. And then inside you're going
to find a local image. You're going to find
three files actually. And they're named the same way except with an apt to
x and then add three x. And that is literally just two times as big
as the first one. And this one is three times
as big as the first one. And the reason why they come in different sizes is because there exists iOS devices with different
screen resolutions. So by adding all three sizes, the platform will pick the right size to use for
the screen resolution. It's being displayed on. So all you have to
do is grab all three and then drag it into the
asset library like this. It's going to be smart
enough to know that those three are in
the same group. And it's going to
give it a name. You can always rename
this so you can click it and you can name
it anything you want. But this name right here is
what you are going to be referencing in the
image element. So go ahead and put
in quotation marks, that image asset name, and you should see
it appear here. Oh, actually automatic preview, updating, paused, go
ahead and hit Resume. All right, in there
we see our image. Now by default, it
displays the image at the size of the graphic
asset that you imported. However, if you
wanted to resize it, scale it up or down, you can add a modifier
called resizable. When you hit that, it
will be able to stretch. When it stretches if
you wanted to maintain the aspect ratio because
you can see here it's all stretched out and it doesn't look like
the original image. You can add another modifier
called aspect ratio. And don't forget,
even though I am typing out these modifiers
through code here, you can always add them
through this menu. You can find it right there. And then the aspect ratio
modifier allows you to select different ways in
which this should scale. So if I say fit, it's going to scale it up
to fit within the bounds. But with maintaining
aspect ratio. And while we're adding
these modifiers, this would be a good
point to mention that a good practice is to hit Enter on your modifiers here so
that they become aligned. Because some elements
might have a list of modifiers and by putting
them all on a new line, they automatically indent under the user interface
elements that they pertain to and it becomes
very easy to read. All right, now you know about text elements and
image elements. How do we go about
combining the two? How do we go about having more than one element
for our user interface? This is where container
elements come into play. So let's go ahead into our library and let's
search for v stack. This is the one that I'm
referring to, vertical stack. And you can go ahead and
click and drag it in here. Now, you're gonna get some errors because this
counts as an element to. Now, it seems that
Xcode hasn't caught up, but this wouldn't be a valid UI. Essentially, we have
two elements here. What we wanna do
instead is we want to take our image and
I'm going to cut that code and I'm going
to paste it in between this opening bracket and closing bracket of
the vertical stack. Inside the vertical stack, you can put up to
10 elements and it's going to stack them
vertically on top of each other. So here I'm going to also put. Text element like that. And you can see that
now I'm able to have two elements and they are automatically stacked
on top of each other. In addition to the
vertical stack, there is also a horizontal one. And instead of the stack, that is H stack. And if you change
that to an H back, you'll see that it's now stacked horizontally
beside each other. And there's also one
called zed stack, I'm in Canada, or z
stack if you prefer. And this places things on
top of each other with the elements at the top being
the farthest in the back. So you can see that
our text element hello sits on top of the image. Now cool thing is that you can nest these different
container elements. So I can have, let's say, I want my image, logo to be the
background and on top, I want to have to text
elements side-by-side. So then I can use
an H stack in here. And rather than typing it out or dragging
it from the library, I'm going to show you
another way in which to embed your elements
into the stacks. If you hold down Command
and click on the element, you've seen this menu before. You can embed in H stack and it's just going to
create that for you. And that's probably the
easiest way to do it. So in this H stack, I'm going to add hello world. You can see here
that now my image is behind this H stack
with two text elements. Now it seems pretty intuitive
using these stacks, right? But how do you arrange the
elements inside this tax? Well, there are some options. So if I click on
this stack here, actually let's take
a look at the stack. So I'm gonna go ahead
and click that. This one actually has alignment. So does that stag
doesn't because it just puts everything
on top of each other. But for the H stack
and the stack, there is an alignment. So you can choose to align
everything by their middles, align everything by
their baselines, or align everything by the top. And you can also add spacing. So you can see here I'm
adding a spacing of three. You can see how it changes the code and it actually
adds a spacing there. Now it's too little for you
to notice that let me add 20. You can see that
there is a gap now. Alright, so you've
learned that you can align the elements
inside a stack, and you can also add spacing
between elements in a stack. But I want to show
you another way of arranging elements
inside of a stack. In order to do that,
I'm going to change this stack into V stack. So we're going to get
something like that. Now let's say I wanted this
logo to be at the top, and I wanted my two text labels
here to be at the bottom. One way I could do it is actually by adding spacing
in my v stack, right? So let's say I add a 100. You can see that
they're pushed apart. If I can add more, 300. But this is a fixed value. And as you know,
there are a ton of different screen sizes
and resolutions. So this isn't a good
way of approaching it. Let me get rid of
this spacing value. Instead, what we can use is
an element called a spacer. So let me show you
how that works. In-between the image element and the H stack containing
the two text elements. I'm going to insert
a spacer element. And the name of this
element is spacer, followed by two
rounded brackets. What this spacer element does is take up all the available space. It just expands and
pushes everything away. So you can see, I've
got the image here. I've got the spacer taking
up as much space as it can. And then my H stack containing
the two elements there. The cool thing about the
spacer element, however, is that it plays nice with other spacer elements
in the same stack. So if I go up here above the logo and I add
another spacer element, what ends up happening is that the two spacer elements both take up an equal
amount of space. You can see above and
below the war logo, there is an equal
amount of space. If I add a third spacer
element beneath my H stack, what do you think's
going to happen? Well, all three space where
elements are going to share the available whitespace. So the first spacer elements
here, second one here, and the third one is there, and it's all having an
equal amount of space. This is a great way to
space things out equally. Now in fact, I could
do the same thing with my H stack instead of
specifying spacing here. And notice this
time I'm just going to delete that spacing 20 there. Instead of changing
it in the Inspector. I can add a spacer there. I'm going to copy that. And you can see here it takes
up all the available space, pushing my two labels the side. But if I add one here
on the right side, it's going to push
it to the middle. And then if I add
one in the middle, then it's going to make
it all equidistant. Awesome. You learned how to use
the image and space for elements in addition
to the text element. You'll also learn how
to use the Stack, HCI Stack and zed
stack containers. That next time we sit together, we'll be building the work
hard game user interface.
6. 05: Build the War Card Game UI: Hello and welcome. In this lesson,
we'll be building the war card game
user interface. Actually, I'm going to
get you to build it yourself first because
I think you can do it. Come on. I'll get you started. You give it an
honest try and then we'll go through the
solution together. Deal. Come on, you got
this, Let's do it. Alright, so we're gonna
start with an Xcode project, launch Xcode, and let's create
a brand new Xcode project. We're going to choose
app under iOS. And you can name this
anything you want. But I am going to call
this war challenge because that's what it is and it's a challenge that I'm
confident you can do. Interfaces Swift UI lifecycle is swift UI app and
language is swift. Leave the rest unchecked, and let's save it somewhere. So I'm going to just
save it on my desktop. All right, here's our
brand new Xcode project. Let's go to the asset library first because we're going to add all of the image assets
that we need for this app. If you go into the Course
Resources folder under this lesson specifically
you're going to find a zip file with all
of the image assets. So go ahead and unzip that. And then let's drag all of these assets
into the asset library. Now you should have
the card back, the background for
the entire app. And then you should have
cards two to 14 and no, you're not missing
cart number one. The ace is carbon-14. And the reason I
numbered them this way is because
we're going to use this number at the end of the card names here to
represent the value. And we're going to
compare this value to see which card trumps the other. And then we're going to
have a deal button image and a logo image. Now just in case I didn't
mention it before, we have three different
sizes for each image because there are different
screen resolutions for iOS devices. So all of the newer devices have super retina display and so they're
using the a3x ones and I don't think they
actually make devices that use the one
image asset anymore. But this app was from a long time ago and we've rebuilt
at many different times, so we still have all three. Now let me show you the
finished user interface. And this is the end result that you're going to try
to achieve yourself. This is what it looks like. Don't pay too much
attention to the spacing as long as you've got everything generally in the right place. I think that's great. Another thing to mention is that this is supposed
to be a button, but since we haven't gone
through buttons yet, feel free to use an
image element for that. And that will be
perfect for when we do transition
to using buttons. And I can show you how to change that image element to a button. One other thing I have
to mention to you is the concept of the safe area. Now, the safe area
is this region that starts about right
here under them notch, and it ends right here above
This little handlebar. And in some cases, there are actually margins on the left and
right side as well. And anything within this
region is in the safe area. Now this area is guaranteed
not to be obstructed. Anything outside
of the safe area. So anything in this corner
or this corner could be obstructed as you can see
by icons or by the time. And obviously there's
this handlebar here that could be
blocking things as well. If you want a full
screen background, like this green background
that we have here, you're going to have to ignore the safe area
because by default, when you add elements
onto the view, it will try to stay
within the safe area. So there is a modifier that
I haven't shown you yet. It's called ignore
safe area that you can apply to an image
that will allow it to stretch beyond the safe area so that it reaches the edges. And that's probably
the only other piece of missing information you need. Other than that, you've
learned about stacks, you've learned about
image and text elements, everything you could need to
build this user interface. So go ahead, pause this video
and give it a try yourself. And then afterwards,
we will come back together and I will walk you
through how to build this. So welcome back. How did you do were you able to build this user interface? Congratulations,
if you're able to build this or something
that resembles this. And if you got stuck
or you weren't able to don't worry because we're
going to go through it now. And oftentimes I find
that if you try it yourself and gets stuck and then later on find the solution. Those are oftentimes the
best learning experiences. All right, let's go
through this together now. Now before we dive in and start building this
user interface, I want to take a
moment to sort of break down what elements
that I can see here. So first of all,
I can see that we will need a zed stack because. We have an image behind
all of these elements. And so as that stack is
going to allow us to position elements on
top of each other. Next, we have a V
stack where elements are stacked on top of
each other vertically. So you can see a V stack running through this entire user
interface top to bottom. Now some of the elements
in this V stack will actually be contained
within an H stack, like these two cards
side-by-side, for instance. And this element
down here is going to be an H stack of TUV stacks. So this is a V stack containing
the two texts elements. This is a V stack
containing the two elements and then you encapsulate
them in an H stack. So that's the
breakdown that I see. And now we're going to jump into our content view dot swift,
and we'll build it out. All right, So here
I'm looking at the content Vue.js Swift. The first thing I'm
going to do is to change this simulator
to iPhone 11. And let's hit Resume. And in a few seconds, time might be longer, will see a preview here. Perfect. Now let's change this
default text element. Get rid of that. Let's put a z stack there, open up a pair of
curly brackets. Now, what's sitting behind all of those elements is an image. And the image that we have
is called background. Notice that it doesn't reach
all the way to the top. Now it does overlap
that safe area a bit. I said the safe area was
under the notch right here. So you do see that it overflows, but it doesn't quite really
go all the way there. So we can add a modifier
called ignores safe area. When you do that,
it's just going to cover everything. So okay. So what's going to be on
top of this background? Well, like I said before, we're going to have
a vertical stack containing all of
those elements. The first one being the logo. And then we're going to
have an H stack with two cards and then an image element representing
the deal button. And then after that we're
going to have the score vertical stacks in
a horizontal stack. So let me, let me type this out so it
makes a little more sense. Let's start with the
logo at the top. We're going to have an image and our image asset
name is logo. So you can see it just just appears at
the right size there. And that's because our
image asset is that size. Okay, now let's put
an H stack in here. And inside here
we're going to put two more image elements. We're going to put the, let's put card too. And then card three. So we have two cards
in an H stack. And then after that, we're going to put
another image element. And this is going to
be the deal button. And now comes the score labels. So it's going to be an H stack. But inside of the stack
we actually have two V's. Thanks. Each VSAT contains
two text elements. So we're going to have Player and we're going to
have the actual score. And then for this one, we're going to have CPU. And we're going to have
the actual score, the CPU. So we basically have all
of our elements laid out. Now, let's add some
spacing to them. So to do that, we
can use spacers. So let's start by adding
a spacer right above, right above the H stack of the two cards below
the logo image. So I'm going to put a
spacer element right there. And what you learned about
spacer elements, right? It takes up all of
the available space. However, if you have multiple spacer elements
in the same container, it's going to evenly divide that space
between the two spacers. So I'm going to put another
spacer right below the cards. So now you can see
that there are two equal amount of spaces. I'm going to put
another spacer below the deal button
or image for now. And then I'm going to put a spacer below the score labels. So you gotta make sure that you don't put it in the
wrong place here. We want to put it
below this H stack. And if you click
this ending bracket, you can see that Xcode
briefly lights up the beginning brackets
so you can verify that that's where you want it. Alright, and the last
thing to do is put a spacer element
above thought logo. So that's right here. Now from a vertical
point of view, it's all spaced out nicely. For this H stack
with the two cards. Why don't we put some
spaces in there? So let's start by putting a spacer in-between
the two cards. And then the space her before all the cards and the
spacer after the cards. We're going to do the same thing with the text labels down here. In this H stack. We're going to put a spacer
in-between the two V's tax. And then we're going to
put a spacer before IT. And the space or after it. All right, and now the last
thing to do is just to change the font colors of
these text elements. And also to change their
font weights and font sizes. And maybe add a little
bit of space in between the score and the label. Okay, So let's click on this text element and take
a look at what we could do. So if you look in the
inspector panel for the font, you can choose one of these
predefined font sizes. For this one, let's
choose headline. And you can see it. It gets a little bolder there. Let's change this to white. We're gonna do the same
thing for the CPU label. We're going to change
it to headline. We're going to change
the color to white. Then for the actual score, we're going to change the font to, let's say sub-headline. And we're going to change
the color to white as well. And for that score label, we're going to change
it to sub-headline, and we're going to change
it to white as well. All right, and if we wanted
to make it actually, I think in the original
user interface I had it as large title. So I'm going to
change it to that. So I'm going to
change the 0 from sub-headline to large title. Now in order to add
some padding in between the label
and the score here. What you can do is
choose the label. Let's start with
the player here. And let's click on just
this bottom padding. So enable that. And then you can change that
number to, let's say 20. You can see that increase. And that looks like a
little bit too much. So maybe we'll stick with 10. We'll do the same
thing with CPU here, and click just the bottom
padding, and then we'll add 10. You can see the
corresponding code here. It's adding padding,
but it's specifying only for the bottom
edge and at 10 points. And this is a good practice
anytime you modify something, visually, adding a modifier or changing something in
the inspector panel here, It's a good practice
to take a look at what has changed on the code side, just so you can remember over
time, the more you see it, the more you remember that, hey, if I wanted to change it
to a headline style font, I would just have to
add a dot font modifier and pass in a headline option. Same thing for the foreground color for this text element, dot foreground color,
color dot white. You don't need to
try to memorize it, but just pay attention to it. And over time, you're
just going to remember. And typing it out will end up being faster than
having to visually click around and
configure things through the inspector panel or
the preview canvas. Alright, last thing
to do, make sure you save the project
and you're done. So in this lesson, you
built the war card game UI, but in order to respond to user interaction and to programmatically change
the card images, we're going to have to learn
some swift programming. So in the next four lessons, you're going to be introduced to coding basics with Swift. Now if this is your first
time learning how to code, take it slowly and don't try to memorize any
of the keywords. And then after that, we're going to come back to this war card game
user interface and bring it to life with code. All right, I'll see you there.
7. 06: Variables Constants and Data Types: Hello and welcome. In this lesson and
in the next three, you're going to be
learning the basics of the Swift programming language. Now these are the skills that you're going to have to have in order to complete
the war card game, as well as the build the feature app that we're
going to do together. Now if you've never
coded before, I know this might seem a
little bit intimidating, but I really want
you to stick with this and really pay
close attention. In fact, open up Xcode on your own machine and type out exactly what I'm showing you. This is really going
to help reinforce the structure of the language
and all of the keywords. There's no need to
memorize anything at all. I guarantee that by the
end of this module, you'll be writing
your own Swift code. All right, let's dive in. I want to start by looking at the View Update lifecycle
of a simple app and show you where
Swift code plays a part in each part
of the lifecycle. Let's start with
what you've already learned in the previous lessons that the UI is generated
from Swift code. We'll call this your view code. It generates a UI for
your user to see. Now typically with an app, we have some sort of data that we want to retrieve and display. For example, a news app. We'd want to get that data from a data source and then retrieve it into our app and
display it in our UI. You can use Swift code for this. The swift code can go and
fetch the data and then process it into a format
that our app can understand. Then using Swift code, we can also link this
data to our view code so that when the UI is
rendered from that view code, that data can be
displayed to the user. And furthermore, when the
user interacts with the UI, such as tapping a button, we can use Swift code to capture that event and respond to it. Now based on what
the user tapped on, we might use some Swift
code to change our data. When this data change
happens because we've linked that data
to our view code. That data changes automatically detected and the new UI is re-rendered with
the updated data so that the user can see
what has changed. Now this cycle is essentially all the app is doing
over and over. And we'll explore this App, View, Update lifecycle in more
detail in future lessons. But for now, I just want you to understand that Swift code has a part to play in each
part of this lifecycle. From the last few lessons, you've already seen the
code for building UI. So you sort of know what
that view code looks like. Let's shift our focus over
to the data part where we can see what Swift code is used for keeping
track of the data. Furthermore, what does that
even look like in our app? In order to try out
some of the swift code and to find the answer
to our question, let's use an Xcode playground. A playground is a
lightweight way to test some of our code without committing to a
full-fledged app project that we can do here. Think of it in Xcode playground
like your doodle pad, but for code, now
just start a new one. Go to File, click on New, and then let's click
on playground. We're going to choose
a blank playground. And let's give it a name. And let's save it somewhere. We're going to close
this navigator tab by clicking this button
because we don't need that. Now, down here in the
lower left-hand corner, you'll notice that we have a button called
showed the bug area. Go ahead and click that
to reveal this tray. This debugger console area is where we're going to
output a lot of data. So just turn that on, make sure you see this
little area down here. And then this button, I want you to click it
right now it's going to be executing the playground. It's going to run
all of the lines of code in the editor area up here. Notice, however,
that you also have this little blue Run button
along the line numbers. And this lets you select which line you want to
execute the code up to. So if I hover over at line three and I hit
the button right here, it's going to run lines 123 as opposed to this button here,
which runs everything. So the first time you
run this playground, it might take awhile. You show the spinner for
up to even a minute. I want you to do
that and just let it run until it says
ready to continue. And that's going to set us up to run some code in the next part. For now, let's just
go ahead and delete these lines of code so
we can start fresh. Alright, now that your setup, Let's go back to our
original question. What does data look
like and how do we use Swift code to
keep track of it? Let's look at a couple of
different types of data. First, let's start with a common datatype,
a piece of text. In Swift, you surround texts with quotation marks like this. And this is known as a
piece of string data. Let's add a note
for ourselves up here with two forward slashes. When you do that, it's
called a comment, and it's a way for us to leave a note or a little piece
of documentation for us to remind ourselves or other people who might
be looking at our code, what that code does. And when Xcode sees these
two forward slashes, it's not going to
execute this line. Now let's take a look at
another datatype, integers. So something that
looks like this. In Swift, this is known as
int, short for integer. And what about decimal numbers? Well, yes, that's
also a datatype that Swift can recognize
and handle. Each of these. They're known as a double. And swift can also
handle Boolean values. So things like true and false. In Swift, this is known as bool. Now string, int,
double and bool. These are all called
datatypes and it's how Swift classifies data. Now these aren't
all the data types that are available,
but these are the, by far the most common
ones that you'll be using, at least in the beginning. And it's a great
starting point for us. All right, now let's
take a look at creating and keeping
track of data. In Swift, there are many
ways to keep track of data, but two of them
are basic ways are using variables and constants. Let's go back to our
Xcode playground and take a look at an example. Let's start with our
hello string data here. Now this piece of data on its
own is going to be useless to us unless we have a way
to reference and track it. And we could do this
with a variable. So let's see how we can declare a variable to keep track of
this hello piece of data. So we use the var
keyword and that's for declaring a new variable. And then we type the
name of the variable. This name is what
we're going to use to reference that piece
of data and recall it. So I'm going to call this myVar, and then we follow
it with a colon. And then after that we put the datatype that this
variable is going to track. Since the data that we want to reference is a
piece of string data, I'm going to put string here. And then next, we usually in the same line that
we declare the variable, we assign the data to the
variable to keep track of. And we can do that using
the assignment operator, which is just an equals symbol. And then on the right
hand side of that, we put the data that we want
to assign to this variable. I'm going to take that
and move that right here. So essentially what this
line of code is saying, we're declaring a new
variable called myVar. We are saying that it keeps
track of string type data. And then we are assigning this hello string data
to that variable. It's kind of like
we're attaching a label to this piece
of data called myVar. Now whenever I want to
reference that piece of data, all I need to do is reference
it by the variable name. So let's give this a try. We can use a special
command that will output the data to the console area below
here in the playground. And that command is just print followed by two
rounded brackets. And in-between those brackets
you put the variable or whatever data
that you want to output. So I'm going to do that. And then down here
I'm going to stop my playground and execute
all the code in it again. And then as you can see down
there and it says hello, that the contents of myVar, which is exactly what
we would expect. Notice that when I
reference my variable, I don't need to use the
var keyword anymore. That was only to
declare the variable. And once I've
declared my variable, I can just reference
it by its name end. I can also reassign
new data to it. I can use it over
and over again. I don't have to redeclare it. So for example, after I declare it an
assigned hello to it, I can turn around and assign
something else to it. Let's assign this piece of string data called
world to myVar. And essentially what
we've done here is we've told that variable instead
to track this piece of data. So what would you expect if I execute the code in
the playground now? We would only output
world because myVar no longer is tracking
that hello piece of data. Now one thing I
want to emphasize is the data type
of the variable. If I specify that myVar
is a string type, I can only track
pieces of string data. So for example, if I
had an integer like 100 and I tried to
assign that to myVar, well, I will get an error
that's not allowed. What I need to do instead
is declare a new variable of the int type to keep track
of this piece of int data. So let's go ahead and use
the var keyword and name it. And then colon and then the datatype that
I want this to track. And now that is completely okay. Let's try printing that out. Xcode is not going to help you auto correct any
spelling errors. All right, So we
have world and 100. Now as we're coding
more together, you'll start to notice different sorts of
naming conventions like what you see here where my variable names start
with a lowercase letter, and then every
subsequent word in my variable name starts
with a capital letter. So that's sort of just a
standard naming convention. You really could do
anything you want. But when you start coding
more and working in teams, it's important to have. Standard that everybody uses, and this is a common one. All right, Now one
more thing I want to talk about before we move on to the next topic is the fact that there are
shorthands in Xcode. You don't really have to
type in all the information. For example, here, we're
declaring that this variable, my int, is an int type and we're assigning
integer data to it. But the thing is, we could actually
omit that datatype and simply assign 102 it. When we do that, Xcode can see that this is a
piece of int data. So it's going to assume that my int is going to
only track in types. Now that same rule
still applies. I mean, after Xcode infers that this variable is n-type because you've
assigned 100 to it. I cannot go and assign
a string to it. That's not going to be
allowed because Xcode is, has already detected that
this should be an n-type. So same thing goes for up here. I don't need to
specify the data type. If I'm going to assign a piece of string
data to it right away because that tells
Xcode that this is going to be a
string type variable. So that's just a
little shorthand to save you some typing. Alright, so you learned how
to declare a new variable, assign data to it, and recall that data by
using the variable name. And you also learned
how to assign new data to that variable. Let's talk about the other
way to keep track of data. Constants. So constants are just like variables except
that you can't reassign data to it once you've assigned the first
piece of data to it. So sigillata, how to declare a constant to keep track
of this string data. Instead of the var keyword, you use the let keyword. And then the rest is just
the same as a variable. So we start with
a constant name, my colon, and then you guessed that the datatype followed
by the assignment operator. And then we're going to
move that piece of data to the right-hand side of that assignment
operator like that. Now let's try referencing
this constant. Let's try printing out
the data in my context. As you can see, it
works as expected. Now, let's try to do the
thing that's not allowed. Let's try to assign
something else to it. And as expected, we cannot reassign data to it
because it is a constant. Now constants are useful. It's an additional tool
that we can use if we don't expect that piece
of data to change. And so we don't need to make
any changes to it ever. So when would you use a
constant over a variable? Well, it really depends
what you're trying to do. You'll probably find yourself
using variables most of the time because of their versatility and
because data changes, however, the best
practice is to prefer constants over variables
where it makes sense. In fact, Xcode is smart
enough to know if you use a variable and you never end up changing
that variable, it will suggest that you
change that var keyword to a let keyword and
use a constant instead. All right, let's
do a quick recap before we wrap up the lesson, you learned about the
View Update lifecycle and how Swift code
plays a part in it. You learned about data
types such as string, int, bool, and double. You learned about how
to use variables and constants to reference data. You're making great
progress so far. And in the next lesson, I'll teach you how to organize your code statements
into functions. All right, I'll see you there.
8. 07: Swift Programming Functions: Hello and welcome. In the previous lesson, you learned about Swift
variables and constants. You'll learn how to create
some data and declare a variable or constant
to keep track of it. While in this lesson
you're going to learn how to organizing, group together your
code statements. So that number one, all of the code statements
that you've grouped together can work
together for a common task. And number two, once your code
is organized into groups, you can choose which
group of coats things to run depending on what
task you need to be done. These groups have
code statements are known as functions in Swift. All right, now let's
take a look at the view update
lifecycle diagram from the previous lesson
and seeing where functions might play a
part in this lifecycle. Remember that when the user
interacts with the UI, Swift code captures that
event and reacts to it. Well here we might have a
couple of different functions depending on how the user
interacts with our UI. For example, the user
tapping a button might trigger the app
to switch screens. In that case, maybe we'll run function a to perform that task. Or on the other hand, what if the user taps on an
item to see more detail? Then in that case, we'll run function B to bring up
the details screen. Now let's go over the code that performs the
data retrieval. For example, we might have a function C that does the
actual retrieval of the data, maybe the networking code. And it grabs the
data and then gives it to function D as input. And the responsibility of this function might
be to process that data and turn it into a format that our
app can understand. So function D takes that data as input and outputs the
formatted data for our app. Now I could go on,
but as you can see, functions are a basic component
of swift programming. It's everywhere. So now let's go and see how we can create our own functions. All right, so here I have a brand new Xcode
playground and we're going to take a look at
the function syntax. And just in case I haven't
explained that yet, the word syntax is simply a word describing the structure or
the grammar of the language. So, function syntax to
declare a new function, you start with the
func keyword FUN, see. It's a funky function. And then you follow it by
the name of the function. And then a set of parentheses
are rounded brackets, and then a set of
curly brackets. Inside the set of
curly brackets, you put your code statements, anything you want to execute or run whenever we
call this function. So let me just put
some statements here. Let's say declare two
constants like this, and then let's print a plus b. So if I run this right now and execute all of
these lines of code, nothing is going to happen. You don't see any output. And that's because we haven't actually called this function. In order to call and to
execute this function, we just have to reference
it by the function name. So that's my FUN, C, followed by the
pair parentheses, and that is how you execute all of the code in between here. So let's try this out. I'm going to stop executing and then run my
playground again. And we get 30 as we expect. If I wanted to run those
set of instructions again, then I can just
simply call it again. And if I print it out, now executes that code twice. Now I want to go back
to that view update lifecycle diagram
for just a second. Because if you notice back
in that data retrieval area, I said that we might
have two functions, c and functions dy, where C would fetch
the data and pass it into D as input parameters. So that function D can work with that data and
formatted how we need. So a function being
able to accept data into it to work with it is
a very powerful feature. Let's take a look at how we
would declare a function that would accept some
sort of input data. Alright, so I'm going to
erase these two lines and I'm going to modify
my function here. Instead of declaring
two constants, a and b, I am going to specify that a and b have to be
passed into the function. So the way we do that
is through the use of function parameters in-between
the two rounded brackets. That is where we
would specify all of the parameters we want to be
passed into this function. You can pass in
multiple parameters, but actually let's
just start with one and let's just start with a. So first I would put the
name of the perimeter, so I would want
that to be eight. And then I would
put colon specified by the datatype that
this parameter is. Since I expect it to be into, I'm going to declare
this parameter as a followed by
the datatype int. And then I can erase
this constant from here. As you can see,
this is almost like a variable declaration or a constant declaration except without the var and
without the left. Here we're specifying that whenever this
function is called, one int parameter needs to
be passed in along with it. And it's going to
be referenced by this parameter name a
inside this function. So now you can see
that nowhere did I declare a variable
a or constant a, but I can still put a as part of my equation a plus B because a is being passed
in as a parameter. So let's take a look at what calling this function
would look like. Now, I'm going to rely
on auto-complete. So I'm gonna type in MY FUN and you can see as
soon as I do that, it detects my function here. So I'm gonna go ahead
and click that. And you can see that now, in the process of
calling this function, I also have to pass in an
integer piece of data. So I'm gonna go ahead
and pass in this, passing something different
in the past and five, you can see here,
there indicates this is the parameter
that I'm passing in. Let's go ahead and stop and execute and run my
lines of code again. And this time the output is 25, because 5 was being
passed into the function. Plus 20 is 25. Now going back to the View Update lifecycle diagram again, function D accepts
input as a parameter, but it also returns output. So that is another very
powerful feature of functions. Being able to take
in some input, work with that data and provide some output back to the
color of the function. Let's take a look at our
playground and see how we can specify that a function
should return some data. So to modify this function to indicate that it will
return some data. We go up here right after the rounded bracket
for the perimeter, and just before the start
of the curly brackets. In here, we write a dash followed by a
greater than symbol, which makes sort of like
an arrow like output. And then we specify the
data type of the output. So what I'm going to do
is I'm going to output the sum of a and B instead of printing it out
to the console. So I'm going to erase this line. And then I'm going
to output an int. So that's where I specify that after that dash
greater than symbol. Now you can see that Xcode
throws some errors now because in addition to specifying that your function
returns an int, you actually have to return an int inside of the
code statements. So as the last line of our code, we can use the return keyword, meaning that this
is the data we're going to return
from the function. And then we specify the data
that we want to return. So I'm going to return a plus b. And all is, well, now keep in mind that
whatever the data type you specify up here in the
function declaration, that is the datatype
that you have to return if there's a mismatch. For example, if I specified that this function
returns an int, but I go ahead and
return a string. Like a piece of text. You're going to see Xcode. Complain about that
as well because that is, that is incorrect. So we're going to return a plus b and we're
going to return an int. So why don't we run our function now and
see what happens. Nothing happens. Well,
what's going on? I'm returning a plus b. So here's what's happening. Calling this function
is returning that data, but I need to somehow reference and track
that data, right? And that's what a
variable is for. So I am going to declare
a variable up here, var. Let's declare constant actually, since I'm not going
to change this, let my sum equals the
result of that function. So you can understand
this code statement rate, we're declaring a
constant called my sum. And then we are calling this function
on the same line that returns 25 and we're
assigning 25 to my sum. So now I can print my sum. And let's double-check
that we get the output. There we go. Now
before we move on, there are two very
important things that I want to mention. So this returns statement actually ends the execution
of that function. So once this return
statement is run, execution returns out
of that function. So any code statements
that you put down here, let's say I had returned
a b right there, and I printed a
plus b right here. That print statement
is not going to be run C code after return
will never be executed. So that's just important
to keep in mind that when you write return and it executes
that line of code, the execution stops and
gets out of that function. Another thing that I wanted to mention is this return type. So earlier when I told you that declaring a function didn't have a return
type like that. Well, it actually did. It was just that the
return type was void. And void means nothing. So let me, let me do a basic demonstration
actually let me just declare another
function down here. I'll just call this a
microphone to see back then I told you this was a basic declaration
of a function, but Actually that was a shorthand. The full declaration
actually has a return type of void like that if you're not
going to return anything. But it's just that when
you don't return anything, then you don't actually have to specify the return type of void. So, so I just thought
I'd mentioned that. So you know what that
void keyword means. So if you see some function that has a return type of void, you know that that
basically means that it's not
returning anything. All right, So now let's
reset a little bit. It's starting to
get a little messy. So let's erase
everything except that, except our function right here. Now I want to show
you how we can pass in multiple parameters. So instead of
specifying be here, Let's put B into the parameter listing here and have it
be passed in instead. Okay, so let me
erase this line of code so that we
get B from appear. Well, how do we add another
parameter to this one? What you do is
simply put comma and then declare another parameter for your function. Easy, right? We're going to name this
one be followed by colon, and then the datatype of B, that's going to be
another integer. All right, so now let's
take a look at how we call this function
with two parameters. My func, you can see that here. No, you just specify, oh, one quick thing is when
you're calling functions, an easy way to just fill in the parameters in the
list is by pressing tab. That just brings you over to the next parameter
that you have to fill. So I'll put 2 and 3. Let's execute all of this code and we get a result.
We get no result. Remember I erased
my line of code. So why don't we just print out the result instead of assigning it to a
variable this time. So I'm going to go
ahead and directly pass that function call
into my print statement. That's going to print out
the output of my function. Let's go ahead and run
that code and we get 5. Now, obviously you can have
more than two parameters. Just put a comma in between each parameter in your function. And then another
thing I wanted to mention that's pretty
cool with parameters, is that you can specify a
default value for a parameter. So for example, for parameter b, I could make this an
optional input data by specifying a default
value for this parameter. If I do that, that means that when this
function is called, passing in data for parameter
b is going to be optional. Let's take a look
at how this works. So after I specify the data
type for my b parameter, I can put an equal sign and
then I can give it a value. Let's say 0 is the
default value. If b is not passed in, then B is just going to be 0. Now, let's erase
my function call, and let's try
calling it again and take a look at what the
autocomplete menu shows us. Here you can see that there are two different forms of
my function call now, one is with parameters a and b. So I pass in both
pieces of data. And one is just simply
passing in a parameter a. If I do that, v is
just going to be 0. But if I pass in both of them, Let's say I pass in 23 again, then B is going to be
three instead of 0. So that's one way to make
your perimeters optional. Now I want to talk
about argument labels. As you can imagine, the
more parameters we have, the more confusing
things are going to be in terms of these
function calls, especially when it comes to
parameter names like a and B. Well, sometimes a
and B makes sense in the context of the code
inside of the function. But to the color of
the function, a and B. They don't mean anything. So there's a special feature
called argument labels. And let me show you
what that looks like. So I'm going to declare a
new function right here. I'm going to call
it my func as well. And I am going to
actually, you know what? I'm going to just copy this function and make a
copy of it and show you how, how argument labels change it. So an argument labeled goes
in front of each parameter. So each parameter can have
its own argument label, and you're essentially just putting a name in front
of that parameter. I'm going to call
this first parameter. I'm going to give it
a, an argument label called first number. And for my, for the
second parameter, I'm going to give it an argument labeled called second number. So that's literally all it is. An argument label
is a name in front of the parameter name
separated by a space. Let's take a look at how this
affects the function call. If I type in my func, you can see here I still
have these first two ones, a and B, and that's from
the first function up here. But look down here, I have first number and first
number and second number. And this corresponds to my
second function right here, because second number is
still optional, right? Because I have this
default value there. So if I call that one. My function call becomes this myfunc first number
1, second number 3. However, internally
inside of that function, I'm still referencing those
parameters using a and b. So argument labels there. A way for you to
distinguish the naming for a function call versus how it's referenced
inside the code. Whereas if you omit
the argument labels, like we've done up here, then the parameter
names are used for both the function call and also the referencing of those parameters inside
of the function. So hopefully you notice
the difference here. One cool trick you can do with
argument labels is if you don't want to show any text
in your function call at all, you can use an underscore
as your argument label. So if you do this, Let's see what happens
to your function call. So my func, you can see here these two correspond to
what I've done right here, using underscores for
the argument labels. So if you use an underscore
for argument label, the function calls
just become myfunc. And then the first
piece of data, comma, second piece of data. There's no parameter names, there's no argument labels in
your function call at all. So this makes things really succinct and really
neat and tidy, but it also makes
things more confusing if it's not clear what those parameters are
supposed to be four. So there's a lot of
versatility here. My personal preference is
simply to do it this first way. And I don't usually specify
any argument labels at all. And I simply use the
perimeter names. Okay, last thing I promised
before we end off with functions is I don't
know if you've noticed, but we've declared two
different functions here, both with the same
function name. We can't do that with
variables, right? If you try to declare variable a and then variable a again, then you're going to get an
error on the second one. And Xcode is going to complain, you cannot redeclare variable 8. For functions. Things are a little
bit different. Functions have what's called
a function signature. And that is comprised
of the function name, the parameter listing, and then followed
by the return type. So let's type myfunc and take a look at what the
autocomplete menu gives us. As you can see, all four of these variations have the same function
name called myfunc. But because the
parameter values, argument labels,
they're different, Xcode is able to discern and to know which function we're
trying to call, right? So if I call this
one and I don't specify any parameter names
or any argument labels. It knows that I'm trying to call this second one right here because this method call,
this function call. I mean, it doesn't
match this first one. Whereas if I do my func and I specify parameter
labels a and b, then it definitely knows
that I'm trying to call the first one because this call, this parameter listing
here matches up here. Okay, so I promised you that we went a little deeper than you probably need to know right
now by showing you all of these options and ways that functions can be flexible
as we code together more, you'll see me just using more
basic forms of functions, but at least pay now
you know a lot more and I'm sure you can appreciate how powerful
these functions are. Alright, this lesson was
pretty action-packed. Let's do a recap before
we wrap up the lesson. First of all, you learned how to declare a basic functions, and then you'll learn
how to declare functions which accept input
data as parameters. Furthermore, you'll
learn how to declare a function with
multiple parameters. And again, functions
when nearly be as useful if it couldn't
output data, right? You'll learn how
to do that using return types and
the return keyword. You also learned about
argument labels. And finally, you learned
about function signatures. You're making great progress. And in the next lesson,
I'll show you how to organize your functions
in two structures. So I'll see you there.
9. 08: Swift Programming Structures: Hello and welcome. So far you've learned
about variables and constants and how they're
used to keep track of data. You've also learned
about functions for organizing and grouping together
you've code statements. While in this lesson,
you're going to learn about structures or
structures for short. And these are the basic
building blocks to represent your data or to represent something in your app. Structures bring
together the functions that variables and constants, everything you've learned so
far in the last few lessons, all into a neat little package. All right, let's dive in and
see what it's all about. Now let's do a quick recap. First, you had coats,
things like these. And then I showed you how to use functions to organize
and group them together. Now with structures, you can group together
your functions. You can also have
variables and constants, keep track of data
inside your structure, but outside of any function. And we're going to
talk about these a little later in this lesson. Now let's take a look at our view update
lifecycle diagram again. For the view code that
represents her UI, you might create a structure to represent your home screen and all of the view code for your home screen would
go into that structure. If you had a second
screen in your app, you might create
another structure for that second screen. And all of the view code for that second spring would
go into that structure. In this case, each structure represents a different
screen in your app. Now let's move over to the data retrieval
part of this diagram. You might create a structure
and call it a data manager. And you're gonna put
all of the code and functions related to retrieving and processing the data inside of that data
manager structure. In this case, the
structure doesn't represent a screening your app, instead it represents a
crucial component of your app. So as you can see,
structures are very flexible and lightweight and they're used all over your app. Now let's go into an
Xcode playground and take a look at how we can
declare our own structure. All right, so here I've got a
brand new empty playground. Let's take a look at how we can define our own structures. First, you start with
the struct keyword, followed by a space, and then the name
of your structure. So I'm going to call
this one my struct. And then you put a
space and you open up a set of curly brackets. Inside the curly brackets, you would put all of the code in your structure,
and that's it. We've declared our
own structure. Now before we move
on and take a look at what's inside the structure, I want to point out
the naming convention of the structure. Notice that I started it
off with a capital letter. This is the standard convention. This is different from the
camel casing that we used for the variables and constants
and the function names. Those started with
a lowercase letter, and it had each subsequent word starting with a capital letter. Whereas for structures,
it starts off with a capital letter and then each subsequent word
has a capital letter. All right, now that you know
about naming structures, let's go inside and
take a look at how we organize the things
inside of the structure. So usually at the top
of the structure, inside the curly brackets, we would declare here
all of our variables and constants used to track data that is related
to the structure. Now, these have a special name, as I mentioned earlier, and we will get to that
later on in this lesson. So up here after you declare
all of the variables and constants tracking
data for this structure, the next section
you have are all of the functions related
to the structure. Now, there are no clearly defined a sections
in a structure. You know, all of the
code really just goes in between the
curly brackets. But usually this is how
you would organize all of the different pieces of code
inside of your structure. So at the top, variables
and constants, and then at the bottom, all of the functions. So as you can see,
structures are great for grouping
together functions, variables and constants
are related for one thing. But structures are usually
meant to represent something in your app in the View Update lifecycle
diagram that you saw earlier, we saw examples of a structure being used to
represent a screen of your app, as well as to represent a crucial component of your app like that
Network Manager. So why don't we do
another example, and I'll show you a structure that is a little
bit more concrete. Let's model it after something. So earlier in the View
Update lifecycle diagram, you saw that we could
use structures to represent a view in our app. So let's go with that. Let's have a
hypothetical chat app. And let's say that
this structure represents my chat view. So I'm going to change the name of my
structure to chat view. Now, under variables
and constants, I might have a variable to
keep track of the message, like the chat message that
I'm typing into the chat box. So I'm going to
call this message. And the type of
data this would be, would probably be a string. And I'm going to assign
it an empty string, nothing in between,
just two quotes. So that's what's known
as an empty string. Now under functions, I
could have groups of code that would perform
different tasks on the screen. For example, maybe when the user taps on the send chat button, it would execute some code to send the chat
message to the server. So I would declare a function. So that's funk, followed by, let's call this send chat
and two rounded parentheses. And I'm going to open up
a pair of curly brackets. And inside here, I would put the code to send a chat message. And then in between
the variables and constants and the functions, I would have the view code for this screen and as all
of the code for the UI. So now in this chat
view structure, we have a neat little package containing all of the
code for that one screen. Now, earlier I mentioned
that the variables and constants that you declare up at the top of the structure, they have a different name. So now I want to tell
you what that is. This variable declaration
that I have up here message. This is known as a property
of the chat view structure. If I had additional variable
or constant declarations, those would be known as
properties of the chat. Do you structure as
well? And down here, functions actually also
have a different name. A function inside
of a structure is known as a method
of that structure. So this send chat function is actually a method
of the chat view. So now let's just update
our comments here so that we use the proper terminology instead of variables
and constants up here. I'm going to rename this, well not renamed,
but just retype my comment and call
those properties. And instead of functions, these are going to be called methods, just so we're clear. Now, inside of a structure, properties and methods can
actually work together to fulfill the duties
of the chat view. Let's take a look at some of the special ways in which
they can work together. Now let's take a look at
this send a chat method. For instance, if
we were to write the code here to
send a chat message, it sure would be handy
if we could access the actual message in this
message property, right? Well, we actually can. So if I wrote
something like this, print and then inside
the parentheses, I put the name of the property. In fact, I can access that data. And the reason for
this is because this property is declared in
the scope of this structure. So the scope of the
structure is anything in-between these
two curly brackets, essentially the opening and closing curly brackets
of the structure. So any of the methods that I declare in here, for instance, if I declare another one, let's call this one delete chat. Because these two methods
are also in the same scope. You know, it's inside of
the scope of the chat view. I am able to access
the property. The properties that you
declare up here are assessable to everything
within the same scope. So that includes all of the methods that are
declared down here. Now I have to say that each method has its
own local scope. So this send chat method
has a scope inside here. And this delete chat method has its own scope in-between
these curly brackets. So if I declare a variable
inside my send chat method, Let's say var prefix
equals Chris, say's. And then let's say I
use this prefix and I prepended to my chat message. So the entire chat message would be Chris says,
and then something. So maybe I'll print prefix plus message to get that
sort of effect. And I wanted to do the same
thing inside delete chat. If I try to access the prefix
variable, type, print, prefix plus message down here inside the
delete chat method, you'll see that it,
Xcode complains. Nssa cannot find
prefix in the scope because this variable is not
declared in the same scope. It's declared inside
the scope of send chat. So how would we fix this? Well, one of the ways we
could do that is to turn this prefix variable into a property that we declared
at the top of our structure. You know, move it outside
of the scope of Sen chat and put it up here into the scope of the
chat view instead. So now that I'm declaring my prefix as a property
of the chat view, you can see that
the errors go away. And I can access this
prefix property inside. Both send a chat and
delete chat methods. Now I want to talk about
another type of property. First, let's define what
these properties up here are. These are called
stored properties. And the reason is
because when you access these properties and you reference them by
their proper name, it just returns to you
the value it's stored. There is another
type of property where when you access it, it needs to compute or calculate the value before
it returns it to you. So let's take a
look at what this second new type of
property looks like. So let me start by erasing this prefix property up
here and deleting that. And then I'm going to declare
this new type of property. It starts off just
like a normal one. Use VAR space and then the
name of the computed property. I'm going to call it
message with prefix, followed by the name. Instead of assigning
it some data, you open up a set
of curly brackets. And here you can put the
computational code to compute the value that you will return when this
property is called. One thing though, because the value is not
immediately known, Xcode can't infer
what the datatype is. So you actually have to
specify the data type after the computed
property name. So after message with prefix, I'm going to put colon and I'm going to put string
because that is the type of value that this
property is going to return. This is different from this
stored property up here message where I can actually use the shorthand and
erase the datatype. So it's just var
message equals string. And I can do this because I am immediately assigning a
value to that property. So xcode can look at
that value and it can determine and infer what the data type for that
property should be. With a computed property, I have to explicitly
specify the data type. Alright, so for my computed
property message with prefix, Let's take a look at the code inside of the curly brackets. Here, I am going to use
the return keyword, just like with functions, right? I'm gonna return. Chris says, so this is
a string plus message. So now in my send chat method, instead of printing
prefix plus message, I can just return
message with prefix. Same thing for delete chat. Instead of prefix plus message, I'm going to return
message with prefix. So every time this
property is accessed, it is going to run
the code inside these curly brackets
and return that as the value for that property and it needs to compute it. That's why it's called
a computed property. Now with computer properties, There's also a shortcut. If there's only one
line of code in here, then I don't need
the return keyword because Xcode can assume that this single line of
code will output the data that I want to return
for my computer property. So I can actually just
delete the return keyword. However, if I have
multiple lines of code, then I would definitely need that return keyword
because Xcode doesn't know which line of code is meant to be the value that gets returned. So for example, inside
my computer property, if I say let prefix equals, Chris says, and then down here I have prefix plus message. It's not going to know which code statement
returns the value. So I actually have to use the
return keyword like that. And that's going to be fine. Now as far as computed
properties go, there's definitely more
we can talk about, but this will suffice for now. In later chapters
in this course. We'll definitely go over
computed properties again. All right, let's
do a quick recap before we wrap up this lesson, you learned how to declare
a basic structure. You learned about properties and methods in the structure, you learned about scope, and you'll learn about
computed properties as well. Now I know that the hard part is wrapping your head
around these concepts. As we code further together, you're going to see these
concepts put into practice. I just want to say one
thing before we end. You did it. If you're brand new to coding these three lessons where
the mind-bending ones. In the next lesson, I'm
going to show you how these concepts relate to
your actual Xcode project. All right, I'll see you there.
10. 09: Swift Programming Instances: Hello and welcome. So you've learned that a lot of Swift in the last few lessons, you started with variables
and constants and data types. Then you learned
about functions. And then you learn
about structures that you can group
all of those things together to represent or
model something in your app. Now this lesson is going to be the final piece
of the puzzle. Not saying you're going to be
a swift master or anything. But by the end of this lesson, you'll see how all of the
concepts and code fits together and works together
inside of a swift UI app. All right, with that said,
let's dive right in. All right, so let's start
with an empty playground. Do you remember back then
when you learned about functions and I
taught you how to declare a function by
using the func keyword followed by the function name. Let's say my function
followed by a set of parenthesis and then a
set of curly brackets. And inside of the
curly brackets, we would have the code
for the function. But this is just a
function declaration that no code is run,
nothing happens. It's not until we call
the function that the code inside of that
function gets executed right? So I would call the function
saying my function, and then the parentheses. If I run my playground
right now you can see that it outputs Hello
into the console. So structures are
like that as well. When we declare a
structure using the struct keyword followed
by the structure name. So let's say my structure, followed by a set
of curly brackets. And then we put the code
inside of this structure. Let me move my function in here, and let's declare a
property up here, var message equals hello. And then let's print out my property message
inside of my function. This is just a declaration
of a structure. It doesn't actually do anything. Think of it like a
blueprint for a building. In order for us to
use this structure, we need to bring it to life. We need to create
what's called an instance of the structure. You can think of it like turning this blueprint for building
into an actual building. So how do we go about creating an instance of this structure? Well, that's easy. You just write the
structure name followed by a pair of
parentheses like that. Now just in case you're
still fuzzy about the concept of creating an
instance of a structure. Let me give you a couple of different analogies to help you try to understand
this concept. Some people find it
easier when I say that declaring a structure or the declaration
of this structure is kind of like a blueprint for a car or an architecture
plan for a house. Using that blueprint or using
that architecture plan, I can create cars and
I can create houses, and those are the
actual objects. Whereas the blueprint or the architecture plan is
more of like a template. It's simply describes how that thing is going to work
once you bring it to life. So that's what's
happening right here. This is a declaration
of a structure. It describes all of its
properties and functions. You know, the things
that it can do. And then it's only until
we bring it to life by creating an instance of it
that we can actually use it. So now that we have
created an instance of it, let's explore what
we can do with it. Now, first of all, we
need to keep track of this instance because it's
considered a piece of data, we need to keep track of it and have a way to reference it. So let's create a variable called I'm just going to call
it a for simplicity sake. And I'm going to assign that new instance
to my variable a. Hey, wait a minute. If this instance is
a piece of data, then what's the datatype
of this piece of data? And what data type is
this variable holding? Well, the datatype is the name of your
structure. That's right. So I can actually change my variable declaration
from var a, var a colon, my structure. Yes, your structure
is its own datatype. So this instance
that you've created, the data type of that
is my structure. Now this little instance has superpowers because we've
designed it that way. It can hold data in
its message property, and it can output that message using the
myfunction method. So how can we go about accessing those things
of this instance? Well, that's where dot
notation comes in. Let's take a look at
what dot notation is. So let's reference
the variable a, followed by a dot or a period. And as you can see from
the autocomplete menu, you can choose message which
is accessing the property, or you can select my function, which is going to execute
the code in that method. So using dot notation, you can access the properties and the methods
of that instance. Let's try this out. So first of all, I am going to assign something to the
property of this instance. I'm going to assign,
let's say hi. And then I'm going to print out. A.me, just to show you that I can indeed access this property
and I can print it out. Next. Instead of using
this print statement here, I'm simply going to call the
method of that instance. I'm going to call my function. And I'm going to run
this code again. And we still get high
because the code inside of this method actually just prints
out the property. Now this little instances quite
the action hero isn't it? It can do all of the things
that we designed it to do. Now because this
structure declaration is like a blueprint or
an architecture plan, that means that we can create as many instances it as we want. So let's go ahead and
create a second instance. This time I'm going to
declare another variable, var be to store another
instance of my structure. Now the important thing
to note is that these are completely
independent instances. Going back to the car
blueprint analogy, it's like the car factory made two cars from the
same blueprint. Those two cars are treated
as two different cars. Same thing here. I've just created two
instances of my structure. For example, if I assign
a message to be high, then I print out
bead on message, or let me assign something else to be.message and
I print that out. You'll see that for a dot
myfunction calling that method, it prints out high. And when I print out b.me, it outputs world to the console. So you can see that each
instance keeps track of its own values inside
the message property. Now you know that
you need to create an instance of a structure
in order to use it. Let's take a look at how instances of structures
can work together. Now to use an earlier example
from the previous lesson, suppose I have a
chat view in my app, so I've declared a structure
to represent this view. It groups together all
of the properties, the view code and the methods
related to my chat view. And suppose that I had another structure to
group together all of the networking code or the database code
to save the data. Let's declare something
like that here. So struct, Let's call
this the network, or let's call it the
database manager. Okay? And suppose that I
had a method in here. So func, let's call
this save data. And the input parameter for this is the data
that we want to save. So let's say I declare a single parameter called data
and make it a string type, and it returns a value, it's going to return
a Boolean value, true or false, indicating whether this was
successful or not. True for a successful,
false for unsuccessful. And in real life, it wouldn't be feasible to really return a result
instantly like this, because depending on network conditions
and other factors, you don't want to wait
around for the data to save. So you don't want
execution to stop. But for the sake of simplicity, let's just say that we can
return the result right away. So when you hear this, this code saves the data and
returns a Boolean result. So in this example, I'm just going to return true. So I'm just going to
turn a hard-coded value because I'm not going to
implement this method. The main thing I want to show
you is how the chat view is going to use the database
manager to save the message. So back in the chat view, in this send a chat method, for example, I could create an instance of the
database manager. So let's say var d b
equals database manager, followed by a set
of parentheses. And just like that, I've created a new instance of that
database manager. And now if I wanted
to save my message, I would call it's
saved data method. So db dot saved data and I would pass in my message property
as the input data. I'm going to go ahead
and pass a message. But remember, when I call
this saved data method, it returns boolean
value for me to indicate whether that saved
was successful or not. So I can assign the output of
that method to a constant. I'm going to call this
was success, right? So I'm going to assign
that Boolean output into a new constant
called was success. Or maybe I'll just
call it successful. And then down here, I can write some code. Check the successful
Boolean value. If unsuccessful. Show alert to user. Now in future lessons
you're going to learn how to write these statements
based on conditions. But for now, this
comment will have to do. The main takeaway. For this example that I'm
showing you is the fact that within the send a chat method
of the chat view structure, it is using another
structures methods by creating an instance of it. So that's how instances
of structures can work together to make
your app function. And this is essentially
all your app is. It's different
instances of structures working together to
produce the views, to handle the user input
and to run the logic. Now I want to talk about
access levels for a second. Suppose, for example,
in my database manager, I had some sort of information
that I was tracking as a property that only the
database manager needed. It wouldn't be relevant
to any other structure. Maybe it is a server name
or something like that. So let me just write a new property in my database
manager called server name. And I will assign to it a
string called server one. Now this property wouldn't be interesting to any
other structure, but as you can see in
the send chat method, I've declared this instance
of the database manager. If I write db dot
using dot notation, I can access that
server name property. And sometimes you might not
want to expose these things. So what you can do is you can specify an access level in
front of that property. So in front of var server
name, that property, I can put the keyword private, So now becomes private
var server name. And by doing this, it keeps that
property accessible only within the scope of
the database manager. So as you can see, I can still access server name inside of
the saved data method. Alright, it's in the same scope, but in the center chat method
of the chat view down here. If I use dot notation
again, for my instance, you can see that I cannot access that property
aim or can't see it. And furthermore,
you can actually do the same thing
with functions. So I can put private in
front of the func keyword. And now you can see
that Xcode complains. I cannot run this method from the sun chat method
of the chat view. Now it's a good
practice to be aware of which properties
and methods need to be accessible to
other instances and other structures and mark
everything else is private. Doing this is a proactive way to prevent unexpected behavior
and bugs from cropping up. All right, and now for the
final piece of the lesson, I want to relate everything
that you've learned so far back to a swift UI
app inside XCode. So let's go ahead and do that. All right, so now let's
go ahead and start a brand new iOS app project. I'm just going to name this
test project and make sure that interfaces Swift UI and lifecycle is swift UI
app languages Swift, and we're good to go. So I'm just going
to save this on the desktop and we're going to first jump into content
view dot swift. Now, I'm just going to change this to iPhone 12 and
I'm going to hit resume. But the important part is
the main thing I wanted to show you really
is the code, right? Take a look at this struct. You know that that means that content view
is a structure. There are some keywords and bits of code that we're
going to gloss over for now because we
haven't learned that yet and now is not the
right time to go over it. So I will gloss over
a couple of things by really want to point out that concepts that you have learned so far and show
you where they fit in. So this is a structure
declaration. Let me just collapse
this code for a second. There you go. So you can see that
this is a struct. The content view is the structure name
followed by colon view. And we're going to get to
this in just a second. And then you can see
the curly brackets containing all of the
code for that structure. All right, so let's
expand it again. And let's take a look at
what else we've gotten. Down here. We've got the var keyword. So that's the start
of a property. The name of this
property is body. Okay, So after that we've got colon and then we've
got some view. And we're gonna get to this
again in just a second. But you can see that there is a set of
curly brackets in here. So that tells you that this
is a computed property. So let me collapse
the code again. And you can see that
indeed this looks like a computed property
var body datatype, and then a set of curly brackets inside is the code
that gets computed or calculated to return the value when this property is accessed. So can you see all
of these concepts that we learned in the
last four lessons? Are they coming back? Now I want to talk about
this view and some view. So let's talk about this colon view in the declaration of
the structure first. Judging by how you've
used the colon before, you might think that this is the data type for the
structure, but not quite. That doesn't really
make sense, does it? Because remember, the name
of the structure itself is the datatype for
instances of that structure. So what is this colon view
after the structure name? Well, when you're
declaring a structure, the colon after
the structure name indicates that this structure
follows a protocol. In this case, it follows
the view protocol. So what do you think
about when you hear the word protocol? Well, for me, I think
about it as a set of rules or a set of actions. For example, kind of like the fire emergency protocol
that a building might have for what to do
when a fire occurs. Or like the building code that a developer has to follow to
build a house that is safe. Similarly in Swift,
a protocol is a specification or a set of rules that structure
has to follow. This colon view
part indicates that this content view follows
the view protocol. Informal Swift terminology. Content view conforms
to the view protocol. Now one important
thing to mention is that writing colon followed by the protocol is saying and declaring that you
conform to the protocol. But do you actually, it's kinda like raising your
hand in declaring something. But do you actually follow
the rules of that protocol? And so the code inside of this
structure actually has to satisfy the specifications
for that protocol. In this case, for the view
protocol to conform to it, we have to have a body property
that returns some view. As you can see here, our content view structure
does indeed satisfy that rule. So that's why it conforms
to the view protocol. So now that you understand
what protocols are, you can see that the datatype
for this body property is actually any value that
conforms to the view protocol. Yes, in this case, the datatype for this property
isn't actually datatype, but it's actually any datatype that conforms to a
certain protocol, in this case, the view protocol. So inside of this code for
this computed property, it needs to return some instance that conforms to
the view protocol. Let's open up this code
and see what we have. So what we have here, well, we have a single code statement. And remember what I said
about computed properties. If it's only a single
code statement, then you can omit
the return keyword, but I'm going to explicitly specify it so
that it's clear for you. So what's happening here? It looks like we are creating an instance of a text structure. Now one way to figure that
out is if you go into the utilities pane or the inspector pane
and you go into the quick help tab right here. And you just put your cursor over the thing
you want to look at. So I'm going to click
into this text. So as you can see here, indeed, text is a structure. So we are creating an instance
of the text structure. However, you'll notice that creating this instance
is different from how we did it before because we used a empty
set of parentheses. I'm here when we're creating an instance of
this text structure, we're passing in
some input data. So yes, you can actually
pass in input data as a parameter into the creation of an instance of a structure. These are called initializers. Now we haven't talked
about that yet and we will in upcoming lessons. But for now, just understand that there is a way
for you to pass in input data into the creation of an instance of a structure. So that's exactly what's
happening right here. Now you might be wondering, does this text structure
conformed to the view protocol? Well, it must write because according to this body property, whatever is returned for this computed property
has to conform to this. So again, let's dive
into the quick help. So I'm going to
hover over texts. I'm going to go down. And in fact, I'm going to open up the developer documentation. Now if you're using Xcode 1.112, there was a bug that crashed when you try
to open this window. So you just have to update
Xcode of this crashes for you. Okay, So this is the
documentation for texts. You can see that
it is a structure. And if you scroll
all the way down, I'm going to skip all this stuff because I want to just show you that it conforms to two
protocols actually. But what we're interested in is it does conform
to the protocol. All right, Another
thing I want to point out is that this, remember this from early on. This is a modifier. And now to you, it must look
pretty familiar, right? Because it looks like
we're calling a method. This is dot notation right here. We are creating an instance
of the text structure. And then we're calling the padding method
on that instance. See if I put it
on the same line. It might look a little
more familiar for you. Alright, so I hope that dots
are starting to connect. No pun intended. Okay, so to relate this back to the previous
structures lesson where I showed you how
to declare a structure. We had a couple of
different sections, right? So at the top here we would
declare our properties. And in fact, this body property is considered a property right. But it also contains
our view code. So this would be where
our view code goes. And then down here we would declare the methods
for this structure. Okay, so I think you understand that this structure
called content view represents the main view or the main screen of this app. But didn't we say
that structures by themselves don't
really do anything. You need to create an instance
of it for it to work. Well, where are we creating
an instance of content view? For that, we need to drill back up to the entry
point of the app, which is this right here. So you can see this by itself is also a structure and the name of this structure is the
name of your project and it conforms to a
protocol called app. So let's look at the
quick help and see what this protocol is all about. Creating an app by declaring a structure that conforms
to the app protocol, implement the required
body computed property to define
the app's content. Now we have another
body computed property. I'm going to skip over some of this scene in
Window group stuff. I want to point out that this is where we are creating
an instance, that content view structure. So do you see how
everything fits together? Furthermore, let's go back to content view and let me
show you something else. So for this, I'm going to
open up the canvas again. And I'm going to
resume the preview. Look at this
structure down here. This is what is powering the
preview that you see here. This structure isn't really
used as part of your app. It's only for previewing
in the Canvas right here. So it conforms to the
preview provider protocol. And it's got a property called previews,
static keyword ignore. For now, we'll explain
that in a future lesson. And down here, you can
see that an instance of your content view
structure is being created and that's actually
what's being shown here. In fact, I can
apply modifiers to this instance and it's going
to change what we have here. Alright, so I can use dot
notation to call modifiers, which now, you know, are just methods, right? Of that view or
of that instance. Actually. Instead of doing
that, why don't we use the visual way and see
how it changes the code. So 10, I preview this change. Actually I'm going to change
the scheme to dark mode. So you can see it adds a
modifier to that instance. Let's also change the
device to iPod touch. You can see it adds another modifier
called preview device. Now, what happens if I
create another preview? Because you can click on
this button right here, and it's going to create
another preview down here. You can see what
happens to the code. Well, it created
another instance of content view and it's
got its own modifiers. Now this is grouped
together by a container, a container called group, which we haven't
really covered yet, but we will in the future just know that it
groups together views. So this instance of content
view is for this one up here, and this instance is
this one down here. See I can change this
scheme to light. And you can see it
changes that here. And I can change this
device to iPhone 12. And the changes that
modifier there. So they're independent
instances. I was a lot to take
in and that's why I never recommend for you
to memorize anything. The more practice you get, the sooner it's going to
become second nature to you. Let's do a quick
recap, shall we? You learned how to create
instances of your structure. You learned how to use
dot notation to access the methods and the
properties of your instances. And you also learned
about access levels. So you can control
which properties and which methods can be accessed
with the dot notation. Finally, you saw how
all of these concepts relate back to a swift
UI app in Xcode. Now in the following lessons, we're going to go
back to our war card game and take all of this new found swift knowledge and bring that war
card game to life. In the next lesson, I'll
show you how to use the button element to
handle user interaction. All right, I'll see you there.
11. 10: SwiftUI Buttons: Hello and welcome. In the previous few lessons, you learned the basics
of Swift programming. And I showed you how those concepts applied
to your Xcode project. Now, let's get back to
Swift UI and views. Specifically today I want to
talk about the button view. Let's dive right in. All right, so I've
got a brand new Swift do I project here? I thought we would take
a look at creating some button instances
in a fresh project together before we go
back to the work hard game to use the button
instance there. So let's go ahead and delete
this text view right here. In create some instances, a button is a structure
just like that text was. And we need to create
a button instance. In other words, we need to instantiate a button and it's just another
way of saying it. So let's go ahead
and type button, followed by opening a
left rounded bracket. And that's going to bring
up our autocomplete menu. There are a couple of different initializer
methods we can use to create a button instance. And these initializer
methods, remember, are just different ways of creating an instance while
passing in some data. Two of the most common
ones that you're going to be using is this one right here, where you pass in a string. And this datatype
string protocol just means anything that conforms to that string protocol and a piece of text does. This one will allow you to just pass in a piece of text to
use as the button label. And it will also allow
you to pass in a block of code to run when that
button is tapped on. So let's take a look at these
parameters in more detail. So this first parameter for the label of the button is
pretty straightforward. Here you just pass
in a piece of text. I'm going to call this
button, Click Me. And if we update, our preview will do anything yet before we specify
the second parameter. The datatype for this
action parameter is something that you
haven't seen yet. But it kind of looks like a function signature without
the function name, right? This is called a closure. And simply put, you can
think of it as a block of code or like a function
without the function name, you pass in a block of
code as a parameter. When the button is tapped on, it's going to run
that block of code. Again, this is called a closure. So let's take a
look at how we can specify the closure
as a parameter. Now one of the easiest
things you can do is you can highlight this parameter
and just hit Enter. And Xcode is going to
automatically open up a closure for you to
type your block of code in. But I'm not gonna
do that right now because I want to go
through the steps and really break it
down to you and show you what exactly
you're specifying. And then at the end, I'll show you what happens when you do hit Enter and just let Xcode
open the closure for you. Let's specify that
closure manually for now. All right, so the type
of closure that this expects is the simplest
type that you can see. It accepts no parameters. These two brackets right here, these two rounded brackets. That is a parameter list, just like you would have when you're
declaring a function. But it's empty, so there
are no parameters. And then next you see a dash followed by a
greater than symbol. And you know that that
means return type, right? And it returns void. Void means nothing. So it doesn't return anything and it doesn't
accept anything. It's very simply
a block of code. All right, so now that
you know the type of function then it's expecting, Let's go ahead and specify it. So I'm going to delete that. And I'm going to open up
a pair of curly brackets. And I don't need to
return anything. I don't need to
specify any parameter. It's very simply just
the block of code. So you can specify that with just a set of
curly brackets. And in between those
curly brackets, you put any code
statements you want. So I'm going to just
print out hello world. And that is your
completed button. Let's run this project
and see what happens. Okay, So we have been in the
middle that says click me. When I tap on it, it
runs the closure. It runs the code in the closure. And you can see that in, down there in the console, it does print out hello world every time I
click this button. Alright, now let's go back to our Xcode project
because that's only one way to
instantiate a button. I'm going to add a
comment here and call this button instance
with closure. Okay? And then I'm also going to
put this inside of a V stack. Actually, I'm gonna
show you a shorthand, cool way to do it. I'm going to put it into inside of the stack because I wanted to show you a couple of other
ways to create buttons. So we're going to create a
couple of buttons together. Go ahead and command
click on this button and you can just simply
choose Embed and v stack. Do that. It puts the element
into the stack for you, although it, it failed to
move my comment there. So let's put that right
there. All right. So we've got one button and I want to show
you the same button, but with a short-hand, There's something called
the trailing closure. Let me show you what that means. So button instance
with trailing closure, I am going to copy and
paste the button we just declared and create
another copy of it. So if in the parameter list, the last parameter
expects a closure, there is a shorthand. And how it works is you take
that last parameter out of the parameter list
and you simply put the closure after
the method call. Let me show you what I mean. So in this parameter list, that closure is that
last parameter, right? So this is a prime candidate for a trailing closure shortcut. I take the closure itself. So I'm going to cut this
out of the parameter list. And I am simply
going to add a space after the ending rounded bracket and then just paste
the closure like that. And then I can go
ahead and remove the perimeter label
or the argument label out of that
parameter list like that. And these two
button declarations are exactly the same thing. It's just that they are
written differently. One is specifying
the closure inside the parameter list
and the other one is specifying it using
a trailing closure. And this is why I
wanted to show you this manually instead of just letting Xcode open
a closure for you. Because when you
let Xcode do it, it's going to recognize that
that closure parameters, the last one, and
it's going to turn it into a trailing
closure for you. I'm automatically so
let me show you that. If I declare another button,
let's use the same one. Click me, and then I tap
on that action parameter, either double-click
it or I hit Enter and let Xcode open
up the closure. It automatically changes it
into a trailing closure. So I thought that would
be really confusing for you if you'd never
seen that before. And so at least now you know what a trailing
closure is and why, you know, Xcode
does this for you. Okay, so that is just
creating one type of button. Both of these ways to create buttons where you just have a
piece of text as the label. But what if you wanted
your button to be an image or an icon or
something like that, not just a simple piece of text. Well, there is another
initializer method for the button that
we can use for that. So let's take a look at that button instance
with label view. So let's go ahead
and type button, open up a bracket. And now let's take a look at this other initializer method with an action and
label parameter, creates a button that
displays a custom label. And you can see from
the predator list that the first let me, let me go back to that
autocomplete menu. Taking a look at this parameter
list now you can see that this action closure parameter
is the first parameter, and then the second
parameter is a label. Now for this label parameter, you can return any view that you want to represent
your button. So let's go ahead and choose
this initializer method. You can see for the action
closure right here, if I double-click it, it's not going to change into
a trailing closure. And the reason for
that is because it's not the last parameter
in the parameter list. So that doesn't qualify to be turned into a
trailing closure. Okay, So when this
button is tapped again, I am just going to print out Hello World
into the console. But for the label, you'll
notice that I have some freedom to specify what sort of view
I want to return. So here it's just
returning a TextView with a simple piece of
text here called button. But I can, I can
return an image B, for example, I could return
a stack of different views. You can return
anything you want. Let me just resume the
preview here so you can see the different
buttons we've declared. Okay? So what I'm going to return here is maybe less return
in each stack. And I'm going to return
a text that says Edit. And I'm also going to return
an image in front of that. And for this image, I'm going to specify, I haven't added any images
to our asset library, but I'm going to use something
called an SF symbol. Now we haven't gone
through SF symbols yet. We will do so in
a future lesson. However, SF symbols are great. Because they're basically
an icon set that comes with Xcode that you can
just use in your apps. And these are very
special features of these SF symbols that we will go through in a future
lesson in this course, there is a free mac app called SF symbols that you
can download where you can browse all of the different symbols that are
available to you for free. So for example, I'm just
going to use this pencil one. Each of these has a name
which you can simply specify and you'll
be able to use it. So for the image, the initializer to use, if you want to use S of symbols, is called system name. And then you specify
the name which you saw underneath the icon. Pencil. I'm just going to put pencil right there and you can
see that the icon appears. All right, So now
let's run this app in the simulator and take
a look at what happens. Okay, so I can tap this one, says Hello World Cup, that one it says Hello world. Taught this one also
says helloworld. Those are the closures that I specified for
all of the buttons. All right, Now you
know how to specify a simple button with just
the text for its label. You know how to specify a button which you can use any
view as the button. We're going to go back to our
war card game now and turn that deal button image
into an actual button. All right, so now I
have the war card game that we were working on
all the way back in, was it less than four or five? But this is where we got to. And if you remember, we had used an image
for this deal button. And this is the
view code for that. And you can see that
it's just an image. Now, you know how to
turn this into a button. So I want you to
just pause the video right now and try
it on your own, in your own project just
as a little exercise. After you've tried
it out for yourself. Or if you just got stuck, continue playing this video
and we'll do it together. Okay, let's try it out together. So I am going to just create
a little bit of space here. And we're going to
declare a button. Using button. Let's open up brackets, and let's choose this action
label initializer method. Now, inside the action, we're just going to open
up that block of code, but we're not really
going to do anything yet. We will do that in
the next lesson. But for the label inside
of a text button, label and delete that view. And I'm simply going to move
our image with the deal been into the label for our button. And just like that, you can't really see
any visual change. But however, if you run
this in the simulator, then you will notice
that you can tap it. It's a natural button. Another way, if you
don't want to launch your simulator is you
can hit this button right here for the live preview and I'm absolutely get started. Yeah. Then you can go ahead and I
have to hit Resume on that. Okay. You can see now in the Canvas, because I have Live
Preview turned on, I can test out the button. That was your first
introduction to handling user interaction
in a swift UI app. The pieces are really
coming together. Let's do a quick recap. You learned how to
instantiate buttons, and that's just a fancy way of saying creating
button instances. Your learned about closures and how they're just blocks of code like functions
without a function name. And then you learned
about trailing closures, which are just a shorthand. And just to remind you, a trailing closure is
when you have a closure as a parameter in a method call. And then it gets taken out
of that parameter list and instead is put at the
end of that method call. In the next lesson,
I'm going to show you a key Swift UI concept
that is going to allow you to change data and have
the UI automatically detect the change and then
update the UI by itself. All right, I'll see you
in the next lesson.
12. 11: State Properties: Hello and welcome. In the last lesson,
you learned about the swift UI button and how
to handle user interaction. Well, in order to change the data and then reflect
that change in the UI, we have to learn about
state properties and that's what this
lesson is all about. Let's dive right in. All right, so I wanted
to revisit that view, update lifecycle diagram
for just a second. Do you remember when we showed a link from the data
to the view code? Well, let's go ahead and do that with our war card game project. So what sort of data do
we have in this project? Well, if you take a look at
the user interface here, you can see that we need to keep track of which card
the player has, which card the CPU has, and then also the scores
of the player and the CPU. So that's four pieces of data. Let's create four properties in our content view structure to represent those four
pieces of data. So right underneath the opening curly
bracket of content view, I'm going to go
ahead and declare var CPU L2 player first
player card equals. And I'll just mimic the
cars that we have there. So we're going to have card too. And I'll actually let me
just, I'll change it. We can put something
else to start it. And then CPU card equals, let's say card nine. And then let's represent
the player score. And this is going
to be an integer. Let's start with 0 as well. Cpu score equals 0. Alright, so now we have these four properties representing
the state of the game. These four properties
are our source of truth because it represents
how the UI should look. Now how do we reflect these pieces of data
in our user interface? Well, we need to reference these properties
inside our view code. Remember that these
properties being declared in the scope
of this structure means that it's available to be referenced in any of the
methods in the same structure, as well as in this block of code for our computed body property. So if we look down here for this first card
that is right here, and we have hard-coded a string
in there, saying card to. Instead of hard-coding
a string there, Let's put a dynamic value by specifying our player
card property. So let's update our
automatic preview and just to make sure that that runs and everything's good. And you can see that that
card changes the card five because that is what the value of player card property is. Let's do the same thing for the CPU card instead of
hard-coding card three here, Let's put the CPU card
property. You see that change. And down here, for the score
instead of a string of 0, Let's put our player
score property. Now you're going to
notice an error here. It says no exact matches
in call to initializer. And that's because for
initializing a text instance, we need to pass in a
piece of string data. But player score, remember, This is an int property, so it contains int data. But how we can get
around this is we can turn our int into a string. Well, at least the string
representation of a number. So the way we do that
is we can create a new string instance
and just pass in the, we can pass in the integer. So this one would
be player score. And we're gonna do the
same thing for CPU score. We're going to create a new
string and we're going to pass in the CPU score. And just like that, we have our four
pieces of data being represented in the view
code and in turn, the UI. Now all we have to do is when the user
taps on the button, we can update this data in the properties and have the UI automatically
change, right? Well, not so fast. Why don't we go ahead
and try and do that and let's take a look
at what happens. So in the last lesson, we had changed this deal
image into an actual button. Right now that action
closure is empty. Let's put some code inside this action closure
for our button. Here we are going to update the cards and we're also
going to update the score. Now if you try to update
the property like here, let's try to update player
card equals card 11. You'll see that you can't. Xcode will complain and say, cannot assign to property
self is immutable. Now self refers to
the instance of a content view and immutable means that
it can't be changed. You see instances
are value types and because of the way that they are allocated in memory,
they can't be changed. Now, I know that makes absolutely no sense
to you right now, but I promise you
in a future lesson, we will talk about that and then it will make complete
sense for now, just understand that we
can't change the value of our property unless we
use a property wrapper. A property wrapper is
a keyword in front of our property declaration
that changes its behavior. Now specifically, I'm talking about the state
property wrapper. So let's go ahead back up to our property declarations
and see how he used this state property
wrapper to change the behaviors of
these properties so that we can
change the values. All we have do is in front of the var keyword of our
property declaration, we are going to write at State. And by adding that
keyword at state, that is going to indicate that that player card
property is actually a state property
and it's going to allow us to update
the value in it. So let's go ahead and put this property
wrapper in front of all four of our property so that they are all
stay properties. State properties have two
special characteristics. Number one is that you can
change the data in them. We've already talked about that. But number two is that
inside the view code, any references to
state properties, it, they will get notified
of the data changes and then your UI will update automatically based
on that new data. So let's go ahead, go down to the action closure of our button and try to update some of these
state properties. And let's watch the UI change. Okay, so here we are. And as you can see now
the error is gone. And I can put CPU
card equals card 12. And let's go ahead and
update the score as well. Might as well just to that. So I'm going to say player
score plus equals one. That means to
increment it by one. Cpu score plus
equals one as well. And we'll save this. Then. Let's go ahead and do a live preview,
see if we could do that. All right, so this
is a live preview. When I tap on this button, it's going to run
the closure here. Wasn't that cool? So when I tapped on that button, we updated the data in
the state properties. Right? And because in our view code, it references those
state properties, they got notified and the UI was re-rendered to
show the new data. Now the problem is that every time we tap on
the button, I mean, it's incrementing the
score, which is cool, but the player cards
aren't being randomized. So what we can do is we can use the random method
of the instructor, generate a random number. And then we are going to
append that random number to the back of the card string
to generate a new card. So let's take a look at
how that would work. Generate a random number
between two and 13. Because if you look
at the asset library, we have card to all the
way to card 14 actually. So I would probably want
to generate two to 14. So I'm gonna say Let player rand equals
int dot random. And this method allows
us to specify a range. You can specify a range with
the lower end of the range, dot, dot, dot, and
then the upper end. And it should be inclusive, if I remember correctly. And we will see in a second. And let's declare another one. Cpu rand equals int dot-dot-dot random in
two, dot-dot-dot and 14. And then what we're going
to do is instead of specifying the number inside
the hard-coded string, I'm just going to specify card. And then I am going to add
player Rand and add CPU rand. Now, we might not be able to do this and as
expected, we can't. Because as you know from
earlier in this lesson, what we're trying to do
here is we're trying to append a integer to a string. And what we have to
do instead is convert that integer to a
string first and get the string representation
of that integer. And there, this should
be dynamic now. So let's take a look at this and see if it's what we expect. This is perfect. The cards are randomizing. What's not perfect is
the score down here. We still need to
determine which side wins and then increment
the appropriate score. So I'm going to comment
out these two pieces of code because we don't want to just be incrementing
it by one each time. Now before we end
off this lesson, I really want to point out and stress how powerful
this framework is. What we're doing here
is tapping a button. It's running this
closure and we are changing the value in
this state property. And because the state
property is being referenced inside of
our view code here, is detecting that
data change and then re-rendering what
we see in the UI. And that happens automatically. All we're doing is
changing the data. In the past with UI kit, this system didn't exist. What we would have to do
instead is update the data, just like we're doing here. But we would also have to update each view element manually
and tell it what to display. So what we'd have to do is get a reference to this image and then generate an image from this asset name
from the asset library, and then set that image
asset to this ImageView. And we'd have to do that
for this one as well. Then we'd have to do it for
the text here and the labels. So everything we
had to do manually. Now, all we have to do is update the data
in any pieces of UI tied to those
state properties will detect the change
and update automatically. Now by definition, a
state property is a piece of data that this
content view depends on. It's not something that other views would care
about or depend on. And so by that nature, we can add the
keyword private and just control the access
level to these pieces of data so that they
are only accessible within the context or the scope of this
content view structure. Since it's only
this content view that depends on these
state properties. All right, We're almost
at the finishing line. We just have to compare
the card values and then update the score state
properties appropriately. That's still a quick recap. Now, you learn how to reference properties
in your view code. We learned about the
state property wrapper. We also learned about
some new terminology including hard-coded values, dynamic values, and immutable, meaning that it
can't be changed. In the next lesson, we're
going to go over conditionals and how to compare values
using if statements. All right, I'll see you there.
13. 12: If Statements: Hello and welcome. In this lesson we're
going to talk about a swift construct that
is going to allow you to write code that says if this, then that, now this
is easy to use, but powerful syntax is
going to allow you to express logic at a
whole new level. Alright, with that said, let's dive right in. All right, so I've got a
brand new playground here. I want to show you how if
statements work before we apply it to our war
card game project. All I have here are a
couple of constants, actually, more than a couple, I have a bunch of constants
with different simple values, some integers, strings,
and Boolean values. And I want to use
these constants to demonstrate how
IF statements work. Now again, the if statement is very powerful because it allows you to run code based
on some conditions. So I'm going to use these
constants as my conditions. Let's first take a look at a basic IF statement,
declaration. I'm going to type it
out first and then I'll explain each of the parts. So you start with the
if keyword and then you put some sort of value or condition that evaluates
to a Boolean result. So I'm just gonna put ie. And I'm going to open up
a pair of curly brackets. And inside here, I will just
print Hello World, right? And that by itself is the
most simple if statement. As you can see,
starts with the if keyword and then followed by either a Boolean
value or some sort of code statement that evaluates
to a Boolean result, followed by a set
of curly brackets. And inside the
curly brackets you put the code you want to run. If the condition is true, in this case, e is false, right? So it's not going
to run that code because it doesn't
evaluate to true. However, if I change this E
and I was testing F instead, then this code would run
because it evaluates to true. Now it can get pretty
crazy because you can chain these things together. So one of the ways you can chain them together is using end, and that's a double ampersand. So let me just
indicate that there. And how this works
is if you'd write f double ampersand, Let's say g. Then, now you're testing both conditions and
because you're using end, both conditions have to be true in order for
this code to be run. So in this case, because
f and g are both true, true and true means true. Okay? And another example
is you can use or. So these are double pipes. The pipes key, a
lot of beginners, they're not sure
how to press it. On my Mac keyboard, this key is right under
the Delete key and right above the return key, and it's the character
on the backslash key. So I have to hold down shift and I have to hit backslash
to get that pipe. So double pipes, it might be
different on your keyboard. This is OR when you use an OR instead of an end and you're chaining together to
conditions like that. You're saying if
either condition one is true or condition
two is true, then run this code. So for instance, f
and g are both true. So that will definitely
run this code. If I do f and e, That's a is false. Remember, this code
will still run because at least one of
the conditions is true. Now again, this can get pretty crazy because I
can keep changing, I can keep doing ors, or I can even throw
an end in there. So let's do that. But this sort of
gets confusing now because this can be read in
a couple of different ways. Is it E and G? And then, or F? Or is it F or E and G?
These see what I'm saying. So for, if I put
brackets around these, this might make more sense. If I do this. That's saying if f is
true or E and G are true, then run the code. However, I could also put
brackets around it like this. If F or E is true and G is true, then run the code. So you can use brackets, rounded brackets to help you differentiate which
conditions to evaluate first. Alright, so far we've been
using just the Boolean values, but there's still more. I want to show you with the
syntax for an if statement before we go on to looking
at integers and strings. So along with the if statement, you can also extend that if statement to
test another condition, because this is just testing
one condition, right? You can then following the closing curly bracket of the first code
block, you right? Else if, and then you
write another condition. So let's say else-if. E, then put that else, if G, then do that. So what's going to happen here is it's going to
test this condition. If this evaluates to false, it's going to then test the next one and it's
going to cascade down. If this is false, then it's going to go
down to the next one. At any point while it's
checking these conditions. If one of them is true, then it's going to
go into that branch. It's going to run that block of code and it's going
to skip the rest. So this allows you to
test, in this case, three different branches or pathways and only choosing one, the first one being true. But keeping in mind
that it checks these branches from
these conditions, I mean, from top to bottom. So the first one that
hits that is true. That's the branch that's
going to go on down. And finally, there is also another feature
of if statements. There can be a sort
of catch all branch. If none of those
conditions above are true, then you can have
an else code block. So this code block
runs at the very end. If none of the
conditions were true and it didn't execute any
of those branches. So this is sort of like your
catch all are fail-safe. And again, these
are all optional. You can have one elsif, you can have no else ifs. You can not have any else's and you can
just have an else. So if this condition isn't true, then it's just going
to come down here. Alright, so this if statement
is really powerful. The syntax is really
simple to understand, but it gives you so much
flexibility in which code statements to run depending on what is
happening inside of your app. Okay, so I'm going to undo this so we can see sort of like a full fledged if
statement here. And I'm going to show you
how maybe integers or strings can be evaluated
as conditions. Now in the example so far, I've just been referencing Boolean values,
and that's simple. But working with
other data types like integers and strings, you might have to use those in an actual statement in order to evaluate to get a
Boolean result, right? For example, instead of g, which is just a Boolean
value true, let's use a. In order to evaluate
a Boolean result, I have to use a comparison
operator, right? So I can use greater than if
a is greater than 0, right? This can evaluate
to true or false. And aside from greater than, here are a couple
other you can use. So greater than, less than, greater than or equal to, and you have less
than or equal to. And then there's equality. With equality, you don't use a single equal sign because
that's for assignment. As you can see up here, we're assigning these
values into constants. To compare quality, you use
a double equal sign instead. So I can say down here, does a equals 0, and of course it doesn't. So this statement here is
going to evaluate to false. And because this is
an end operator, both of these conditions
have to be true. And because this one
is false already, then it's not going to
come into this branch. Anyways. We can change these as well. So if b is less
than three or four, I mean, and if c is equal to 10. So those are some examples of comparison operators that
evaluate to true or false. Now for strings, you
can also do that. You can, you can evaluate d, for example, is a string and you can test if it equals hello. So that's one thing you
can do with strings. You can still use greater
than or equal to. For example, if we had
let h equals world. And we can say if D
is greater than h. So we can do that. In this case, it's going
to compare the H with the W. And because h is
not greater than w, because it comes before W, then this is going to be false. One more interesting
thing I want to show you is the use of the
exclamation mark. So this one, it basically
flips the Boolean value. So if g was, G is true, right? If I put the exclamation
mark in front of it, it's basically going to
flip the Boolean value. So g is true. I have the exclamation mark. It's going to turn
it into false. So it's not going to run this. You could put it in front
of this, for example. And a dozen, a does not equal 0 because a is one, as you
can see up there. But having this in front of it is going to
flip that to true. And then now that I think of it, you can test inequality as well. So not equals. Okay, so I can test if a is not equal to
0, which is true. But then because I have this exclamation
mark in front of it, it's going to flip it to false. So lots of flexibility here, and this is just
an example, right? So it doesn't have to
be this complicated. Now I want to go back
to our war card game and use the if
statement to determine which card is larger and then increment either the player
score or the CPU score. All right, so here I have
the war card game project. And if you take a
look at this part here where we were
updating the score, we're simply
incrementing the CPU and player's score with each
a dealing of the button. Now that you've learned about if statements in the
Xcode playground, I'm sure it's very
trivial for you to implement it so that you're comparing player ran
versus CPU RAM and seeing which number is bigger to determine which score to update. Now, because we
labeled our assets correctly to being the lowest
and ACE being the highest, having a value of 14. It's very trivial to compare. You just compare that
ending number, right? And essentially that
is the random number. So if you think you can do this, pause the video right now, and try it out for yourself. You'll learn a lot. I promise, even if you Give it a shot
and you don't get it, the lesson is going to
stick that much more. So go ahead and pause the video, try it out, and then unpause
it and watch me do it here. All right, So welcome back. Let's implement this
if statement to see which card is bigger. So
I'm going to start with if. And I'm going to first test if the player's number is
bigger than the CPUs number. All right, I'm going
to use greater than, if that is the case, then I am going to
increment the player score. Otherwise, I am just going
to increment the CPU score. Now. I don't care about ties, and that's why I'm not comparing equality between the
two random numbers. But you could definitely do that in your version
if you'd like. Actually, there is a problem with the way that
I'm doing it here. The CPU has an unfair advantage because in the case of a tie, the CPU does get the score right using
this else statement. So therefore, I kinda do
have to test the other case. So I'm going to test else-if CPU rand is greater
than player around, then CPU score plus one. Otherwise, if those two
conditions are not true, then it's a tie and I
don't want to do anything. All right, now
let's try this out. So I'm going to hit
live preview again, and we'll just do it
right here in the Canvas. I'm going to hit deal. So 14 is definitely
bigger than five. So the player gets a score. Jack is definitely,
well, that's a, that's an 11 is greater than 3, four is greater than three. So it looks to be
working correctly. Congratulations, the war
card game is complete. You've learned how to
build user interfaces, how to code in Swift, and you've completed
your first app. Think back on day one of
this 14 day challenge. How did you feel back then? Were you nervous that you think
you could do all of this? And now look how
far you've come. How do you feel about
app development now? Now I've tried to make this
as easy as possible to understand and I hope you are able to gain some new skills. Now I know I'm making
this sound like the end, but really it's just the
beginning of your journey. In the next lesson,
I'll tell you what are the next steps and
where to go from here.
14. 13: Bonus Challenge: Hello and welcome to Lesson 13. Now, in this lesson, it's going to be more of a hands-on and
practical challenge. I want you to try to build
this app on your own. Now, you have all the skills you need based on lessons one to 12. And this exercise is going to be a great way to reinforce
what you've learned and also to identify any gaps in your knowledge at this
point so that we can go and review it and also
go and figure out what it is that
you need to get up to speed before continuing. Okay, So let me just
walk through this app. You've got a title, you've got number of credits, you've got some images. And when you hit this button, it merely randomizes the images. If they don't match, then
you're going to lose credits. But however, if you get
three matching ones, which I can't seem to do
right now. Oh, there we go. Then you would gain credits. So this is very much
like the war card game, except that now there are three things that you
randomize instead of two. And the image assets are in
the description in a link. So you can make sure
you grab those. Then you'll have
everything you need. Whether you think this is too easy or if it's too
hard, either way, I highly recommend that you try it because it's really
the best way to learn, even if you get stuck. When you look at the solution
and you figure out how to overcome that obstacle
that you're stuck on. It's going to be extra
meaningful and it's going to really help
commit it to memory. And this belief about
hands-on learning is due to my own failure in the beginning when
I tried to learn iOS. So this is not just something I read
or something I heard. This is from my own personal
experience that it's, there's nothing else that can replace as the
best way to learn.
15. 14: What's Next?: You've made it. Where do you go from here? What do you learn next? Well, there are still a
ton of skills to master before you can finally build
any sort of app you want. But I hope in at least doing the war card game and
completing this challenge, it's helped you break through some mental barriers about whether or not you can do this. Because now you should
know that you can do this. And it's just a matter of time. More learnings, more
obstacles overcome, and more practice before you
finally reach your goal, I'm going to share with you
the next five things you can do to make progress
on your app journey. Number one or more views and containers through doing
the war card game, you already learned
about a handful of them, such as text, image
buttons, stacks, but there are a lot more VMs and containers that you can
learn about such as toggles, pickers, status, bar shapes, grids, lists, and the
list just goes on. Now learning how to use
more views and containers is like getting a truck
load of lego pieces. Your options are going
to expand greatly. Number two, more types of apps. Why? Well, think about it. Nothing new ever
comes from scratch. You're always drawing upon
your previous experiences, what you've seen, what you've
done, what you've tried. So if you want to
build your own app, the best thing you can do at this point of your
journey is to get exposed to as many different
kinds of apps as possible. With each new app, you're going to learn
new architectures, new patterns, and new
ways of doing things. For example, how do you navigate from one
screen to the next? How do you download
data from the Internet? How do you save
data to a database? And how do you let users
create accounts and login? These are all different kinds of apps that you need to be exposed to before you can incorporate these same
elements into your app. Number three, more,
Xcode and swift. Now in this challenge,
we've lightly touched on Swift basics and how to
navigate around the next code, but there's definitely
more depth to both. Azure Apps get more complex
in your projects, get bigger, you're going to encounter more problems and
more bucks to solve. And you're going to
need a deeper command of the Swift
programming language. So how do you learn
more swift and Xcode? Well, it goes back to
building more apps. As you build each app, you're naturally going to learn more swift and Xcode techniques. Number 4, MVVM. Now this one's pretty
important in Swift UI. This is the main architecture
pattern and it stands for Model-View-ViewModel in the
war card game that you did. We had the view part and we had some data
properties in it. But in a larger Swift UI app, you would have models
representing your data as well, and view models
supporting your views. This architecture pattern exists in any larger Swift UI app. So it's pretty
important to know, do some Google or
YouTube searching on MVVM to understand it
at a conceptual level. And then next time you
do a swift UI Tutorial, either try to spot the pattern yourself or if you're
building your own Swift do I apps definitely try to put the pattern
into practice. Number five, more
Apple frameworks. Apple has a ton of frameworks that you can tap
into with your app. Simply add the framework
to your Xcode project, read the documentation
and you'll be adding new capabilities to your app
such as machine-learning, augmented reality, and so on. Now this is going to take
a little more experience because you need to read and
understand documentation. But it's a good skill to start training because
every year there's going to be new tools and new platforms and new
frameworks for you to learn. As an app developer, the learning never stops and your ability to learn quickly and to try things
out will really determine your
long-term success. Those are the five areas
I recommend that you explored make progress
on your app journey. I want to thank you so much for sticking through this challenge
and for learning with me. I hope you've had an
awesome experience. And if you've had, please share it with your
friends and family. Please help me get
the word out and tell everyone about
code with Chris. I appreciate you so
much and thank you for letting me be a part
of your app journey. All right, I'll see you
in the next lesson.