Transcript
[ Music ]
[ Applause and Cheering ]
>> Welcome to Getting Started
with Xcode.
My name is Prachi and I'm an
Xcode engineer.
Along with my colleagues Holly
and Honza, I'll be walking you
through how you can build a
simple iOS app using Xcode.
Xcode is an integrated
development environment used for
developing software in Swift,
Objective-C, and other
languages.
In the session, we'll be
covering how you can create a
new project using Xcode, write
and navigate your source code in
Xcode's Source Editor, run and
debug any issues that may exist
within your code base, extend
the functionality of your app
using packages and frameworks,
and finally how you can test
distribute your app to the App
Store.
Let's get started with creating
a new project in Xcode.
In front of you, you see the
Xcode window which I'll be
discussing in four different
sections.
In the center section is the
Source Editor where you can view
and edit all of your files.
In particular, we have the
Source Editor open and you can
use it to navigate and edit all
of your source code.
There are other editors
available to use such the
Project Editor.
And here, you can customize your
project settings when you need
to.
Within the project editor, you
will find targets for your app.
A target contains instructions
to build one product.
Examples of products include
libraries, frameworks, test
bundles and the app itself.
To the very left of the Xcode
window is the Navigator where
you have quick and easy access
to all of the content within
your project.
You can use the Navigator
selector bar to select a
navigator.
You have many available to you.
And because we have the project
navigator selected, you can use
it to add, delete group, or
otherwise manage all of the
files that exist within your
project.
On the very right is the
Inspector and it provides with
you contextual data about the
contents of your editor.
Because we have the Source
Editor open, you can view
information about the file
that's being displayed such as
the file name and the file path.
The top section is a toolbar.
And here, you'll find the Run
button which will build and run
your product.
The Stop button will terminate
the current action in progress.
The next two drop-down menus are
the Scheme and the Run
Destination.
A scheme a sharable file that
contains rules for our how app
will be built, run and tested.
The Run Destination is where you
will run your app.
You can choose to run your app
in a simulator for a device such
as the iPhone XR which is what
we're doing up here.
You can run it on your Mac or a
connected device such as an
iPhone or an iPad.
The last three buttons are the
Show and Hide buttons which will
show and hide different sections
of the Xcode window.
And these can come handy.
For example, if you're
developing code and you need
more space in the editor, you
can use the right mouse button
to close the Inspector and
provide yourself with that extra
space in the editor.
Now, I'd like to bring your
attention to the Xcode Help Menu
where you have access to
resources such as Developer
Documentation, Release Notes and
Xcode Help.
Xcode Help is an amazing
resource for learning about
Xcode.
And we highly recommend that you
browse through it on your own.
So now that we walked through
the layout of the Xcode window,
let's go ahead and create an
actual project from scratch.
So in front of you is the
Welcome to Xcode Window.
And on the left, you have the
option to create a new project
which will store all of your
files and resources for your
app.
You can also clone an existing
project that may be hosted on
the source control account such
as GitHub.
And finally, you can also open
up a Xcode Playground which
allows you to experiment with
your Swift code and then see the
result of that code in real
time.
On the right are all of the
projects that we've been
recently modifying, and so we
have quick and easy access to
them.
I'm going to go ahead and create
a new project in Xcode.
This will open up the template
selector.
Templates are starting points
for our app.
And there are a variety of
templates that are available for
us to use.
In order to pick the right
template, we need to start out
by identifying the platform
we're developing for.
And I know I'm writing an iOS
app.
So I'll go ahead and click on
the iOS tab.
Within this tab, you'll notice
that there are two categories of
templates available such as the
Application templates and the
Framework and the Library
templates.
For the purpose of this session
though, I'm going to go ahead
and select an Application
template and I'm going to pick
the simplest one which is the
Single View App and I'll click
Next.
So my teammates and I have
decided we want to build a
meditation application.
And we've decided to call it
Mind.
So for the Product Name, I'm
going to enter in Mind.
For the Organization Name,
typically, I would put in the
name of my organization, but for
the purposes of this session,
I'm going to call ourselves
Example Team.
The Organization Identifier is
then the reversed DNS of the
organization name.
So in this case, it is
com.exampleteam.
Finally, the Bundle Identifier
is autofilled and it is a unique
ID for your app within Apple's
ecosystem.
It is a combination of the
Product Name and the
Organization Identifier.
For the Language, I will go
ahead and leave at Swift because
I want to write my app in Swift.
And I will ensure that I have UI
Tests included so that it
creates a target for them.
Because as developers, we want
to be in the habit of constantly
testing our code.
We'll show you later how to add
unit tests.
So after you click Finish, it
will open to Save sheet.
Here, I can decide where I want
to save my app.
It defaults to the Desktop and
I'm happy with that.
So I'll leave that as is.
But one thing that I do want to
ensure is that Source Control is
available from the very
beginning of this project so
that I can manage, track and
backup any changes that I make
during the development process.
So I will go ahead and check the
Create a Git Repository on my
Mac checkbox and I'll click
Create.
So we have our template setup
now.
We can add an app icon to our
app.
App icons are the images that a
user will select whenever they
want to launch our app.
App icons are assets.
Examples of assets include
images and colors.
Assets are managed and organized
by an asset catalog and we can
access that asset catalog
through the Navigator by
clicking on it.
And because we want the catalog
for our app icon, let's go ahead
and click on the app icon and
the editor.
And you'll notice from the
catalog that you can have assets
for Notifications, Settings,
Spotlight as well as the app
itself.
So I have an app icon sitting on
my desktop.
It's ready to be used.
And I have device that uses 2X
resolution.
So app icon-- assets are
available for 1X, 2X and 3X
resolution depending upon the
device you use.
So I'm going to ahead and grab
this app icon and drag it into
the 2X catalog box for the
iPhone app.
Now, I want to test my app icon
to make sure that it actually
works.
So to do that, I want to run it
in a simulator for the iPhone
XR.
So I'll change my Run
Destination to the iPhone XR,
and then I'll click the Run
button.
This will launch the simulator.
And you'll notice that the
simulator goes about launching
my app immediately.
I know this because it's
displaying Hello World and
that's what my template is set
up to do.
So I need to go to the Hardware
Menu to actually see my app icon
in the home screen.
So I'll go to the Hardware Menu
and click on Home.
This will bring me to the home
screen and I see my app icon is
there.
If I click on app icon, my app
comes back into the foreground.
So great, I know that my app
icon works.
I can terminate execution of the
simulator.
And now, we're at a good point
where we can commit and save our
changes so that our colleagues
Holly and Honza can continue
developing on this app-- on this
project.
To do that, we first need to add
a GitHub account.
We can do that through Xcode
Preferences which you can access
from the Xcode Menu and then
going to Preferences.
Xcode Preferences lets you
customize Xcode for your needs.
And in order to add an account,
we'll go ahead and ago to the
Account Preference Pane and
click on the Plus button.
You'll see that there are a
variety of accounts that are
available to us.
And since we're interested in
the GitHub account, we'll click
on GitHub and click Continue.
So now it's asking me for my
account credentials so I am
going to go ahead and type in my
account name and my password.
So it's signed in to my account
which is great, so I'll go ahead
and close Xcode Preferences.
And now, I need to make the
actual commit.
So to do that I'll go the Source
Control Menu and I'll click on
Commit.
This will open up the commit
sheet.
And here you can verify all of
the changes you made and you can
add a commit message to let your
colleagues know what you
changed.
So for the commit message, I'll
say that this commit will add an
app icon.
And I'll click commit which will
close the commit sheet.
So now to get to this point in
our development, we started out
by creating a project using
Xcode.
We then chose a template that
was appropriate for our
platform.
We added an app icon to our
asset catalogue and then we used
Xcode source control
functionality to commit our
changes so that our colleagues
could continue developing on our
project.
To learn more about Source
Control we recommend that you
check out the Source Control
Workflows in Xcode talk from
2018.
Now we're at a point where we
can start adding actual
meditation functionality to our
app.
And to do that, I'm going to
invite up my colleague Holly.
Thank you.
[ Applause and Cheering ]
>> Thanks, Prachi.
My name is Holly and I'm an
engineer on the Xcode Source
Editor team.
And welcome to the Source
Editor.
This is where you will write all
of the code for your app.
To the left of the Source Code
we have the line numbers, and to
the right of the code we have
the mini map which shows you a
miniature view of the file in
the editor for navigation.
Above the source code we have
the Jump Bar.
The Jump bar also helps you
navigate the file in the editor
using the function popup.
The Jump Bar also lets you
customize the layout of your
editor using the Editor Options
and Editor Split menus.
We are already making great
progress on building our
meditation app.
Let's have a look at where we're
headed.
We are building a meditation app
that allows users to select a
duration and meditate for that
amount of time.
When the meditation is over, the
app will write the user's
mindful minutes back to their
health data.
We'll need to add quite a bit of
Swift code to get our app
working.
But instead of trying to read
the code that I write, I want
you to focus on the tools that
Xcode provides to aid the
editing process.
And if you're new to Swift,
welcome.
To get started with Swift, I
recommend going through the
Swift guided tour which is
available online or in an Xcode
Playground so that you can
experiment with the Swift code
as you walk through the tour.
This resource is available on
docs.swift.org.
And with that, let's head over
to Xcode.
I added some code to the project
template that Prachi showed us
to implement timing of
meditation and drawing a
peaceful background for the app.
We still have to implement a UI
for selecting a meditation
duration and for starting the
meditation.
We also have to implement the
class that interacts with
HealthKit.
To get our app up and running
really quickly, I implemented a
mock HealthStore that does not
interact with HealthKit and
we'll implement the real
HealthStore later.
So here, we're looking at the
ContentView.swift from the
project template and I added a
title and a background.
While building the UI for your
app, Xcode can show you a
preview of what your UI will
look like on an interactive
Canvas.
To show the Canvas, we can
select the Editor Menu and click
Editor and Canvas.
The Canvas will build and run
your code as you edit so that it
can show you the results of your
code in real time.
So now in the preview, we can
see the welcome title and the
peaceful background.
Next, I want to add a meditation
view.
So I'll create a new file, and
I'll use the SwiftUI View file
template.
And I'm going to call this
MeditationView.
Right now, the preview is
showing me a full device, but
the view that I'm working on is
only taking up a small portion
of the screen.
I can modify the preview
provider which is what's
supplying the view to show on
the Canvas to only show the view
that I'm working on using the
previewLayout modifier.
When I start to type the
modifier, Xcode will bring up
the Code Completion Window.
This shows me a list of
suggested symbols based on the
text that I typed as well as the
surrounding context of the code.
The modifier that I want is the
first one in the completion list
and I can press Enter to accept
the suggestion.
Now Xcode inserted the symbol
into the editor along with the
placeholder for me to fill out
the remaining code.
And I'll fill that out now with
a sizeThatFits.
Next, I know that my
MeditationView will need to
interact with the
MeditationController.
So I am going to add a property
wrapper that wraps a
MeditationController, and I'll
resume the preview.
If you're unsure of what a
certain API does in the Source
Editor, you can view
documentation for that API by
holding down Option and clicking
on the symbol that you want to
view documentation for.
This will bring up the Quick
Help popover which shows me the
declaration of the symbol along
with its documentation.
Before we move on, I need to
supply a MeditationController
using the environmentObject
modifier.
Now, let's start building up
this view.
Right now, we have text that's
showing us Hello World, and I
want to change this to show the
remaining time for the
meditation which I can get from
the MeditationController.
And as I updated the code in the
editor, the preview updated to
reflect this change.
Now, the text looks a little
small to me and I can make it
larger using the Inspector.
So, I'll show the Inspector from
the button in the Xcode Toolbar.
And I'll click on the Attributes
icon.
Then I'll click on the view that
I want to inspect.
And here I can see the values of
all of the modifiers being
applied to this view.
Right now, the font is
inherited, and I can change it
by clicking on the Menu, and
selecting Large Title.
When I do that, the preview
updates and the Source Editor
automatically adds in the code
required to make this change.
[ Applause ]
Above the text, I want to show a
button to allow users to pause
and resume their meditation.
You can add in ready to use
resources into the file that
you're working on using the
Library which you can access by
clicking on the plus button in
the toolbar.
The Library has different
categories of objects including
views, modifiers, and code
snippets.
Let's look at the code snippets
category.
Xcode has built in code snippets
and you can add your own
snippets too for fragments of
code that you write frequently.
Here, you can see all of the
snippets that I have added to
allow us to add code really
quickly during this demo.
But now I'll switch back to the
View Category, and I can type in
the view that I'm looking for.
I can drag in this button into
the Source Editor or directly on
to a preview.
And now the Canvas is telling me
that this button will be added
to a new vertical stack along
with the existing text.
When I drop the button, the
Source Editor will add in the
necessary code to embed both the
button, and the text into a
vertical stack by adding a
VStack.
And now I can fill in the
placeholders.
When we tap the button, we want
to toggle the meditation.
and rather than showing text, I
want to show an icon that's
either showing play or pause.
Now finally, I only want to show
the remaining time if the user
is actively meditating.
Otherwise, I want to show a
picker with preset meditation
durations.
Xcode knows a lot about the
structure of the code that I
have written in the editor, and
it can help me transform and
refactor my code using
structured editing.
If I hold on Command and click
on a code structure such as
Text, Xcode will show me the
Action Menu which has many
different actions that I can
perform to transform this code
structure.
There are also options in the
Menu to Jump to Definition and
to view Quick Help for the text
symbol.
Since I only want to show the
text under a certain condition,
I'll click on Make Conditional.
And now I can fill in the
placeholders again.
The condition is if the
meditation is active.
And now, I have another
placeholder further down in the
file.
And I can jump to it, using the
Control-forward slash key
binding which helps me really
quickly fill out the missing
code without even having to
touch the mouse.
Now, this is exactly what I want
my meditation view to look like.
So now, I'll switch back to the
ContentView to add it there.
I want to add my MeditationView
to the bottom of this VStack
along with another spacer.
And now, the preview has updated
to show me my welcome title, my
Play button and my picker to
select the meditation duration.
Now, that I'm done with the UI,
I'm going to close the Canvas.
And I'll hide the Inspector to
make some more room in the
editor.
Before, we try to run our app, I
want to modify the
MeditationController to make
debugging a little easier.
And here, I'm going to use the
mini map to navigate to the
Meditation Timer State section
of code.
The mini map shows me text
labels for all of the marks
throughout this file.
And I can navigate to a mark by
clicking on the label in the
mini map.
A mark is a special comment that
Xcode understands to show your
sections of code any editor, in
the jump bar and into the mini
map.
Now, in this section of code, I
have several computed properties
that indicate state.
To make inspecting the state
easier, I'm going to add a
stored property called State
that has one of the possible
values stopped, paused, or
running.
And I'll default this to
stopped.
Now, when we update the
MeditationTimer, we want to look
at the timer state and update
the controller state using a
switch statement.
The possible values of the timer
state are nil, paused and
running.
And in Swift, switch statements
must be exhaustive.
If they're not, I'll get a
compiler error telling me to add
the missing cases.
And notice that I've gotten a
compiler error in my editor
without even building my code.
These are called live issues and
they appear as you type.
So if I click on the live issue,
I get a Fix-It asking me if I
want to add the missing cases.
And I do. So I'll go ahead and
click on that.
Now in the case where the timer
is nil, I want the state to be
stopped.
Now, rather than having a catch
all case for all of the possible
values that can be wrapped, I
want explicit cases for each of
those values.
So I'll change this underscore
to the first value which is
running.
And now that I've done that,
this switch statement is no
longer exhaustive.
So, I'll get another live issue
with another Fix-It to add at
there with last remaining case.
And I don't need this associated
value so I'll go ahead and
remove that.
You may have noticed that these
two names, running and paused,
are the same as the remaining
cases of this State enum.
And I can use multi-cursor
editing to quickly fill out the
code placeholders.
Right now, I have one insertion
point, and I can add another one
by holding down Control and
Shift and clicking where I want
to place my next insertion
point.
Now that I have multiple
insertion points, I can perform
any command and that command
will act on each my insertion
points.
To see all of the commands that
are available, you can go to the
Xcode Preferences, select the
Key Bindings Tab.
And here you can see all of the
commands and their key bindings,
and you can even change the key
binding to be whatever you like.
So I'll will show you a few now.
I can select the word back,
copy, jump to next placeholder,
type and paste.
And now, we're done.
[ Applause and Cheering ]
And this is all of the code that
we need to implement the basic
functionality of our App.
Before we dive into running and
debugging, let's review what we
learned about the Source Editor.
We saw how Xcode's interactive
Canvas can help us preview the
UI of our app and help us edit
the appearance of our views.
We learned how code completion
can greatly speed up the
development process.
Then we saw how Xcode can help
us transform and add
functionality to our code
structures automatically from
the Action Menu.
And finally, we saw how live
issues and Fix-Its can help us
fix our compiler errors before
even building our project.
For more information on the new
Swift language features that we
saw or the SwiftUI framework
that we built-- that we used to
build up our views, please watch
the What's New in Swift and the
Introducing SwiftUI Session
recordings.
And now that we're ready to run
the app, I'm going to hand it
off to Honza to walk us through
running and the bugging.
[ Applause and Cheering ]
>> Thanks Holly.
Hi, my name is Honza and I'm and
Xcode engineer.
So now that Prachi created our
project and Holly added some
codes to it, we'll talk about
how we can build, run and debug
our app on the simulator and on
a real device.
And then, we'll add a Swift
Package dependency that allows
us to add new feature to our
app.
So let's get started.
So Prachi has shown you how to
build and run our app using the
Run button in the toolbar.
But we can also do this from the
Product Menu where we have the
options to Run, Test, Archive,
Build and many more.
So right now, I will run the app
on the simulator.
The app is being built,
installed, and launched on the
iPhone simulator, and the
simulator app comes to the
foreground automatically.
So this is what our app looks
like right now.
So, because we're moving pretty
fast, let's do a quick
meditation using our new app.
All I have to do is click on the
Play button to start a new 3
minute meditation.
So the meditation started
correctly, but the Play icon
didn't change which I think is
wrong.
Just like in music apps, we want
to show the Play icon when the
meditation is paused, and the
Pause icon when the meditation
is running.
So we'll use the debugger
integration in Xcode to help us
find and fix this bug.
To run our app with debugger
attached to it, I don't need to
do anything special.
As when I just run my app right
now, Xcode automatically
attached debugger.
So, I'll leave the app running
in the simulator right now and
go back to Xcode.
And we'll start to looking in
the MeditationView.
We'll get to the MeditationView
by using the Jump Bar.
And the MeditationView is
responsible for showing the Play
icon and the remaining time
label.
And here, it seems that we're
getting the image from the
MeditationController's
displayedIcon property.
So, to get there, I will Command
click on displayedIcon and
select Jump to Definition.
And here we are in the
MeditationController.
So I will add a breakpoint to
the second line of the
displayedIcon property getter by
clicking on the line number.
And because the app is still
running in the simulator and the
timer is still ticking, the
breakpoint got hit right away
and highlighted the line in
green.
Breakpoints in general allow us
to pause the app's execution
when it hits a specific line of
code.
So at the bottom of the Xcode
window now, let me make this a
bit bigger, we have to debug
area, at top of which is the
Debug Bar with the buttons to
control the debugger, as well as
to activate features like the
View Debugger, the Memory Graph
Debugger and more.
Below it, we have the variables
view on the left and the console
on the right.
And finally, on the left hand
side of the Xcode window, we
have to Debug Navigator within
information about our running
app, like how much work it's
doing, how much memory it's
using.
And below it, we have to calls
stack.
The call stack is the record of
how this code is being called.
And when I select a different
frame in the call stack, Xcode
switches the Source Editor, the
debugger, and even the variables
down here.
So, I'll switch back to the
original frame and we'll get
back to trying to fix the bug
where the icon didn't change
after we started the meditation.
So, let's look at and which icon
is being used to right now.
I can do that by selecting the
variable and clicking on the
Quick Look icon at the bottom.
And here, we get a preview.
And because the variable that
we're previewing is an image, we
actually got a rendered version
and damage right here in Xcode.
Quick Look preview supports
images, colors, views, any
custom objects that implement
the debug Quick Look object
method.
So in the preview, we can see
that we're still showing the
Play icon even though the
meditation is already running.
So I wonder if it's because the
MeditationController is in the
wrong state.
To find that out, I will expand
the self variable which refers
to the MeditationController
we're debugging here and we
reveal the properties.
And one of them is the state
property that is telling us that
the MeditationController is in
the running state.
So that's what I expected.
And that means that the
displayedIcon property getter is
not taking the state of the
MeditationController into
account when picking which icon
to show.
So to fix that, we will check if
the MeditationController is
running.
And if so, we will show the
pause it, we will show the Pause
icon, and otherwise, we'll show
the Play icon.
Now, because I don't need the
breakpoint anymore, I will
remove it by dragging out and
letting go.
And because we changed the code
just now, I will stop the app
and click the Run button again.
This recompiles the project,
reinstalls and relaunches the
app in the simulator.
Now this time, when I start a
new meditation, we can see that
the icon changed from Play to
Pause.
So the bug is fixed.
Great.
[ Applause ]
So we'll stop the app for now
and we'll hide the debug area.
So, we have been running our app
on the simulator which is a
great way to quickly iterate on
our code.
But I would also like to install
my app on a real device so that
I can start meditating on the go
as well.
First, to be able to run-- to
install and run apps on
connected devices, we have to
sign into Xcode with our Apple
ID.
We'll do that by going to Xcode
Preferences, select an account,
and adding new account.
We'll select the Apple ID, type
in the username and password.
And there, we sign in to Xcode
with our Apple ID.
Next, I'll close the window and
I will go to the Project
Navigator and select the
project.
Here, we'll select the app
target and go to the Signing
&Capabilities Tab.
This is where we manage code
signing and capabilities.
Capabilities allow us to declare
what permissions our app needs.
And in our case, we need to
access to the HealthKit data to
be able to write meditations
that the user performed in our
app, but also to read
meditations that the user
performed in other apps so, that
we can show them statistics for
all of their mindfulness
activity.
So we'll add a new capability,
search for health, and select
the HealthKit capability.
Next, I have this iPhone
connected to my Mac here.
So, I will select that as the
run destination, and I will
click Run.
Now, the app is being built for
the device, installed, and
launched there.
And so that you can watch what's
going on on the screen, we'll
use QuickTime Player which
allows me to stream the iPhone
screen back to the Mac.
So there, we have Mind running
on a real iPhone now and I could
just unplug this phone and start
meditating on the go.
Now, let me stop the app and
switch the destination back to
the simulator.
When you want to find out more
about devices, you can go
Window, Devices and Simulators
where we can see the name, the
type, and the OS version of the
device, as well as we can see
the installed apps that we've
put there.
But also, we could actually
configure the device to connect
to Mac over WiFi.
In that way, I wouldn't need to
physically plug in the phone to
the Mac over USB at all and I
would still be able to build,
run, and debug on it.
So, now that we successfully run
our app both on the simulator
and on our device and we even
fixed a bug in it using the
debugger, let's talk about
adding more functionality to our
app.
I'd like our app to show the
users statistics about their
meditations, like how many they
have performed, what the average
duration was, and so on.
But calculating statistics is
not a specific problem to just
our meditation app.
So we have created a Swift
Package called QuickStats that
solves that problem for us.
A Swift Package is basically a
folder with the manifest file
and source files that you can
use to build products like our
QuickStats library.
To add the package to our
project, I will go to the
project editor and select Swift
Packages at the top.
Here, I will add a new package
to our project.
And because Prachi signed us
into GitHub with our account, we
can actually see all the
repositories that our account
has favorited.
QuickStats is right here at the
top, so I'll select it.
Click Next.
We'll, use version 1.
That looks good.
And this is where we make sure
that the QuickStats library gets
linked with our app.
I'll click Finish, and now Xcode
manages the fetching of the
package in the background.
And in the Project Navigator,
there's an Swift Package
dependency section where I can
actually browse the sources of
the package which is a great way
to understand how the package
works under the hood.
Now, before I hand it back over
to Holly to integrate this
package into our project, let's
do a quick recap.
We saw how we can run and debug
our app on the simulator.
And we also ran our app on a
real device.
And then we added the Swift
Package dependency to our
project that allows us to add a
feature to our app.
These are the sessions relevant
to the topics discussed in this
demo.
And next, please welcome Holly
back.
Thank you.
[ Applause and Cheering ]
>> Thanks, Honza.
During this demo, we will see
how to use the QuickStats
package in our project.
After that, we will walk through
how to restructure our project
by moving our model code into a
framework.
Let's head back to Xcode to get
started.
Now, that we've added the
QuickStats package, we can
import the package into our code
and start using its public APIs.
As Honza mentioned, we want to
show our users some statistics
about their meditation sessions
in the ContentView.
We'll jump back to the
ContentView.swift using Open
Quickly which you can find under
the File Menu.
In Open Quickly, I can enter any
type name, method name, or file
name to navigate to.
So I'll type Contentview and
press Enter.
The first thing that I need to
do is import QuickStats.
Now we're ready to start using
the APIs from this package.
I'm going to add some code below
the contentView from a code
snippet that implements
StatisticsView that takes in an
array of meditation sessions and
displays statistics about those
sessions using QuickStats APIs.
Since I have access to all of
the package source code, I can
jump to the source code
implementation to understand how
it works.
So if I Command click on
QuickStats.averageDuration and
select Jump to Definition, I'm
now looking at the actual
implementation of this method.
I can see where the file is in
the Project Navigator by
clicking on Navigate, Reveal in
Project Navigator.
And now we can see that we're in
the package source code.
I can navigate back to the
previous file by using the
Editor History button in the
Jump Bar.
Now, let's add the
StatisticsView to the
ContentView.
But before we do that, I want to
show the Canvas.
And I'll zoom out so we can see
the full device.
I'll add the StatisticsView
below the spacer and it takes in
an array of sessions which we
can get from the
MeditationController.
Now, we can see the
StatisticsView at the bottom of
our ContentView.
And now that I'm done with the
UI, I'll close the Canvas again.
Now, we want to start writing
unit tests for our model.
And to make this easier, we are
going to move our model code
into a unit testable framework.
I could choose to use a Swift
Package, but I only want to
share this code with my team.
So I'm going to choose a
framework instead.
We need to create a new target
and I can use the filter bar to
search for the framework.
And I'm going to call this
framework MindKit.
I want to make sure to check the
box to include a unit tests so
that a unit test target is
automatically created when I
create the framework.
Now, before I move the code
over, I want to import MindKit
into all of the files that I
know will need it.
I know I'm going to move over
HealthStore.swift.
And this file has two public
types that are used throughout
the project.
And I'm going to use the Find
Navigator to figure out where
these types are used.
I'll switch to Find Navigator,
and the Find Navigator allows me
to search my entire project for
text, symbol references, regular
expressions and more.
Right now, I want a regular
expression and I want to search
for HealthSession or
HealthStore.
And I'll press Enter to see the
results.
I know that I'm going to be
moving HealthStore.swift and
HealthStoreFactory.swift into
the MindKit framework.
And I can these results by
clicking on the disclosure
triangle.
Now, I'll navigate to each of
these files and add the import.
So I'll jump to the top of the
file here, and the import, and
then finally, we need it in
ContentView.swift.
Now, we're ready to move the
files over.
So I'll switch back to the
Project Navigator.
As I mentioned, I want to move
over HealthStore.swift, but I
also want to move over
HealthStoreFactory.swift.
I can select multiple files in
the Project Navigator by holding
down Command and clicking on the
other files that I want to
select.
Then, I can drag these selected
files into the MindKit group.
When I do this, Xcode
automatically updates the target
membership for these files.
And we can verify this by
showing the Inspector and seeing
that the target membership for
the file open in the editor
which is HealthStore.swift is
now the MindKit framework target
rather than the Mind app target.
Now, I haven't forgotten that we
still need to implement the
HealthStore that interacts with
HealthKit.
We're going to do that now so
that we can start integrating
real health data into our app.
The first thing that I need to
do is import HealthKit.
Now, I've never used HealthKit
before.
So to get started, I want to
read the documentation.
I can do this right in Xcode by
opening the Developer
Documentation window which you
can find in the Help Menu.
Here, you can search for a
framework from the SDK, a
specific API, or a programming
topic, such as requesting access
to health data.
So here I'll search for
HealthKit.
And now I have access to all of
the documentation for the entire
framework.
And this is also available
offline.
Luckily, I have all of the code
that I need ready in a code
snippet.
And I'll add that at the end of
the file.
Now, before we start writing
unit tests, I want to add my own
documentation for the APIs in
the MindKit framework starting
with the HealthStore protocol.
I can do this using special
comments called doc comments.
Xcode knows how to generate a
doc comment template for
declarations.
And this feature is available
through the Action Menu.
So, I'll Command click on the
first API that I want to
document which is requestAccess.
And then I'll select Add
Documentation.
Now, Xcode has inserted a doc
comment template with
placeholders for the method
description as well as the
description of the parameter
that it takes in.
So this method requests
permission from the user to
access mindful sessions.
And the completion parameter is
a closure to execute when the
request is done.
Now, I know that this method can
execute asynchronously.
And I want to add a special note
that-- to document that.
And I can do that using a
special bullet point.
And now I can add that note.
Now that I have written the
documentation, I can view this
in Quick Help.
Again, we can bring up the Quick
Help popover by option clicking
on the symbol that we want to
view documentation for.
And now we can see the
description that we just wrote,
the note that we wrote as well
as the description of the
parameter.
And this is available at any
call site of request access.
For more information on writing
and documenting your own APIs,
please see the Swift API Design
Guidelines which is available on
swift.org.
During this demo, we covered how
to use and navigate code from a
Swift Package.
We talked about creating a new
framework target in our project
and moving existing code over
into that framework.
Next, we looked at the Xcode
Developer Documentation Window.
And finally, we learned how to
write our own documentation
through doc comments.
Now, I'll hand it back over to
Honza to talk about Testing and
Distribution.
[Applause]
>> Thanks, Holly.
Now, in this section, we'll talk
about how we can test our code
in Xcode, and how to distribute
our app once we're ready to
ship.
Now, since our app is coming
along pretty nicely, we need to
make sure that it continues to
work properly.
A great way to increase our
confidence in the app's quality
is by using automated tests.
There are two high level
categories of tests that we will
write for our app -- unit and UI
tests.
Unit test ensure that a single
component such as our
HealthStore works properly by
giving it a specific input and
verifying that the output
matches our expectations.
UI test on the other hand ensure
that all these components are
integrated correctly and that
the app works from the user's
perspective.
So let's dive back into Xcode.
So Holly already created the
unit test target for the MindKit
framework called MindKitTests.
But we'll still need to add it
into our test plan.
A test plan is a file-- a
repository that describes how
our tests are built and run.
A way to see which test plan our
scheme is using is to go-- to
click on the Scheme and select
Edit Scheme.
We'll switch to the Test Action,
and here we can see all the test
plans used by our scheme.
There's only one and that the
default.
So we'll jump to it by clicking
on the jump arrow next to the
test plan's name.
The Test Plan Editor shows us
which test targets it's using
and we already have the UI test
target here for which we'll
write code in a minute, but
we'll still need to add the
unit's test target.
We'll do that by clicking on the
Plus button at the bottom and
selecting MindKitTests.
Now, let's actually write our
unit test code.
I will write some unit tests for
our HealthStore.
So what I'll do now is to
Control click on the
MindKitTests group and select
New File.
I will use the Unit Test file
template and we'll name the file
Test HealthStore.
That looks good.
The first thing we'll do here is
import MindKit because that is
where the code lives now.
And to be able to test not only
public but also internal
interfaces of the MindKit
framework, we'll add the
testable keyword to the import.
Next, I'll add two tests to our
class.
The first one verifies that
after we saved a meditation, we
can retrieve it right back.
And the second one ensures that
we can actually request access
to read and write data.
So I'll run these tests by going
to Product, Test.
Now, these tests are being built
for the simulator and run on the
iPhone XR simulator.
Now that the tests are finished,
we can actually see next to the
test name in the Source Editor
diamonds that both of them
succeeded.
Good. Now, we can also see the
test hierarchy in the Test
Navigator.
So we added a few unit tests for
our HealthStore but we want to
make sure that the UI of our app
works as well.
So we'll add some code to our UI
test.
I'll jump to the existing
MindUITests class by selecting
it in the Test Navigator.
And here, we will add UI test
code that launches our app,
starts a new meditation, a few
seconds later, it pauses the
meditation, and then finally, it
verifies the remaining time
label, shows what we expect.
So I will run our test again.
And this time, I'll bring the
simulator to the foreground so
that we can watch the UI test
run.
So the app is launched and new
meditation has started.
And a few seconds later, it gets
paused and the app gets
terminated.
Next, we can also see the unit
test launched the app for a
moment.
Now, it seems that some of our
tests failed.
And to figure out what exactly
happened, we'll go to the Report
Navigator by clicking on the
right most Navigator button.
Here, I'll select the top which
is the most recent test action
and we get to the test reports.
Here, I can see that the new UI
test I just added is marked in
red which means that it failed.
And to know what exactly
happened, I will disclose the
test and drill into the failing
activities to see that the
search in failure says that
02:56 is not equal to 2:56.
Now, this is starting to make
sense.
But to really understand what
was on screen when the failure
occurred, I can disclose the
failure itself to reveal an
automatic screenshot which I can
preview the click icon.
And here, I can clearly see that
the remaining timer label shows
02:56 but our test assertion at
2:56.
So I'll close the preview and
we'll jump back to the test
source by clicking on the jump
arrow next to the test name.
And here, we'll fix the
assertion by adding, deleting
zero.
Now, I'll rerun just this one
test by clicking on the test
diamond next to the test name.
And again, we can see the app
being launched and new
meditation starts, few seconds
later it gets pause, the app
gets executed, and this time--
terminated, sorry, and this
time, we can actually see with
the test diamond that the test
succeeded.
That's great.
[ Applause ]
Finally, now that we have a
functional app, we would like to
make it available to more
people.
To build an app for distribution
on the App Store or TestFlight,
which is Apple's beta testing
service, we need to perform an
archive.
To do that, we first select the
generic iOS device run
destination, and then select
Product Archive.
And this builds the app in the
release configuration and
produces an archive that we can
use to distribute our app.
When it finishes, it opens the
organizer automatically, and
here, when we select the
archive, we can click Distribute
App.
And we would go through this
flow to submit our app directly
to Apple from Xcode.
Please note that to deploy apps
to TestFlight or the App Store,
you'll need to register
developer account associated
with your Apple ID.
Once your app has been uploaded,
you can manage it using the App
Store Connect website.
And this way, you can ask your
friends and family or your
colleagues to download your app
using TestFlight and eventually
getting listed-- get it listed
on the App Store as well.
So in this demo, we started by
creating unit and UI tests for
our app.
And then we learned how to edit
our test plan and how to use the
Test Report to diagnose a test
failure.
Then we built an archive and
discussed how to use the
organizer to upload our app to
TestFlight or the App Store.
To learn more about these
topics, please refer to these
talks.
And now, let's recap what we saw
in the last hour.
Today, we went through the whole
journey of creating an app from
scratch.
Prachi created our project and
introduced the Xcode UI.
Then Holly added codes to our
app using the Source Editor
features to make that process
really smooth and fun.
Then I came up to discuss
running and debugging on the
simulator and device, and we
added a Swift Package to our
project.
Then Holly came up and
integrated the Swift Package and
split some of our code into a
framework.
And finally, we just learned how
to use the testing integration
in Xcode and how to distribute
our app to the App Store or
TestFlight.
For more information about the
session, please refer to this
link.
And if you have any questions,
there's a lab starting right
after this session ends.
And have a great week.
Thank you very much.
[ Applause Cheering ]