WWDC2019 Session 418

Transcript

[ Music ]
[ Applause ]
>> Good morning, everyone.
Welcome to Getting the Most out
of Simulator.
My name is Russ Bishop.
I'm an engineer on the Simulator
and Devices team.
And let's go ahead and get
started.
Today we're going to tell you a
little bit about what the
Simulator is.
Then Tracy is going to come out
and tell you about some burning
questions and answers and
getting the most out of the
Simulator application.
I'm going to come back and tell
you about using Simulator from
the command line, and then
finally Katelyn's going to come
and tell you all about Metal in
the Simulator.
So what is Simulator?
Well, it is the best way to
simulate iOS, tvOS and watchOS
devices on your Mac.
It can be an amazing tool for
development.
Your Mac has more cores, more
memory.
You can run multiple devices in
parallel.
So it is a great tool, but as an
engineer, that explanation might
be a little bit unsatisfying.
So to talk really about what the
Simulator is at a technical
level, we need to talk a little
bit about what an operating
system is.
We have a kernel, manages
hardware resources, allocates
memory, arbitrates between
processes.
That's pretty straightforward.
macOS then on top of that has a
userspace.
We have PID 1, launchd.
We might have some daemons
running on top of that, some
services.
We have some frameworks, and
then we run our applications.
Simulator is essentially a
separate userspace.
It has its own launchd, its own
daemons, its own frameworks and
runs its own applications.
These things are all completely
separate and isolated from your
Mac's userspace.
And if I start another
Simulator, that essentially
brings up another isolated
userspace.
It's isolated not only from the
macOS userspace but also from
any other running Simulators.
So at a technical level, what a
Simulator is is the iOS, watchOS
or tvOS userspace but running on
the Mac kernel.
Has a separate launchd, separate
daemons and services, separate
notifications domains, separate
URL sessions, separate mach
bootstrap.
It does share the same
filesystem but has a separate
Home directory.
From libSystem up, everything is
built for the platform that
we're simulating, so that
includes, at the lowest layers,
you know, libSystem, all the
Syslibs all the way up to
UIKit and other frameworks.
It uses the ABI for that
platform, and it's built
natively for your Mac's
processor.
It's not an emulator.
A couple of more details to
cover.
The memory and CPU limits of
Simulator are -- or rather, the
memory and CPU limits of the
devices are not simulated, so if
your Mac has -- you have one of
the new Mac Pros and you have a
terabyte of memory, your
simulator can allocate a
terabyte of memory.
If you try that on an iPhone X,
that probably isn't going to
work.
Mac also has different number of
cores, different threading
behavior.
That can be a boon.
It can help expose data races or
other threading conditions, but
it is something to be aware of.
The application sandbox is not
enforced, so a process in the
Simulator can write outside of
its sandbox, but, again, if you
try that on the device, it's not
going to work.
However, most people's Macs are
setup with a case-insensitive
file system, but the Simulator
goes ahead and runs in a mode
where all processes are using a
case-sensitive file system
accesses.
And then the, last but not
least, the Thread Sanitizer is
supported in the Simulator,
whereas it's not supported on
devices.
So that can be a useful tool.
So now, I'm going to hand this
over to Tracy who's going to
talk about some burning
questions and answers.
Tracy?
[ Applause ]
>> Good morning.
My name is Tracy, and I work for
the Development Technologies
group.
So, you know, we often get
questions in our session and in
labs and through our user forums
and via feedback.
So we thought it might be useful
to go over the answers to some
of those questions.
So my goal is that you'll walk
away knowing at least one thing
you didn't know before about the
Simulator.
But to start off, I'd like to
talk for a bit about why the
Simulator should be important to
your workflow.
Well, if we take into
consideration all of the devices
that are compatible with iOS 13,
and then we add on all of the
other operating systems and
devices, you're looking at
literally hundreds of devices
and operating systems available
to your customers.
And that's just the iPhones and
the iPads, not even including
the Watches and the TVs.
Well, that's a lot of stuff to
be carrying around in your
backpack.
And we thought about, "Well,
what about testing with these
older operating systems?"
So I'm sure you have customers
that are using older devices and
operating systems.
So you might be thinking,
"Tracy, there's no way that I
could test all these
configurations."
Well, that might be true.
And although you may not have
all these physical devices,
through the Simulator, you will
have access to every operating
system and device available.
That makes the Simulator a very
important tool to your everyday
workflow.
All right, let's get on to those
burning questions.
Number one, can I zoom in on the
Simulator?
Yes, you can.
You can simulate the pinch
gesture by click and dragging
while holding down the Option
key.
Another gesture you can simulate
is drag and drop.
First, you grab the app.
Then you want to click down the
Control key to simulate a hold,
drag to where you want to go and
then just let go of the Hold
key.
Oh, that's a good one [laughs].
Next question.
Can I change which audio device
the Simulator uses for input and
output?
Yes, you can.
So that's done through the
hardware menu.
You can select which audio
device you want to route to.
That way you can listen to your
Apple music without
interruption.
Next question.
Does iCloud work in the
Simulator?
Yes, it does.
You can log into iCloud through
the Settings app, and then
you'll have access to all your
Calendars, Contacts and every
other app that's available
through iCloud and in the
Simulator.
You can also trigger an iCloud
sync by using the Debug menu,
Trigger iCloud Sync.
Oh, look. I have a vacation
coming up next week.
Good.
Next question.
Can I use a Shake Gesture?
Yes, you can.
In this example, a colleague
created an app that will
indicate when a shake is
received.
So you go to the Hardware menu,
and you select Shake Gesture.
You can also simulate a memory
warning by going to the Debug
menu.
Next question.
How do I get older simulators to
show up as deployment targets?
So this is all done through the
Devices and Simulator pane.
It's found under the Windows
menu, or you can use the
keyboard shortcut.
Xcode 11 now ships with a
default list of simulators,
which you may have noticed have
been pared down quite a bit.
But you can always install
additional simulators as needed.
How are we going to do that is
we're going to go to the
Simulators tab.
Next thing we're going to do is
click on the Plus button at the
bottom left.
Then you will select your device
type and what operating system
you want to use.
In this case, for the device
type, let's select the iPad mini
simulator.
Xcode 11 now ships with support
for iPad minis going back to
iPad mini 2.
So you're going to give this sim
a name, and then you click
Create.
And now your newly created
simulator target will show up.
And you can run your app to the
new iPad mini simulator.
Let's talk for a minute about
Watch sims.
So preset Watch pairs are
automatically added to the
iPhone X and the Xs Max, but you
can add a new pair by clicking
on the Plus button.
Again, you'll select your
operating system and device
type, and then you click Pair.
So to change the act of pairs,
all we do is click on the Radio
button.
You can also download older
simulator runtimes by going to
the Xcode Preferences and
selecting Components.
You can choose what you need and
then click Install.
Older simulators will install,
and then you will be able to
select them based on the
deployment target settings in
your project.
You can also get older
simulators by using the
Hardware-Device menu, and they
will just launch.
This will allow you to show
newer operating systems and
older operating systems side by
side.
You can hide simulator targets
by deselecting the Show as run
destination.
You can also delete simulator
targets if you don't want them
around anymore, and you can use
the Delete button on your
keyboard.
Or you can use the Contextual
menu, holding down the Control
key.
You can also select these other
items that are shown.
Remember, if you change your
mind, you can always add a
simulator target back again by
creating them.
All right, let's go on to the
next question.
The simulators are overtaking my
screen.
Can I make them smaller?
Yes, you can.
So there are three presets that
are available on the Simulator:
Physical Size, Point Accurate
and Pixel Accurate.
So what do these all mean?
Well, Physical Size is actually
the physical size of the device.
You can hold up your device to
the screen, and it will be the
physical size.
Point Accurate is going to be
one UIKit point will equal one
AppKit point.
And then Pixel Accurate is the
pixel-by-pixel representation
based on your monitor
resolution.
Or as some of you might know,
you can always drag, open the
Simulator and size it however
you want.
So you can size it as large as
your display.
Next question.
Can the Simulator help me debug
UI animations?
Yes, it can.
So that's done through the Slow
Animations under the Debug menu.
Once this is toggled and you
select any app, it will go very
slowly, slowing down the UI
animations.
Next question.
Is Siri available in the
Simulator?
Yes, it is.
As long as you give the
Simulator access to your
microphone, you can invoke Siri
on all Simulator platforms.
Additionally, you can find Siri
in the hardware menu, or you can
use the keyboard shortcuts.
Next question.
How do I control my tvOS
Simulator?
Well, there's a few different
ways you can do this.
One is you can use the Apple TV
software Remote.
So that's located under the
Hardware menu.
Click on it.
And to activate the area, you
just hold down the Option key
while you move the cursor
around.
Another way is you can actually
use the hardware Apple TV
Remote.
You pair it holding down the
Plus and the Menu button on your
remote, and then once it's
paired, you'll be able to use
the hardware Apple TV Remote on
your tvOS Simulator.
You can also use game
controllers, and for simple
navigation, just use the
keyboard.
Next question.
Can I use Xcode 10 with iOS 13
Simulators?
Yes, you can.
So as long as you have Xcode 10
running on the same system as
Xcode 11-Beta, first thing you
want to do is launch Xcode 11
and then also launch a
Simulator.
So that'll give you an iOS 13
runtime.
Then you close down Xcode, but
you leave the Simulator.app
open.
Then you'll go into the older
Xcode 10, bring it up, and then
you can build and run to the
Simulator.
Let me show you how that's done.
So this is we're running Xcode
10.
So what we're going to do is
we're going to select the iOS
12.2 Sim, run our app to that.
And then we're going to change
over to the iOS 13 Sim, and
we're going to run our app to
that.
Now you can look at the older
and the newer side by side.
Oh, yay. That got a clap
[laughs].
Next question.
Can I copy content into my
Simulator?
There's a couple different ways
to copy content.
One of the ways is through drag
and drop.
So through drag and drop, you
can copy app bundles, locations,
photos and videos and URLs.
So in this example, I can take
my project, grab my app bundle,
just drag and drop it onto the
Simulator.
It will install, and I can run
it.
In this example, we're going to
take some photos and videos.
So I grab them all, and I can
just drag and drop them right
into the Simulator, and they
will automatically go into the
Photos app.
Oh, wait. I drug in four, and I
only got three.
Oh.
That's because the photo and
video file are recombined to
give you a live photo.
Drag and dropping URLs is
simple.
Just open up Safari, grab the
URL, drag and drop it.
And from within Safari, you can
also use a Safari Share Sheet.
The Simulator is a target under
the Safari Share Sheet.
Just select it.
It'll bring up a dialog.
You can select one simulator, or
you can go to all simulators at
the same time.
Also, you can share location via
the Share Sheet.
At the Maps app, you got a
location.
Just click the Simulator, select
your target, and then it will
share that location with the
Sim.
OK, let's go over some other
helpful hints that you might not
have known.
Under the Hardware menu, there
is the Rotate Device
Automatically.
So if you toggle this setting,
it will honor the settings in
your project, and it will rotate
the Sim automatically.
We have a few presets for
simulator locations in the Sim.
One is like a freeway drive, so
you can simulate a freeway
drive.
You can also input your own
custom location by putting in
the longitude and the latitude.
If you want to see what your app
will look like when a call is
received, you can use the Toggle
In-Call Status, or you can use
the keyboard shortcut Command-Y.
External displays can be used
for a variety of content.
In this example, what we're
doing is we're playing some
video out of Safari, and we're
selecting a couple of different
display resolutions.
Dark mode is also available on
the Simulator.
You'll find that under the
Developer menu.
Just go under Settings, toggle
down to Developer, and you can
click on Dark Appearance.
You can also change the
wallpaper in your Sim if you
want to.
You can just drag a photo into
your Photos app.
Then click on the photo.
Use the Share Sheet, and that'll
bring it up just like it does on
the iOS device.
Select it as the wallpaper, and
the Simulator will also use this
as a wallpaper for your
background, for the lock screen,
and now you have a new
background.
Dictation also works in the Sim.
So that's found under the
Settings app.
You'll go under the keyboard,
and there is an Enable
Dictation.
So once you have that toggled
on, you just bring up an app
that accepts keyboard input.
Use Command-K to bring up the
software keyboard, and then
you'll see the microphone down
there, and you just start
dictating.
Input language can also be
changed if you didn't know that.
So you can go into the keyboard,
select what input language you
would like.
There's a variety of languages
in there available.
And then again, you're just
going to bring up the software
keyboard.
And you're going to click on the
globe just like you do on your
iOS device.
And speaking of keyboards, the
new QuickPath is also supported
in the Simulator.
Just open up the keyboard, start
your path, and there you go.
You can find more information
also by using the Simulator Help
menu.
Type in what you need, and also
the Search feature will just
point you right where you need
to go.
Well, my time is just about up,
so I hope you learned at least
one thing you didn't know before
about the Simulator.
Now I'm going to turn it over to
Russ who's going to go over
running the Simulator through
the command line.
Thank you.
[ Applause ]
>> Thank you, Tracy.
So let's talk a little bit about
Simulator from the command line.
If I can leave you with one
thing today, it'd be xcrun sim
control or simctl.
But if I could leave you with
two things today, it would be
xcrun simctl help.
Sim control has extensive help.
If you run it without a command,
it will tell you all of the
commands that are available.
If you run help and then the
command name, it will give you a
lot more detail about that
specific command.
So I'm going to cover a few
commands that may be useful to
you and then talk briefly about
a few others, and then we'll do
a little demo.
So the first command, the most
basic command, is the list
command.
This will show you the device
types, runtimes, devices that
you have.
I've shortened this list to fit
on a slide.
You'll probably see quite a few
more on your own machine.
We can see here that we have the
device types, both their short
names and their identifiers, the
runtimes, short names and
identifiers, my device, its
identifier and then the current
state, which is Shutdown.
Most of the commands that
accept, for example, a device
type or a runtime will accept
the name, the short name.
It's totally fine to use that
when you're typing at the
terminal, save you a few
keystrokes.
But I do recommend for
automation and scripting that
you go with the full identifier
just to be specific.
The list command accepts a
couple of different categories,
one of which is devices.
So in this case, I'm not looking
for the runtimes or the devices
types.
I just want the devices.
I can specify that, and I can
give a search string as well.
So in this case, I'm just
looking at my iPhone X devices.
So list command also has a json
flag.
This will output a
machine-readable json file that
you can use for automation
purposes.
The next command I want to talk
about is create command.
Some of you may have heard we
have standalone Watch app
support this year.
So I think I would like a
standalone Watch simulator that
I can deploy to.
So I'm going to call this Test
Watch, and I'm going to specify
the device that I would like, a
Series 4 - 44mm.
And I would like that to be
running watchOS 6.0.
The output will be the
identifier of the device.
This is so I can capture that in
an environment variable or use
it for scripting purposes.
In this little example, I set
NEW DEVICE to that value, and
then, look the bot echoed the
identifier, the device that was
created.
Most Sim control commands follow
the UNIX convention.
On success, they exit with zero.
On a failure, they exit with a
non-zero code.
Errors are printed to standard
error, and then actual output
such as a device identifier or
the json is output to standard
out.
The next command I want to talk
about is the spawn command.
The spawn command will pause
xspawn a process inside the
simulated environment.
And you might think, "What use
is that?"
Well, we ship a couple of
utilities in the Simulator that
might be useful to you.
In this case, the default
utility.
So I'm going to specify the
device that I want to target.
In this case, I'm going to use
the alias booted, because I have
one booted simulator, so I don't
need to actually specify which
one it is.
And I'm going to say defaults
write, the bundle ID of my
application.
I want to set the ResetDatabase
key to YES.
So this can be a handy way to
change the user defaults for
your application before it's
running.
I can also run the log stream
utility.
If you haven't seen this before
or haven't run this on your Mac,
you can pass a predicate, and
you can stream the log output.
Well, you can do the same thing
with the Simulator.
In this case, I'm going to say
that the predicate is
senderImagePath CONTAINS
nsurlsessiond, because I want to
debug something that's going
wrong with my URL sessions.
And then I can see the log
stream output.
You may notice sim control has
detected that I'm using an
interactive terminal that
supports color.
It's passed that information
through, so log stream is giving
me some nice pretty colorized
output.
And here I can see my
dataTaskWithRequest
allowsCellularAccess is set to
1.
That's what I expected, so I'm
happy.
Speaking of logs, the next
command I want to talk to you
about is diagnose.
This is an incredibly useful
command.
The diagnose command will go
through and collect not just
logs on disk, but ephemeral
logging and dump system state
that can be useful in tracking
down a problem.
This a great thing to run in
automated systems if you have a
test failure or some kind of
issue immediately capture
diagnose, control diagnose.
This is also great if you're
filing bugs.
So in an automated scenario, I'm
going to pass the -l flag to
skip the privacy warning.
But I do recommend that you read
that before you use this command
and also check out Apple's
privacy policy.
This will tell you the types of
information that this will
collect, could include account
names and things like that.
The diagnose can run.
It'll tell me where it wrote the
file to.
If I'm using this at my desk, I
would also get a Finder window
that pops up, that shows me the
file it produced.
So, please, if you're going to
send in feedback through the new
Feedback Assistant with issues
occurring the Simulator, attach
a sim control diagnose.
That makes it much easier to
figure out what went wrong.
And I do recommend you use it in
your own workflows if you're
going to send a bug to-- For
example, if you're working in
QA, you're going to send a bug
to the engineer.
Hey, the app-- something went
wrong.
Attach a diagnose.
That'll include all the log
output from your application.
The next command that I want to
tell you about is launch
command.
Launch command launches an
application.
You might ask, "Well, what is
difference between that and
spawn?"
Well, launch politely asks the
system, "Would you please start
the application with this bundle
ID?"
This is equivalent to tapping on
the icon on the Home screen.
And in fact, this is the only
way a process can display
information on the screen on
iOS, watchOS or tvOS.
So it's incredibly important.
So if you actually want to
launch an installed application,
you'd need to use the launch
command.
So I'm going to specify again
the booted alias, because I only
have one simulator that's
booted.
I'm going to launch my
com.apple.example application,
and I'm going to pass some
arguments.
If you haven't seen this before,
user defaults allows you to
override defaults that you've
set as arguments from the
command line.
Prefix the key with a single
dash, the key name and then
specify the value.
And for that specific launch of
my application, the
-MyDefaultKey will be set to YES
regardless of what's stored on
disk.
The launch can do something else
very interesting for me.
If I pass the -- console-pty
flag, launch will connect my
application's standard input,
output and standard error to the
terminal I'm working with right
now.
So when I launch this
application, I see its standard
output right there in my
terminal.
And more than that, I can hook
up debugging facilities.
In this example, I press Enter,
and it's going to dump some
debugging state.
So in Terminal, I can press
Enter, and I get that debugging
state printed from the
application.
This can be a real useful tool
when you're debugging.
The other thing you might notice
is I press Control-C, which
sends an interrupt signal.
Sim control detects that, grabs
the signal and passes it through
to the application.
That applies not just to signals
like interrupt, but user
signals: user1, user2.
Those are other ways you can set
up your application to include
debugging information.
So there's a couple more
commands that I don't have time
to go into, but I'm just going
to briefly give you an overview.
Boot as you might expect boots a
device.
Shutdown also pretty obvious; it
shuts down the device.
But shutdown accepts a special
alias.
The all alias-- That will just
shut down all running
simulators.
Delete, again-- as you might
expect-- it deletes a device.
But there's another convenient
alias that it accepts--
unavailable.
That will go through and find
all of the simulators that use a
runtime that's not available to
you anymore.
Maybe it's an older version of
Xcode that you've upgraded or
it's a downloaded Simulator
runtime-- like Tracy showed
you-- that you've deleted.
That will go through and clean
all these up and recover that
disk space.
The next one, pair.
There's pair and also an
associated unpair and pair
activate.
You can set up watch phone
pairings from the command line.
Addmedia-- that's similar to
what Tracy showed you earlier
dragging, dropping photo and
media into the Simulator.
You can script that as well.
Get app container is an
interesting one.
If something's going wrong with
your app.
Perhaps it's writing a corrupted
file or it's attempting to load
something, and you know it
should be there, but it's not
there, get app container can
give you the path on disk to
your application's data
container or even to a shared
container that perhaps your app
and your app's extension are
using.
And you can go then examine the
actual content, the filesystem
from Finder or from Terminal and
see what's going wrong.
Install. Again, that's very
similar to what Tracy showed you
with dragging dropping app
bundle.
You can install an application
from the command line.
And then the last one I want to
mention is the io command.
Io itself has several
subcommands, probably the most
important of which is
screenshot.
So that allows you to automate
taking of screenshots in
Simulator.
And then the last command I want
to talk about is the clone
command.
Clone is a very powerful command
that can be used for automation,
for testing, for making
experiments.
Clone allows you to set up a
single simulator exactly how you
want, install your app, set user
defaults, load data.
Then you can shut that simulator
down and then make as many
copies of it as you want.
Then you can run those copies,
perform your experiments and
then throw them away when you're
done.
This can be a great timesaver
and saves a lot of disk space
because clone takes advantage of
APSF file cloning under the
covers.
If your game has a
gigabyte worth of assets and you
want to run multiple tests in
parallel, you can go ahead and
do that without taking up a
bunch of disk space.
So rather than talk more about
that, I'm going to show you with
a demo.
OK.
So the first thing that I'm
going to do is I'm going to go
ahead and start the simulator
that I'm going to use as my sort
of baseline for comparison.
So I'm going to start that
simulator.
You can see I have the Simulator
app open, so it automatically
attaches to it.
The next thing I'm going to do
is install my application.
I have my application bundle
here and ready to go.
So like I showed you earlier,
I'm going to run install, booted
in that application.
Well, see, it appeared on the
Home screen, and it's now
installed.
So the next thing I'm going to
go ahead and do is shut this
simulator down.
We do need to shut it down
before we can clone it.
And then once I've shut it down,
I'm going to go ahead and create
a clone called clone-1.
And now I'm going to run this
command again.
I'm going to create another
clone, clone-2.
Now that I have these two clone
simulators, I'm going to go
ahead and ask them to boot.
And here we can see that both of
them are starting up.
They started up much more
quickly, because I don't have to
pay the first boot cost.
I already paid that cost with
the base simulator when I set it
up.
So that can be a great
timesaver.
And then here's what I could set
up things in place for my demos
or my experiments that I want to
run, and then I would launch the
application on both of these
simulators.
Now, some of you may actually
recognize this code.
This is the Metal
DeferredLighting demo.
This is something that we
weren't able to run in previous
years.
This is new to Xcode 11 when
running on macOS Catalina.
And to tell you all about Metal
in the Simulator, I'm going to
invite Katelyn out.
Katelyn?
[ Applause ]
>> Thank you.
Thank you, Russ.
Good morning.
I'm Katelyn Hicks, and I'm an
engineer on the GPU Software
team.
And today, I'm excited to tell
you about the new Metal support
in Simulator.
So let's dive in to see how to
get the most out of Metal in
Simulator.
While running on macOS Catalina
and Xcode 11, Simulator now
supports Metal.
But what does that mean for your
application?
Well, two things.
Simulator is fully GPU
accelerated for all
applications.
And second, the Metal API is now
available to use in Simulator.
So let's take a look at how fast
Simulator is while running on
macOS Catalina and Xcode 11.
We'll quickly go through a few
applications to see that, across
the system, animations are much
smoother, and user experience is
more responsive.
This is due to the fact that
Apple frameworks have migrated
to Metal renderers and are now
taking advantage of the GPU.
So if your application is not
using Metal, but instead you're
using an Apple framework for UI
2D or 3D graphics, you will
still get the performance
improvements of GPU
acceleration.
There are no changes necessary
for your application to achieve
GPU acceleration through Metal.
This speedup is free.
Now, I'd like to show you a few
examples.
So on the left, we have a device
that is running on the software
renderer.
And on the right, we have the
newly GPU accelerated simulator.
In this simple graphics
workload, we can see the
improved performance through
scrolling through this Table
View that uses UIKit.
Since the original Simulator, an
iOS device's resolution has
increased 17 times, which has
put extra pressure on the
underlying software renderer.
In this SpriteKit Xcode
template, we see the performance
dipped down to 15 frames per
second in the software renderer,
whereas we're rendering the same
application in Xcode 11 and
macOS Catalina, and we see a
steady 60 frames per second with
more SpriteKit nodes rendering
in the scene.
For more complex 3D scenes like
this Fox demo that uses
SceneKit, we see a dramatic
performance improvement without
any changes to the Fox
application source.
And now it is possible to run
multiple simulator devices in
parallel with real-time
performance.
In this Badger demo, which also
uses SceneKit, the geometry and
animation was previously too
strenuous for a single software
rendered GL simulator device,
let alone two running in
parallel.
For those of you that use Metal
directly, Metal development is
now possible, and the workload
is fully accelerated.
Let's see how your experience
has changed while running your
application in Simulator.
So previously, you may have seen
a black screen.
But now when you run your
application in Simulator, you'll
be able to run your application
across all simulated devices.
Now that you've seen it in
action, let's dive into more
details.
If you've seen our other Metal
session, you know that this year
we have revamped our feature
query API and have introduced
the Metal GPU Family API.
The Metal GPU Family API makes
writing cross platform code
simpler by abstracting GPU
capabilities into a few distinct
tiers, and the three families
that are relevant to Simulator
are first common, which includes
all GPU features that are
available cross platform.
And second, macOS, which in
includes the features that are
specific to macOS GPU hardware.
And third, Apple, which includes
the features that are specific
to iOS and tvOS GPU hardware.
So while running your
application in Simulator, your
application can use features
from MTLGPUFamilyApple2, which
includes features that are
included in MTLGPUFamilyCommon1
as well.
This support is common for all
Simulator devices.
So let's take a look how it is
possible to run your iOS
application in Simulator.
Previously, your application
rendered on an OpenGL ES
software renderer for all
applications, and it had no GPU
hardware acceleration.
But now in Xcode 11 and macOS
Catalina, the great news is the
Metal API is available to use in
Simulator.
And all of the Apple frameworks
are now using Metal as well.
But not only it is available,
it's GPU-accelerated.
So this means that all commands
that are created by your iOS
application for UI 2D or 3D
graphics are all being
translated from iOS Metal to
macOS Metal.
And this translation allows you
to take advantage of the
underlying Mac GPU on your
system.
But this does come with a few
caveats and one of them being
the performance you see may be
different from the actual
device.
So the graphics you see will be
the performance of your
underlying Mac GPU.
And the Simulator device is not
a true iOS GPU emulator.
So if you run an iPhone success
simulator on your incredibly
fast Mac Pro, the performance
you see will be different from
running your application on an
actual success device.
So as always, make sure to
profile and optimize your
application directly on devices
before shipping your
application.
One other thing you need to take
into mind is the fact that there
are different storage modes
across macOS and iOS.
iOS has support for private,
shared and memoryless textures,
whereas Mac has support for
private and managed textures.
And while the native macOS
device does not support shared
and memoryless textures, they
are supported in Simulator.
There are a few other special
cases with shared storage, but
first let's revisit how shared
storage works.
So when you create an iOS
texture with Shared Storage
mode, this means that your
texture can be modified both on
the CPU and on the GPU.
And so if your application
wanted to initialize this
texture on the CPU, then bind
your texture to a render or
compute encoder to be read on
the GPU.
You could directly modify this
same texture on the GPU and then
read back those modifications on
the CPU after the command buffer
completes.
And your app does not have to
worry about any memory
synchronization as on iOS it's a
unified memory model.
And so in Simulator, for
multisampled, depth stencil and
linear textures, these texture
types must be created in private
storage, whereas on an actual
iOS device, these types may be
in shared storage.
And so your app may need a
simulator-only path if you need
CPU access to these textures.
For most of you, you will
initialize these texture types
and use them directly in your
GPU commands, and so this won't
affect your application.
They should already be private
textures.
But if you do need CPU access
for one of these textures, let's
go through what changes may be
required.
So as a reminder, if you create
a texture in private memory, the
texture does not have CPU
access.
It only can be modified by the
GPU and read by the GPU.
So if your app reads or writes
to the texture on the CPU, you
need an intermediate shared
resource to do so.
So first we can either create a
shared buffer or a shared
texture.
Then in order to copy this
texture, you create a
BlitCommandEncoder, and you can
copy from the shared buffer in
this case to the private
texture.
Or you can copy from the private
texture to the shared buffer.
So let's take a look at what
this looks like in source code.
So in this code example, we see
that a depth stencil texture is
created, and we want to
initialize it on the CPU.
So first, we set the storage
mode to private only in
Simulator.
While we're not in a simulated
environment, we want to still
use a shared storage mode.
Then we create the texture with
the modified textureDescriptor.
And then while in the simulated
environment, in order to
initialize this private texture,
we will first create a shared
buffer.
For this shared buffer, we will
initialize it on the CPU with
the data that you'd like to see
in your private texture.
And finally, we blit from that
shared resource to the private
texture.
And then in the case that you're
still running on an actual iOS
device, we want to do the exact
same thing you did before and
initialize that texture on the
CPU and avoid this unnecessary
blit.
From this point forward, the use
of this texture is the exact
same, whether you're running on
an actual iOS device or in the
Simulator.
All of your GPU commands can be
the exact same.
And so there are a few other
changes that may be needed for
your application in Simulator,
and for that we have full
documentation for those small
changes.
And we also have a sample code
available for you to download
and to see example of porting an
application to Simulator.
I hope you learned something new
about Simulator today.
We first went over that the iOS,
watchOS and tvOS userspace is
running on the macOS kernel and
that the Simulator is pivotal to
testing your application across
all devices and runtimes.
We saw the power of xcrun simctl
and how you can script all of
your testing through Simulator.
And lastly, we saw that the GPU
acceleration through Metal in
Simulator is for everyone, and
it also enables Metal
development in the Simulator.
And if you have any other
questions, please visit the
session website.
Thank you, and I hope a great
rest of your week.
[ Applause ]