Transcript
[ Music ]
>> [Applause] All right.
Good morning.
Thank you for attending this
session.
My name is Kulpreet.
I'm a Software Engineer in
Localization and I'll be joined
by my colleagues Vivian and
Arthur.
In this session, I'll be going
over some exciting new
localization features in our
platforms.
Vivian and Arthur will then
touch on some new tooling in
Xcode 11, including some great
enhancements to localization
workflows, localizing images,
and how you can use testing to
generate screenshots of your app
in any language.
Today, we estimate over 70% of
our users are outside the United
States.
Localization is an opportunity
for you to expand your reach and
capture new markets with your
app.
At Apple, we care deeply about
creating a great experience for
all of our users around the
world.
This year, we have a host of new
features and improvements for
our Multilingual and
International Users.
To name a few, in iOS 13 we have
keyboards for 38 new languages.
I'm sure if your language is up
there you're really excited.
We also have a new setup flow
that guides multilingual users
to the right language settings.
Now one of these features I'm
particularly excited about, and
I want to dive a bit deeper with
you.
In iOS 13 there's a new setting
that appears from Multilingual
Users in your app settings page.
I'm happy to say that users can
now set the language of your app
independent of the system
language.
[ Applause ]
If a user has a connected watch,
the setting will also sync to
the accompanying watch
application.
And similarly, on macOS, users
can set the language of an app
via Language and Region
preferences.
This is important because in
multilingual regions, users may
prefer to use different
languages in different context.
In a region like Hong Kong,
someone might read their news in
Chinese even though they do
their banking in English.
In India, a student will go to
school and learn in English even
though they come home and speak
Hindi with their family.
Apps are windows into these
interactions we have everyday.
And this new setting allows
users to choose a language that
reflects their preference for
your app.
Now this works for your app out
of the box and for free if
you're using all of our standard
foundation APIs for
localization.
But there are couple things to
keep in mind to make this work
great for your users.
First, do not attempt to set the
application language manually in
code.
Our APIs do a lot of work to
ensure users get the right
language and font fall backs.
If you do need to add the option
within your app to switch
languages, we recommend you
Launch into Settings where users
can go in and switch the
language of your app.
Next, when the user does change
the language of your app, your
app will be relaunched in the
target language.
Now, to make this language
change a seamless experience for
the user, we recommend you adapt
state restoration APIs.
In iOS 13, there are some new
state restoration APIs with
NSUserActivity.
To learn more about how you can
use them, you can check out this
talk on Friday.
And, finally, it's important
that all of your content is
shown consistently in one
language throughout your app.
If you're doing some custom or
server-side resource loading,
there are handful of APIs that
might be useful for you to
determine which language to
request that content here.
Let's go over a few of them.
Locale APIs are useful for
fetching the user's Language and
Region preferences.
Locale that preferred languages
returns a list of languages in
order of user preference.
Now, this list might be useful
to you if maybe you're building
an app that needs to handle
multilingual content, and you
need to fetch resources such as
font for all of the user's
languages.
And one thing to know is that
locale, that preferred languages
will return the language list,
that user's preferred languages,
regardless of the languages your
application bundle supports.
So it's not useful for getting
the current running application
language.
To get the current running
application language, we can use
Bundle APIs.
And Bundle APIs are useful for
language matching.
Bundle.main.preferred
Localizations considers both the
user preferred languages and the
languages that your application
bundle supports and returns a
list of languages your
application Bundle supports in
order of user preference.
Now, if you have an external
list, say if you're loading some
remote content from a server and
your server has a different
setup supported languages, you
can use the class method
Bundle.preferredLocalizations
from.
And this will also consider that
third language from your server.
Now, to help walk you through
this feature and what it means
for your apps, I'd love to jump
in to a demo.
[ Applause ]
OK. So, last year, we demo'd
Vacation Planet.
The first Interplanetary Travel
Booking app, and we've since
expanded the app to be able to
book complete travel
experiences.
We had this new Discover tab
with the collection view that
shows some of our great
offerings in these thumbnails
like this romantic space cruise
to Pluto or Moon Yoga.
Now, some of these are seasonal
offerings like this WWDC
Afterparty.
And because this is seasonal
offering this content is
actually pulled from our server.
So this image and this great
description about how this is
the first Interstellar Bash and
how we're going to be going on a
onboard-- we're going to be
going on a ship with an onboard
seafood restaurant, the Codable,
is actually being pulled from
our server.
Now, after reading that
description, I think this looks
great and I'm ready to book.
But as you know, WWDC attendees
has come from all around the
world and they might prefer to
do their travel booking in a
different language.
So, what I'm going to do is I'm
going to go down to the profile
tab where we have a table view
cell that shows the current
running application language.
And when I click on that, it's
going to pop me right into
Settings where I can click in to
see a list of all the languages
my application supports.
I'm going to go ahead and change
this to French.
And when I go back, you can see
that the System UI is still in
English but when I go back to
Vacation Planet, the app will
relaunch and it'll be in French.
[ Applause ]
Now, one thing you'll notice is
that it actually brought me
right back to where I left it
and that's because I've adapted
those state restoration APIs.
And you can see now all of our
strings and all of our date
formatters are in French which
is great.
But when I go to that server
side loaded content, I can see
that that is still in English.
Now that seems problematic
because we want to be consistent
in our app and we want their app
to be in one language.
So, let's take a look of what
might be going on there.
So, I'm here in our Collection
View Controller and I have this
method Local Discover Items that
downloads that content from the
server.
And when we download that
content, we actually need to
pass in a language because the
server needs to know what
language are we fetching that
content in.
And here you can see that the
language I'm passing in is
Locale.preferredLanguages.first.
As I mentioned before,
Locale.preferredLanguages going
to return the users preferred
languages regardless of the
language that my application
supports.
And so, this could be something
like Persian that my application
doesn't necessarily support.
Now, ideally, I'd like something
that I'll consider the server
support languages, my
application bundle supported
languages, in order of the
user's preferences.
So, I'm going to start by
fetching the server's supported
languages.
You can see that here.
And then I'm going to use that
Bundle API, that class method on
Bundle.preferredLocalizations
from, and I'll pass in the
availableServerLocalizations.
And now the first element of
this will be the best language
to request that content and from
the server.
So I went ahead and I rebuilt.
And wait a couple of seconds for
it to relaunch.
And you can see now that image
and all of that content is in
French.
Isn't that great [applause]?
Cool, so, I'm ready to book and
I can't wait to see you guys all
at this Interstellar Bash.
All right.
So, to summarize, App Language
Setting allows users to choose a
language for your app.
Launching to Settings is the
best way to allow your users to
switch the language of your app.
Use state restoration to make
that language switch a seamless
experience for the user.
And, finally, if you're doing
some custom or server-side
resource loading, be sure you're
using the right bundle or locale
API for your use case.
I'm incredibly excited for all
of the great features and
enhancements we've worked on
this year and can't wait to see
how you're going to bring your
apps to an international
audience.
Now to tell you how we've made
it easier for you to do just
that, I'd like to call up
Vivian.
Vivian?
[ Applause ]
>> Thanks Kulpreet.
So, let's talk about some of the
enhancements that localization
tooling in Xcode.
And this year, we've done a lot
of things you've been asking
for, so this is going to read a
little like a wish list.
First up, performance.
So, I'm very excited to announce
that exporting projects with
lots of Interface Builder files
for localization is now on
average, 15 times faster.
[ Applause ]
So, this means if you had a
project that was taking about a
minute, that's going to be down
to four seconds.
And we did this by redesigning
the string extraction process,
so the more Interface Builder
files you have, the bigger an
improvement you're going to see.
Also to really speed up and
streamline your workflow, don't
bother with calling genstrings
or ibtool directly, instead use
xcodebuild, exportlocalizations,
and importlocalizations to take
care of creating all of your
strings files.
Next up. iPad apps for Mac, so
you may be really excited about
bringing your iPad apps to Mac,
but maybe you have some strings
that wouldn't make sense, and
maybe something it says, tap
here but the user would now be
using a mouse with a cursor,
maybe clicking, or here in news,
you can control Siri's
suggestions in Settings, if
you're on the iPad, but that
would be the apps preferences on
a Mac.
And, of course, you want to have
that one NSLocalizedString
called it's already in code.
So, to help with this, we're
introducing a new stringsdict
rule for device-specific
strings.
And this rule can be combined
with the plural and variable
width rules.
So, you can use this for any of
your existing strings even if
they're already in a stringsdict
file.
So, the new rule is
NSStringDeviceSpecificRuleType
and the supported device keys
are apppletv, applewatch, ipad,
iphone, ipod and mac.
So, it's not just for iPad apps
on Mac.
And your stringsdict will look
something like this, at the top,
your existing string key then
the new rule
NSStringDeviceSpecificRuleType
and inside a dictionary, with
all of your device specific
strings index by those device
keys.
For more on iPad apps for Mac,
please check out the session
Taking iPad Apps For Mac to the
Next Level.
Next up. Settings bundle.
Settings Bundles are now
included in your Xcode
Localization Catalogs.
So these are as easy to localize
as anything else in your
project.
And one of the more significant
improvements we made to the
localization tooling in Xcode is
in how you localize Assets.
So until now, in order to
localize an image it needed to
be an independent file in your
project and this may have meant
you had some files in your Asset
Catalog and the localized ones
floating around lose.
So I'm very excited to announce
that starting now you can
localize images directly in your
Asset Catalog.
[ Applause ]
So, this means you can now
localize your image sets, watch
complications, Apple TV image
stacks, Sprite atlases, Game
Center dashboards and
leaderboards, as well as the new
symbol sets.
So, let's take a look how you do
that.
In the Asset Catalog Editor when
you select a supported type in
the Attribute Inspector, you'll
now find a localized button.
Click that and we add the
localized of our attribute to
the content so adjacent to that
asset, you're ready to export an
Xcode Localization Catalog.
But, say that you're
multilingual and doing some of
the localization work yourself
or maybe you're moving already
localized images into the Asset
Catalog, well, when you click
that button, it's going to
reveal check boxes with all of
the localizations already in
your project.
Check any of those, and it will
create the wells in the Asset
Catalog Editor, so you can drag
in the localized images like you
would any other asset.
Now, what about those new
symbols?
Well, SF system symbols are
localized for you, you don't
need to do any extra work.
Custom symbols can also be
localized.
You can either set the
directionality, if you just need
them to flip for right-to-left
languages like Arabic and
Hebrew, or you can do a full
localization cycle in the same
workflow as images.
You'll find the same localized
button in the Attribute
Inspector.
For more on symbols, please
check out the session
Introducing SF Symbols later
today.
And with that I'd like to show
you all this live in the demo.
[ Applause ]
Now, you may have notice in
Kulpreet's demo that we had not
localized the rest of these
images, so I'm going to do that
now.
If I go into Xcode, I can go to
my asset catalog and let's fix
up this nice yoga image.
It's a very nice yoga retreat on
the moon where you can feel
lighter, mentally and
physically.
So, I just go over to the
Attribute Inspector, click
localized, save, and that one is
ready to go.
I've already done this for my
other vacation packages but I
have one image that's already
localized and I want to move
into my Asset Catalog to take
advantage of all the great
features of Asset Catalogs like
being able to specify a
different appearance for Dark
mode.
This is super easy, I just grab
my old image and drag in to the
Asset Catalog.
Xcode has created a new image
set with the same name as my old
resource.
So I don't even need to go make
a change in my storyboard, it
will just work.
Now, I want to bring my
localizations along too, so I
click localized, check off the
existing language and I'll drag
that one into place, and save.
And I can just delete the old
one, from my project and on
disk.
OK, so everything is ready.
I can now export an Xcode
Localization Catalog.
This is the same workflow as
Xcode 10.
I select the project, go to
Editor, export for localization.
And let's just do French for
now, I don't need the rest of
these.
OK, export.
Let's see what we got.
OK, here is my Xcode
Localization Catalog and I can
just send this off to my
localizers and I'll find my
localizer.
I'm going to pop this open and I
know I can dive right into
Localize Contents and get to
work.
So, what do we got here, OK,
here is the xliff, I know what
to do with that, I know it has
all the strings for the project
but what else is here?
OK, we have an Asset Catalog.
And this is a fully formed Asset
Catalog.
I could go drag this into
another Xcode project and use
it.
But this one has been filtered
down to only what the localizer
cares about.
So, it's only the localizable
content and only for this
locale.
Now, in this case, we don't have
any French images yet, so
[inaudible] on here, it's just
the copy of the English.
This is for the convenience with
the localizer.
They can just jump in, start
editing.
Save time, I've had some
localizers do exactly that for
me.
So, let's see what they sent
back.
Just go open the catalog in my
favorite localization tool here.
And we can see side-by-side the
English and French versions of
all images there is yoga, yup.
OK. Let's import this into the
project, go back to Xcode, again
same workflow as Xcode 10,
select the project, go to
Editor, import localizations,
select that finished Xcode
Localization Catalog and click
Import, great.
So, now, I have to go to my
asset catalog, I can see, I now
have two versions of my image in
here all in one place.
[ Applause ]
But, it's kind of small, so
let's run the app again, so we
can see that a little bigger.
So, this time when we go back to
the app, we should see all of
our vacation packages now with
the French titles.
There we go, beautiful.
[ Applause ]
OK. Let's go back to the slides.
So, we just saw some of the
enhancements to localization
tooling in Xcode.
Export and import of interface
Builder files is now a lot
faster.
There's a new stringsdict rule
for device-specific strings.
Settings Bundle is now easy to
localize.
And symbols and images are
localizable in Asset Catalogs.
Now, of course, once you've
localize your app you're going
to want to test all of those
localizations.
And we've made that easier too.
And I'd like to call up Arthur
to tell you all about it.
[Applause]
>> Thanks, Vivian.
Now, let's take a look at how
you can take advantage of UI
testing for localization.
Testing is a significant part of
any development cycle.
It takes time and resources but
it's very important to help
catch regressions as you add new
features and detect bugs before
you release your product to your
customers.
If your app support more than
one language you will have to
test full language specific
issues.
Clip strings, truncated content,
overlapping layouts or even
issues specific to right-to-left
languages such as Hebrew,
Arabic.
Now, if you want to test for
every device you support, in
every language you support, your
test metrics can repeat and
explore.
You can easily end up with
thousands of different
scenarios.
And that will make it really
difficult for your testers to
cover all these scenarios
manually.
So, it's even more important to
include test in your project to
help produce manual work load
for your QA.
In Xcode 11, we made it easier
for you to cover all of this
test automatically with test
plans.
[ Applause ]
Test plan is a very easy way to
run the same tests multiple
times using different
configurations.
I'm not going to go too much
into details about test plans
today.
So please check out the Testing
in Xcode session on Thursday
morning to learn more about it.
What we will be covering is how
you can use test plans in your
localization workflow.
So, first, we will see how you
can make sure that your test
localization friendly, then
we'll talk about how you can use
test plans to generate localized
screenshots.
And, finally, we will go over
some of the many use cases for
those screenshots, because
they're not only good for
testing.
First, let's see how we can make
sure that your test can work in
every language you run them in.
To do so, you should rely on
Accessibility Identifiers.
These identifiers are unique,
stable, and we'll guarantee that
your test can run in any
language.
You can easily set them up,
setting the property of the same
name in code or if you're using
interface Builder to create your
UI element, you can define them
right there in the Identity
Inspector, and that's all it
takes.
So, now, that your test are
localization friendly, let's see
how we can use them to Generate
Localized Screenshots.
As I mentioned earlier in your
test plan you can create
multiple configuration.
In each of this configuration
you can set a different language
and a different region to run
your testing.
Then by simply turning on the
Localization Screenshots option
in the UI testing section, your
screenshots will be persisted
and there's so much you can do
with them.
Well, some of this option
available in the Scheme Editor
that we already-- you already
know and use in case you haven't
market it to test plans yet.
And now that your tests are set
up to capture Localized
Screenshots, let's see what we
can do with them.
They're actually a great
marketing resource.
You can pass them along to your
marketing team or even upload
them to the App Store to
showcase your latest design.
You can use them in your
documentation or in your
tutorials.
But more importantly they can
help your localizers get the
context they need to provide you
with high quality localization.
Let's take a quick example.
A simple word like Start in
English could either be a verb
meaning to begin or it could be
a noun and referred to the
beginning of an event.
While this difference might seem
really subtle in English, it can
lead to widely different
localizations in other
languages.
Here, we can see it's a noun
because it's labeling the
starting date.
Giving this visual context to
your localizers we'll alleviate
the ambiguity and make sure that
you get the most accurate
localization.
Last year, we introduced the
Xcode Localization Catalog.
It's a very common way to handle
localizing both strings and
non-string based resources all
in one place.
In it we included the Notes
directory, specifically for you
to include contextual
information such as screenshots
for your localizers.
This year, I'm very happy to say
that we are automatically
including these screenshots for
you in the Xcode Localization
Catalog catalog.
[ Applause ]
And all it takes in one-- is one
single click during the Export
Localization Workflow that
you're already using.
If you rely on automation to
generate your Localization
Catalog, you can simply add the
include screenshots argument to
your xcodebuild
exportLocalizations command.
You can also customize which
screenshots I exported.
We made it easier for you to
specify which test targets,
devices and languages I exported
to Localization Catalog.
But that might be a lot of
screenshots for your localizers
to come through to see exactly
what Strings shows on the UI.
So, alongside every Localized
Screenshot that we generate, we
also generate a metadata.plist,
mapping the strings to the exact
location on the screenshots.
This plist include the strings
IDs, the ones that you can find
in the Eclipse but also the
framing formation, which is the
exact location of the Strings on
the screenshots.
This makes it really easy for
localization tools to map the
Strings to the Eclipse and
highlight them directly on the
screenshots.
And once you export your
localization catalog, this new
content is neatly organized in
the Notes directory and the
metadata.plist consolidated into
one for test targets and device.
And this is how easy it is to
direct Localized Screenshots
with Xcode 11 and test plans.
[ Applause ]
And with this, I'd like to call
Vivian back on stage to show you
all of it in action.
[ Applause ]
>> Thanks Arthur.
So, now that we've localized our
app, we want to test those
Localizations.
All right.
So, I've already created some UI
tests for my project here.
I have some here that will
capture all of my screens, which
I think would be really helpful
for giving to my localizers for
context.
And I have another test that
just zips in there and gets a
picture of those nice vacation
package images, which I think
would be good for marketing.
But I want to run all of these
test in all the localizations I
support.
And that could take some time
which is where test plans comes
in handy.
So you can add a test plan to
your project like any other
file.
File, New, File, and there's a
template for it, so I can just
search for plan.
There it is.
You can also, migrate your
existing test to test plans.
Let's save time.
I've already made one.
So, let's take a look.
OK. So I have two test targets
here.
I have one that will run all of
my screens tests and another
that's just going to capture
that marketing image.
I also have some configuration
setup.
The important thing here is in
the shared Settings.
Localization Screenshots is
turned on.
So, I've got one configuration
for English, United States and
another for Swedish, Sweden.
So, since I've just got those
images in French, I'm going to
add one for French.
Just click Plus.
Let's call this one French,
France.
OK. And we will set the
application language to French
and the application region to
France.
OK. It's now-- I think, I'll
rerun just the test to get that
marketing image.
So, I can get a picture of those
newly localized French images.
So, I go back to my UI test in
order to run it.
And now, when I click the test
diamond, instead of running my
test once, it's going to run it
with all of my configurations
and we can actually watch as it
goes through all of this.
So, it's going to run three
times, English and then Swedish
except my localizers aren't
done.
So, we'll probably going to see
some English strings again and
then one last time in French.
And I know that this will work
because I use accessibility
identifiers like Arthur said.
So my test will work with all
three language configurations.
All right.
Here we go again.
French, OK, great.
So let's see what we got here.
OK. If I look at the test that I
just ran.
OK. I can see it run, it's on my
configurations and if I check
out French and look at my
attachment.
Beautiful.
So, I can use this one for
marketing.
But my localizers are waiting
for an update on Swedish that
they can finish that.
So I need to send them a fresh
Xcode Localization Catalog and I
want to make sure that they get
that really tricky start string,
right.
So, let's make sure they get a
screenshot.
I ran my test earlier for it to
capture all of my screens.
So, if I look at the Swedish
one-- let's see if we can find
that tricky start string.
I think it's down here.
Yeah. There we go.
OK. So they haven't translated
Start yet or End and they got
Travelers.
And also in here I have that
plist with the frame information
which should be useful.
So, I'm now ready to export an
Xcode Localization Catalog.
Select the project, go to
Editor, export localization.
And this time, I'm going to do
Swedish and importantly I'm
going to click Include
screenshots.
All right.
Xcode has found I have 19
screenshots available.
Let's see exactly what I have
here.
If I click customize, I can see
I ran my test with iPhone 8
Plus, 10R and 10S.
So, if there's any layout issues
that might catch some of those.
OK. I'm definitely going to keep
all of those.
And, now, I'm ready to export.
OK. So, now, if I look at my new
Localization Catalog, now in the
Notes directory I have
screenshots.
And here I can see I have all of
my screenshots organized by test
target and device.
So, actually, I'm going to pull
the marketing ones out for later
and just send the rest to my
Localizers.
So we look in here, we can see I
have all of my screenshots.
OK. There's that tricky start
string and actually worst than
Start, you can see in this one
screenshot, we have the string
Book, one, two, three times.
So that plist with the frame
informations can be really
useful.
And this is the consolidated
plist, so it has the frame
information for all of the
strings captured in this entire
set of screenshots.
So, they're really handy because
now when I'm on localizer I can
open the catalog in my favorite
Localization Tool.
And now, I can preview where
string shows up.
[ Applause ]
And not only can I see one place
where a string shows, it will
show me all of the screenshots
that capture the given string.
So, my localizers are going to
be thrilled.
All right, let's wrap things up.
So, today, we saw how users can
run your app in a different
language to their system
language.
We saw a bunch of improvements
to the localization tooling in
Xcode, including faster export
of interface Builder files, a
new stringsdict rule, how easy
it is to localize your settings
bundle, and of course how you
can now localize images right in
your Asset Catalog.
We also saw how you can generate
Localized screenshots with your
Tests and some of the uses for
those screenshots.
For more information, please
visit our page on
developer.apple.com.
And if you have any questions,
come see us later in the labs.
Thank you.
Enjoy the rest of the
conference.
[ Applause ]