WWDC2016 Session 201

Transcript

[ Music ]
>> Okay.
Hello.
[ Foreign Language Spoken ]
So hello and welcome
everyone to WWDC.
Looks like it's your first
session this morning.
If you didn't understand
what I said at the beginning
of the talk, you're
at the right talk.
So let's talk a little bit
about internationalization.
So as you might know,
Apple ships its products
all over the world.
Apple ships its products
all over the world.
And two-thirds of Apple's
users are outside the U.S.
Which is why it's really
important to make sure
that the linguistic experience
is right in your apps.
So we have users all over
the place from San Francisco
to Milan and Dubai and from
New Delhi to Hong Kong.
And of course these
users are most likely
to be using your
apps and Apple's apps
in their native languages.
They're also likely
to be using these apps
in languages you didn't expect
that aren't related
to that region.
For example, English, you
might be surprised is a fairly
global language.
So today I'd like to talk
to you about what's new,
what we've been up to for
the last year in the space
of internationalization.
Some fundamentals about getting
started with localization
and internationalizing your app.
Then some quick fixes that
you can make in your code
to make it a great app
for a worldwide audience.
And lastly, some things to
keep in mind from a design
and mentality standpoint when
you go about making your app.
So let's get started
with what's new.
I'm really excited to talk
about the multilingual keyboards
that we've added in iOS 10.
Now if you look around you,
just to your left or right,
you're probably sitting
next to or are a person
who speaks more than
one language.
The U.S. is an extremely
multilingual place
and California especially so.
And with iOS 10 we embraced this
by offering you multilingual
keyboards.
So you can choose from a mix
of any of the two languages.
Or any two of the languages here
on screen, and you can type them
on the same layout without
having to switch the globe key
and you'll get autocorrections
and predictions
and you'll get autocorrections
and predictions
for both those languages.
Another enhancement we've
made is the addition
of Latin American Spanish.
And this comes to iOS,
watchOS, and tvOS.
And this is the first time
that your app might
encounter a language variant
that is not for specific
country.
And I'll talk about
how that's important
at the code level in a bit.
Another great enhancement is
the new measurement formatter
that is added in foundation.
And this will take care of
unit conversions in a language
and region aware manner
for you all under the hood,
and it already supports
more than 20 different units
like temperature, energy,
pressure, you name it.
Now, I won't be going into
depth about this here,
but there's a whole session
dedicated to this on Friday.
So please check that out.
We've also localized the
keyboard number pads this year.
And so when you request the
number pad keyboard type,
you're automatically
going to get a keyboard
that supports different
numbering systems,
such as those used
in Arabic and Hindi.
And when you're in this state,
you're going to see a 123 key
in the bottom left of the
keyboard to let you switch
between these different
numbering systems.
Now in some cases,
you might want
to specify ASCII capable number
pad instead when you're sure
that the input that
you have needs
to be restricted
to ASCII digits.
Some examples of this are credit
card numbers and IP addresses.
They're edge cases, but things
that you should be aware of.
One of the huge new features
in macOS Sierra is native
right-to-left support
for languages like
Arabic and Hebrew.
And macOS has been redesigned
with right-to-left
languages in mind.
And of course, macOS joins our
existing family of products
like iOS and watchOS
which already support
right-to-left
languages natively.
Again, this is a huge topic, and
I won't go into this in detail.
And again, there's
a dedicated talk,
What's New in International User
Interfaces on Friday at 9 a.m.
that you should definitely
check out.
So let's get started with
some of the fundamentals
that you need to know
about internationalization.
Let's take a look at an app that
comes with iOS, the Clock app.
It's been re-themed,
but probably still
looks familiar to you.
So what are the various
aspects that you would need
to internationalize here
for this app to work
in different languages
and countries?
First of all, you need
to localize the strings.
So this is basically any button
or tab or view that has a string
in it, you need to make
sure that it's translated
in it, you need to make
sure that it's translated
into all the different languages
you're going to be supporting.
Then there's another
category of string that needs
to be localized but it
is formatted content
and so you should use
formatters to achieve that.
And this will save
you a lot of work.
And lastly, you need to
internationalize the layout
so that it will work well
for right-to-left languages.
And for languages that have
longer or shorter translations
than the language
you're starting with.
So if we do all this right,
then we take this English app
and we translate it
into a Chinese app,
and it looks fantastic.
Notice how in Chinese the a.m.
/p.m. marker goes before
the numbers instead of after
like it does in English.
It'll also work well
for right-to-left
languages like Arabic.
Notice how the layout
of the entire app is
flowing from right-to-left.
And in this case, see how
Arabic is using the Arabic-Indic
And in this case, see how
Arabic is using the Arabic-Indic
numbers which are different
from those used in English.
Again, if you use formatters,
you get this for free.
So those are some fundamentals
for the development side.
Let's take a look
at the fundamentals
from the user side as well.
What does a user do when they
get a brand new Apple device
like an iPhone?
Well, every Apple
device that you open
up will first ask you
to choose a language.
And what's going on
under the covers is
that every language has a
code associated with it,
and of course, every region has
a code associated with it also.
So let's say a user chooses
Spanish, United States.
What that becomes at the end
of the day is a language
code like es-US.
What you may not know is
that language codes are
part of hierarchies.
So for example, Spanish,
United States actually inherits
from Latin American Spanish
which then inherits
from base Spanish.
which then inherits
from base Spanish.
This is really important
because not every app is going
to be localized into
Spanish, United States.
So we want to know, okay,
what is the next best language
that the user would prefer
if we don't have their most
preferred language available
on the system.
Also, this hierarchy is not just
for Spanish but even languages
like English have a hierarchy.
For example, Indian
English has spelling systems
that are more close
to British English
than to American English, and
so it is part of the hierarchy
in which it inherits
from British English.
And English and Spanish are
far from the only two languages
that have such a hierarchy.
We also have other languages
like Chinese, French,
and Portuguese that have
similar hierarchies.
So I hope you all are taking
notes on this, you know,
on these aspects because
no, of course not.
The reason I'm mentioning this
at all is because we're going
to help you solve this
problem, and you don't need
to know anything about this.
So I'm going to show
you how to do
So I'm going to show
you how to do
that in the next
section with quick fixes.
So what's the first
thing we need to do?
We need to localize the strings.
Now there is a little
bit of setup.
It's simple.
But there's some setup
involved, and I won't be talking
about that in detail
because there's a whole --
there's a lot of documentation,
and there's another talk
that goes into detail about
how to set up your app.
So let's assume that you've got
your setup for localization,
so you've got some
localized strings in your app.
If you're using storyboards
with Base Internationalization,
you're done.
There's nothing you need to do.
You launch your app.
The strings get loaded.
You're golden.
If you are creating or loading
strings in code, then you need
to call NSLocalizedString.
NSLocalizedString will use the
fantastic logic that I mentioned
with all the fallback,
and it will load the most
appropriate string for you.
Now, note that it's
important to provide a comment
to your translator because
oftentimes words are
to your translator because
oftentimes words are
distinguished by which
context they're in
and the comment helps
clarify that.
Let's move on to slightly
more complex scenario.
Let's say you're getting
strings from a remote service
like a server or
another process.
Well, in that case you
probably want to let the server
or the other process know,
hey this is the language
my app is launched in,
please give me strings
that match this.
And in order to do that, you
can call preferredLocalizations
on the Bundle that
you're launched from
and get the first
language and give
that to your remote service.
If you have an even
more involved setup
and for some reason you have
a list of available languages,
say, on the server that
don't match exactly the list
of languages you
have on the client.
Let's say you have a
larger set on the server,
then you can call the class
method preferredLocalizations
and give it the available
set that you have.
And again, it will match
you to the right language.
And again, it will match
you to the right language.
So I mentioned this Bundle's
language matching logic multiple
times during the
last few slides.
So what is all this about?
And what is Bundle doing
for you under the hood?
So what Bundle does for you is
that it figures out things like,
okay user prefers English
U.S. We don't have an English
U.S. localization.
We do have an English.
So okay, in this case it
will give you English.
It figures out things like
you want Indian English,
but we have British but not
Indian, we'll give you that.
And again, with the Spanish
Latin America example,
if you say I prefer Mexican
Spanish, it will figure
out that oh the best
match for you
in the list shown here is
Latin American Spanish.
And similarly, for Chinese
and many other languages.
This is a lot of
complicated locale aware logic
that you do not want to be
implementing in your apps.
And definitely if you have
code that does something
like take the language
identifier and split it
like take the language
identifier and split it
on hyphens or something like
that, please go and delete
that code because you
should not be doing that.
So now you've localized all your
strings and used the right APIs.
You want to double check
that everything you have
done is actually localized.
To do that, you can use the
new static analyzer in Xcode 8,
which will actually find
any issues that you have
with localizability,
where you're feeding
non-localized strings
into the UI.
And that's all there is to
localized strings, really.
Next let's talk about
formatters.
This is a common kind of
app that you see these days
with all the delivery services.
And this, however, is not a good
thing that you're seeing here.
So it says AM9:41, which to an
English user will definitely
look like nonsense.
But believe me, I've
seen this in a real app.
And similarly, you might see
something that is the opposite
in Chinese where
it puts the a.m.
/p.m. marker after the numbers,
which is completely
wrong for Chinese.
So how do we avoid
bugs like these?
The problem is actually
that we're using this method
which is formatter.dateFormat
setting a fixed format on it.
It seems like the
right thing to do.
It looks pretty nice in code,
but it's actually
the wrong approach.
And although it yields the
right result when you try it
out for English, so it'll give
you 9:41 a.m. you try the same
thing out in Chinese, and it
gives you the wrong result.
Why? Because it's applying
a fixed format to no matter
which language you're
running in.
The correct approach for this is
to just use the predefined short
style on the date formatter.
And it's going to give you
the right result for English,
for Chinese, and for any other
language your app might be
localized in.
And of course, there
are more styles.
So we have the short style
that I just showed you.
You can also get a
slightly longer style,
You can also get a
slightly longer style,
which has the seconds.
You can have a style
which has the time zone
or the full time zone name.
There are variety of different
styles for different needs.
And of course, not
just for times.
For dates, also, we
have the whole range
of styles going from
short to long.
Now you might come back to me
and say, "okay, sure but none
of those styles is
what my designer wants.
They want, you know,
just the full year
or just this or just that."
That's fine.
So you can use a format.
The important thing is to use it
with the setLocalizedDate
FormatFrom Template method,
which will make sure that it
takes your format, interprets it
for the current language
in question
and gives you the
correct localized format
for that language.
There are also two classes
that you might not have used.
They're fairly new, although not
new this year, date components,
which will let you format, say,
a duration like 4
hours and 25 minutes.
Or a date interval like
the duration of this talk,
9 to 9:40 a.m. So the
advantage to these, again,
is that if you use
these classes,
all the localization is going
to get taken care of for you.
Next let's talk about
another kind of data type
that you can format, names.
Now, if this is how you're
going to show the user's name
or their friend's name to
them when they open your app,
they're going to get a really
bad impression of your app.
So let's not do that.
Instead, you should show the
names in the way that is correct
for that given language
and script.
So how do we do that?
It's actually really simple.
You create a
PersonNameComponents object.
Fill it with some name
components, and then just
Fill it with some name
components, and then just
like any other formatter,
you just ask for the string
from the components for any
given style that you want.
And again, we have a variety
of styles going from long,
which is the full name
all the way to abbreviated
which you can use for initials.
And of course, it supports
multiple languages.
New this year, though,
is name parsing support.
So now you can go from a full
name to a set of components.
And it's as easy as creating a
formatter, giving it a string,
and then looking
at the components.
If it returns nil, it
means it wasn't able
to successfully construct
components out of it.
The really cool thing, though,
is that this is not a
static API that's looking
at some set of static rules.
It's actually a statistical
model so that even if you pass
in the name in the
opposite order,
it knows that in John Appleseed,
John is much more likely
it knows that in John Appleseed,
John is much more likely
to be the given name and
Appleseed the family name.
And it's still going
to parse it correctly.
And of course, it supports
multiple languages as well.
So there are a lot
of formatters.
I talked about Date
and
PersonNameComponentsFormatters
in detail.
The components and interval
formatters for dates, briefly.
And there are some formatters
I didn't even mention
which are existing formatters
that we have in the system.
And there's the brand new
measurement formatter that's new
in this set of releases.
So be sure to use these
formatters wherever you can
in your code because they
will do the right thing,
and you will also save
localized strings.
Which you shouldn't be
using for these cases.
So that's all about at this
point your whole UI is localized
So that's all about at this
point your whole UI is localized
in terms of strings.
Now let's take a look at
what you need to do in terms
of the layout to make sure
that the UI actually works
well with those strings.
So the key word here
is Auto Layout.
It does what it's intended --
what its name tells you it does,
which is it automatically
lays things out.
And so whether you're
in a left-to-right app,
if you use Auto Layout you
will get automatically a user
interface for a right-to-left
language.
And again, Auto Layout is a big
topic, and I'm not going to go
into detail into how you
should use Auto Layout
because there are sessions
for that both this year
and from previous years that go
into a fair amount of detail.
What I will tell you is that
you should use UIStackView
and NSStackView as much as you
can because these are very easy
to use APIs that leverage
Auto Layout and make sure
to use APIs that leverage
Auto Layout and make sure
that your views will
flip in the right way
for right-to-left languages
and adjust appropriately
when they get long
and shorter strings.
So we will have sample code
for you that shows you how
to implement a version of the
Clock app using Stack Views.
Now one thing that you
might want to keep in mind
for layout is that sometimes
you need to get creative.
Now you see this
screen in English.
Are you sure you don't
want to use an Apple ID?
And you have two options there,
Use Apple ID or Don't Use.
Now in some languages you can
imagine the translations might
be longer than can fit in
two side-by-side buttons.
So what do you do?
Well, in this case, you see
that the whole view switches
to a top-bottom orientation
instead
of a left-right orientation.
And these kind of creative
UI elements are things
that you should keep in mind for
your apps before you ask a --
that you should keep in mind for
your apps before you ask a --
you ask a translator to
shorten a string to the point
where it might not even be
intelligible in that language.
The next thing is
vertical flexibility.
And a lot of you may not
have realized this before
for your apps.
So we have a lot of scripts
in the OS for languages
like Vietnamese, Thai, Arabic,
and Hindi that go much higher
or lower or both than the basic
Latin alphabet that's used
to write English.
And so what happens
often is we see this bug,
which is that somebody
might set clipsToBounds
to true on the label.
And what that does is it clips
the text often on both side
and besides being very ugly and,
you know, just looking terrible
in that language, you often lose
important semantic information
in that language, you often lose
important semantic information
like a diacritic mark.
In this case the pronunciation
of all of the words
on the right is changing
when you clip them like this.
So to fix this it's
pretty simple.
Don't set clipsToBounds to
true if you have a label.
And that should be enough
to solve this problem.
More interestingly, though,
when you have multi-line labels,
you also need to consider
interline spacing.
So let's take a look here
which has Hindi on the left
and English on the right.
And here it's English
on the left and Hindi
on the right, sorry about that.
But see what happens when
we try to squeeze Hindi
into the same amount of
vertical space as English?
It looks really cramped.
And any Hindi reader will tell
you this is really hard to read,
And any Hindi reader will tell
you this is really hard to read,
and it doesn't look nice.
So what you really need to do is
to give each script the
room it needs to breathe
and to look good on screen
and to be easy to read.
The good news is that
this is really easy to do.
Any time you have a
multi-line label, again,
a lot of this is done by default
but you just need to be sure
when you set a custom font
that you do the right thing
that you get a preferred
font using the UI font API.
Now, you might say, okay
I have a custom font
and I can't use this.
Well, there is a solution
for you, and you should check
out the fonts and typography
talk on Wednesday that goes
into more detail about
how you can make sure
that a custom font will
also adhere to dynamic type.
Next, for table views, we
do something really neat,
which is that if you have a
language with a taller script,
which is that if you have a
language with a taller script,
we will actually make the table
row height larger than it is
in other languages like English.
Again, this gives the script
the room it needs to breathe,
and it just overall looks more
natural for those languages.
The way you can take
advantage of this code is
by using the standard
UITableViewCell styles.
And now you might say, okay,
sure but I have a custom cell,
you know, it's not
going to work with this.
I mean, I don't just have
a label and you know,
it's not as simple
as you think it is.
And I'll be like, okay sure.
I agree. But what
I found at least
in using UITableViewCell is
that it is highly customizable.
It has a bunch of
overrides that you can use,
usually to get exactly
the appearance you want.
So try that first before you're
implementing a completely
custom UITableViewCell.
So that's mostly what I have
in terms of small code fixes
So that's mostly what I have
in terms of small code fixes
that will make your app great
for an international audience.
Let's talk about some things
that are more abstract
that are more design based.
And also the mentality
you need to keep in mind
for making great apps.
First of all, it's
the iconography.
Now you know that when you go to
the App Store and you're looking
for an app one of the
first things you're going
to notice is that icon.
And oftentimes, at
least I've done this,
if the icon doesn't look
good I don't buy the app
because that's going to
go on my Home Screen.
And I don't want to have an app
there that doesn't look good.
So icons are really important,
and it's also important
that the icon that
you choose works well
for different languages
and also languages that go
in different layout directions
like left-to-right
or right-to-left.
So photos has a great icon here.
This is a great example of an
icon that doesn't have any words
or numbers that would tie
it to a specific language.
or numbers that would tie
it to a specific language.
It also doesn't have
a directionality
like left-to-right
or right-to-left.
So it really works well,
you know, in Japanese,
in English, and in Arabic.
Now if you are making a
right-to-left localization,
and you want to make sure
your UI is really good
for right-to-left languages.
You should take a look at some
of the artwork you're using.
And if you are using artwork
that has a directionality to it
that would need to change
for a right-to-left language,
then you would probably need to
flip or create dedicated artwork
for right-to-left languages.
Now here you see an
example of artwork
that you can't just
flip horizontally.
You need to create
dedicated artwork if you're
in a right-to-left language.
But if you do have images
that just need to be flipped,
there is actually API for
that and you don't need
to create separate artwork.
There's more information about
that, again, in the What's New
in International
Interfaces session on Friday.
But the key is asset catalogues.
Another thing that you might
or might not have thought
about is your app's name.
Now, when looking at various
App Stores around the world,
one consistent theme we've
seen that doesn't surprise us
in the least is that users
are more likely to buy apps
that work for them
in their language.
And that applies to
the apps' name as well.
Because if they can -- if they
can understand easily what your
app does by looking at the
one line name and description,
then they're much more likely
to tap inside the
app to take a look.
And of course, the world is --
users all over the world are
more and more multilingual
or at least they're bilingual.
So your app should
not make assumptions
about the UI language and
how it relates to the content
that the user will type.
For example, a very common theme
you will see all over countries
in Asia like India
and Southeast Asia is
that people will run
their phones in English,
but they'll have content
in their local languages
like Hindi in this case.
So when you have an app and you
run in English, don't assume
that the user's going
to type English text,
especially make sure to
test your app with Chinese
and Japanese keyboards
to make sure
that the experience works well.
And here's an example that I
wanted to show you of an app
that in our opinion
does a really great job
at the things I just
talked about.
So this is Evernote.
And first of all,
you'll see the app icon.
It doesn't have any words
or symbols or anything
that would associate it
with a single language.
So that's great.
However, they have also gone
and localized their
app name into Chinese.
And this is actually if
you're a Chinese speaker,
you'll see that they have
a great visual pun in there
because the Chinese word
that they've chosen also
contains the character
for elephant, which is their
icons, which is kind of cool.
You'll also notice that they
have localized screenshots.
And there's a lot of attention
to detail in those screenshots.
You'll see, for example, that
in the localized screenshot
in which they're
creating a note,
you actually have the
Chinese keyboard on screen.
So the user is seeing
in the screenshots exactly the
experience that they're going
to get when they
download this app.
This is exactly what
users expect to see.
So take advantage of the fact
that you can upload
localized names, descriptions,
and screenshots to
the App Store.
And lastly, I wanted to talk
about surprise and delight.
What you can do to go above and
beyond to make a great product
What you can do to go above and
beyond to make a great product
for people in the --
using a specific language
or in a specific country.
I'll give a couple of examples.
One is if you have any
kind of predefined content
such as templates and pages.
You could create
different customized content
for different languages.
And so for example, in Pages
you have custom templates
for cards for some languages.
And just one more
example I'll give is
for more advanced feature,
let's say you're supporting --
you're a calendar app, and you
want to have a really great app
for the Middle East and also
for a lot of Asian countries
like China where they
use a lunar calendar.
Well, you could support
the lunar calendar
in your calendar app just like
iOS does and iOS and OS X do
because this is going to
deliver a much richer experience
because this is going to
deliver a much richer experience
for those users.
Now what your app
does is really --
depends on what your app does.
And so you need to take a
look at your own app and see
if there's an area where you can
deliver a surprise to the user.
That's really all I
wanted to talk about today.
So in summary, localize
your app.
Use standard system APIs
like Formatter and Bundle.
Make sure that the apps' layout
is flexible and works well
for languages with
shorter translations,
longer translations, which have
normal -- not normal-sized,
English-sized scripts
or taller scripts.
When designing the
iconography for your app,
make sure that it is
a world-ready design
and doesn't tailor to a
specific language too much.
and doesn't tailor to a
specific language too much.
And finally, at the end
localize your app's name,
if appropriate, and screenshots.
Now for more information,
you can follow this link
to get some other useful links
about internationalization
and localization.
There are also some
really cool other talks
that I mentioned
during my presentation.
So for example, there's
What's New
in International
User Interfaces.
And there's also a
What's New in Auto Layout.
One talk that I wanted to call
out specifically is
Inclusive App Design.
It kind of will talk more about
some of the things I mentioned
at the end about how you can
keep an inclusive design in mind
for both internationalization
and for users
that need accessibility support.
And that's all.
Thank you very much.
[ Applause ]