Transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> Welcome everybody to
Localization with Xcode 6.
My name is Zoltan Foley-Fisher
and I'm an engineer
with the Xcode team.
Later my colleague Chris
Hanson will join me on stage.
So you've spent time on
your applications artwork.
You've spent time on your
applications code but you
yet have to consider
your global audience.
The App Store is available in
150 countries around the world.
Here's a small fraction of them.
And there are literally
hundreds of millions
of users shopping
in these stores.
The interesting thing is
there's no one dominant language
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The interesting thing is
there's no one dominant language
around the world.
IOS is localized
into 40 languages
to reach a global audience
to take your application
to the next level, you
simply must localize.
So if this sounds like an
interesting opportunity,
you've come to the right place.
We'll bring you guys up to speed
on Apple's award winning
support for iOS and Mac OS X.
And of course we'll detail
some of the workflows in Xcode
to help you get your
application localized.
And for the old hands out
there, we have some new features
that I think you'll
find very interesting.
I want to take a step
back for a moment though
and introduce an
useful distinction.
Internationalization isn't
quite the same as localization.
I like to think of
internationalization
as a milestone on a path
to a localized application.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
as a milestone on a path
to a localized application.
Internationalization is where
you structure your application
to be language and
region independent.
That involves corralling
the source strings,
using interface builders
auto layout support.
And then once the application
is ready, then you can proceed
to the second step,
localization.
And I should be clear that users
around the world see
your applications
in very different ways.
So here's an English
application in the U.S. region.
Here's the same application
in Mexico.
And you'll notice that in
addition to being in Spanish,
it's also got a subtle
difference in the date.
Here's the same application
running in Spain also in Spanish
but again a difference in the
dates and the number formats.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
but again a difference in the
dates and the number formats.
So your applications
are going to have
to handle these subtleties, and
we're going to show you how.
First we'll create an
internationalized application
and then later, we'll
localize it.
And to get things started,
I'd like to introduce
you to Chris Hanson.
[ Applause ]
>> Thank you, Zoltan.
So as Zoltan said
internationalization is the
first step on the route
to having a fully
localized application.
And I'd like to show you how to
prepare your application and how
to leverage Apple's frameworks
to prepare for localization.
So we have some excellent
Framework Support
for internationalization and
localization in iOS and OS X.
And it's completely
pervasive throughout the
systems frameworks.
Otherwise I don't
think we'd be able
to localize iOS into
40 languages.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to localize iOS into
40 languages.
And what our system does is
separate your localizable data
from the rest of your
application thus making it much
easier to produce localized
variance of your application
that are actually all
built into a single bundle.
And these localized resources
these localized data can be
images, sounds and movies,
and documentation in addition
to the user-facing text
in your application.
And even the user-facing
text in your source code.
And as I said, it's
extremely simple to use.
Now the first step is to
start with NSLocalizedString.
NSLocalizedString lets you
internationalize strings
that are used in your user
interface but that come
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that are used in your user
interface but that come
from your source code.
And the way NSLocalizedString
works,
it lets you keep nice strings in
your code such as format code.
You don't have to replace
all the nice readable strings
in your code with some sort
of all uppercase identifier
pointing into a resource file.
Instead with NSLocalizedString
you can keep those strings
as they are and still have your
application fetch localized
resources automatically.
And that's the important part.
There's no explicit
loading or management
of your localized
strings needed at all.
And we have a couple of
variants of NSLocalizedString
such as
NSLocalizedStringFromTable
that you can use if you do need
to keep different string tables
for different purposes.
Let's just dive into some code.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Here we have the
kind of format string
that will often appear
in your code.
Here I'm just saying how
tall a particular mountain is
so I can assign that to a label.
Now obviously this
string is in English
and it's completely unlocalized
and un-internationalized.
So that's not really
great for my users
who use other languages.
Fortunately all I have to do is
wrap that with NSLocalizedString
and add in a comment explaining
what the string is for
and I've made that
code localized.
Now that comment is important.
It tells your localizers,
your translators,
just why you're using
that string.
Because different languages
might use different terminology
based on context.
So for example, a
language might say
that a person is a
certain height tall
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that a person is a
certain height tall
in a completely different way
than it says a mountain
is a certain height.
Of course, that wasn't
quite enough.
We were using StringWithFormat.
We should actually switch to
LocalizedStringWithFormat.
What that will do is it will
ensure that when we pass
out that height as a number,
that that number is
also properly formatted
for the user's language and
region, including such things
as localized digits because not
everybody uses the same digit
system, the same Arabic
numerals that we use
in say, the United States.
And of course, as with all
of our system frameworks,
this is all available
from SWF as well.
And in fact, I think
you'll like how we've --
how we're handling
NSLocalizedString in SWF.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now those localized strings,
when you localize
your application
into another language will come
from a dictionary called a
localizable strings file.
And this is a nice
readable file within Xcode
where you can specify all
of your localizable strings.
Of course, Zoltan will show
you how you don't even have
to author these files yourself.
How Xcode will take
care of that for you.
At the very beginning of a
particular entry in the file,
you'll see that comment that
you put in your source code.
And that's so somebody
who is localizing
that file will know just
what that string is for.
Then the string exactly as it
appears in your code will show
up as a key in that file,
and that's how our frameworks
localization system will look
up the string to use
in another language.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
up the string to use
in another language.
And finally on the
right-hand side,
you'll see a modified
version of that string.
Now here this is
just an English file,
but some languages actually
use a different word order
than English.
And instead of making you
write some code to say, well,
if I'm using this language,
then I need to pass my arguments
to StringsWithFormat or
LocalizedStringWithFormat
in this order, and then in
this other language I need
to pass them in a different
order, you can pass them all
in a stable order in your
code and you don't have
to write anything
language specific.
Instead you can use this one
dollar sign and two dollar sign
in syntax which Xcode will
put in for you automatically
to indicate what order
the arguments come in.
And here's an example
just in English
of how you might say the same
thing but in a different order.
And some languages
will use one order.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And some languages
will use one order.
Some languages will
use another order.
One order might be formal;
one order might be informal.
It doesn't really matter.
The point is that
Cocoa will take care
of the heavy lifting for you.
Now sort of at the next level
up, we have NSFormatter.
A lot of what your apps do is
present information from objects
to users as human-readable text.
And that's exactly what
formatters are for.
Formatters actually
translate between objects
and human-readable text.
Not just from one to the other.
And they can be used
both for presenting
and interpreting text.
So if you're say getting
numeric input from a user,
you'll probably want to use
the formatter just as much
as you'll want to
use a formatter
to present numeric output.
And formatters use the
user's current locale,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And formatters use the
user's current locale,
their current language
and region
and other settings by default.
You don't have to do any
special setup or configuration
to tell a formatter, hey,
use the user's specific
language and region.
So some very simple
formatter code.
Dates are actually extremely
difficult to format properly
for every language and
region in the world.
And that's why we
built support to them
in our systems frameworks
so that everybody doesn't
have to do that work.
Here we're configuring
the formatter
to present a medium
length date string.
Now that's a date string
that might not have the day
of the week but might
present say the month
and the day and the year only.
And since a NSDate doesn't
just carry a day, a year,
and a month, but
also carries a time,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and a month, but
also carries a time,
we're telling this formatter
that we actually don't care
about the time that's
in the date.
We just care about the
date portion of it.
And of course, once we
have a formatter set up,
we can just keep reusing it.
So once we have a date,
we just need to pass it
through that formatter using
the stringFromDate method
in the case of NSDateFormatter.
Or in the equivalent method
for any other formatter
and we can the assign it
straight to our label.
And of course, in SWF, this
all looks very similar.
It's actually a little bit
more concise though thanks
to SWF's enum syntax.
Now we have formatters
for dates as I said,
but we also have formatters
for individual date components,
and for time intervals
which are also very hard
to get right in all situations.
We also have formatters
for numbers.
And for formatting numbers
specifically in currency
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And for formatting numbers
specifically in currency
which might have slightly
different rules and even
for formatting byte counts
such as the number of bytes
or megabytes uploaded
or downloaded.
That way you don't have to
figure out how to format
that properly in
your apps themselves.
And new in iOS 8 and OS X
Yosemite we have support
for formatters for
health-related quantities
such as energy in
calories and kilocalories.
We have formatters
for length and height.
We have formatters for mass.
And this way you can present
this information consistently
to your user with other
apps on the system.
Now underlying all of this
is the concept of a bundle.
Your apps are actually built
into directories,
not single files.
And those directories
are called bundles.
And that doesn't
just cover your apps.
That goes for your app
extensions, your frameworks.
Everything else in
the system too.
And NSBundle provides an
API that's the standard way
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And NSBundle provides an
API that's the standard way
to access resources
within those bundles.
And when you use
NSBundle's APIs,
they automatically get the
most appropriate resource
for your current language.
And what's more, building
bundles is directly supported
by Xcode.
So when you have localized
resources in your application,
you don't need to write
scripts to place them
in the right place in your app.
Just tell Xcode that
they're localized
and what language they're for
and XCode will automatically
include them in the right place.
The NSBundle API is very simple.
Here we see getting a resource
that represents a game menu
from our main bundle
which represents our app.
And then we're just
creating an image with it
and assigning it
to UIImage View.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and assigning it
to UIImage View.
Now most of the time, these
are very common operations
so we have some shorthand
in our frameworks for them.
For example, UIImage has
the image name method
and that will just
automatically go to NSBundle
for your main bundle
and ask for that image,
and it will even handle
differences in things
like the path extension for you.
But not everything is going to
come from one of those methods.
For example, if I want
to play a welcome message
when my application starts
up, I'm probably going to want
that audio message to
be localized as well.
But AVAudioPlayer doesn't simply
have a player with file method.
That's okay.
We can just the URL from our
main bundle to that message
and then pass it
along to AVAudioPlayer
because those URLs
are just regular URLs.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
because those URLs
are just regular URLs.
So there's nothing special about
them that requires any form
of translation before they
can be passed elsewhere.
And as always, we
support this in SWF.
And in SWF, when you're
following sort of a chain
of methods like this, you can
actually use the Let Syntax
so you don't accidently reassign
to one of these variables.
I find that really handy.
Now let's talk about tools.
Since Xcode 5 we've supported
a concept called base
internationalization in Xcode
that helps you internationalize
your interface
by keeping your strings that are
in the interface files separate
from the UI components that
are in those interface files.
And of course in Xcode,
we also make it very easy
to localize your other project
resources as you need to.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to localize your other project
resources as you need to.
And new in Xcode 6, we have
some powerful preview features
that let you preview how
your application will look
in other regions and
in other languages,
both while it's running
and directly within Xcode
in any interface builder.
But first let's talk
a little bit more
about base internationalization.
As I said, it keeps your strings
and your user-facing
text separate
from your interface objects.
So the placeholder text that
you put into your IB storyboard
or your xib files is
only representative
of your development language.
What this means is that when
you have other languages added
to your project, you only
need to change the strings.
You don't need to
go through any more
and adjust every single xib
file or every single storyboard
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and adjust every single xib
file or every single storyboard
for every single
language you support.
And for other resources, we just
show them exactly the same way
that we show localized
strings in Xcode.
So as an example, I have an app
here that has a stop sign icon
and the yield sign icon.
Well those have text on
them so I'm probably going
to want a different
stop sign icon
and a different yield sign
icon, at least for the text,
possibly even for the shape
for English and for Swedish.
And you can do this with any
kind of resource: Images,
sounds, movies, documentation,
and really any kind of resource
that you can put in Xcode
and in your project.
And Xcode knows about
the structure of bundles
so you don't have to tell it,
hey, I want these over here; no,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
so you don't have to tell it,
hey, I want these over here; no,
I want those over there.
Xcode just knows and will
automatically put everything
in the right place in your app.
Now new in Xcode 6 we
support preview at run time.
This debug time preview
is accessed
through the edit scheme sheet
where you can set your
application language
from a pop up.
And this pop up will let you
pick the system language;
it will let you pick
any language
into which your application
has been localized;
and it will let you pick a
couple of pseudo-languages
that I'll explain
a little bit later.
But that's not all.
We've also added the ability
to IB's preview assistant
to select a language in which
you want to preview your NIB.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to select a language in which
you want to preview your NIB.
So you can preview
your interface
by just selecting any language
in which your application
has been translated
from the language pop up
on the lower right corner
of the preview window.
Now we also support a
pseudo-language directly
within IB for checking your
auto layout constraints.
And I'll show you that
a little bit later too.
And here it is zoomed in a
little bit so you can read it.
Now the stages of
internationalization are simply
to identify the strings
that you're going to use
for your translations,
to make sure
that your application
is properly using base
internationalization
and Auto Layout;
and then to localize any other
project resources that you need.
And I'd like to show that
to you now in Xcode 6.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And I'd like to show that
to you now in Xcode 6.
And so here I have
an application
that when I run it will
show some earthquakes data
from the U.S. Geological
Survey's web data feed.
Now I'm not actually using the
live feed so don't be alarmed
if you see anything in there.
On the other hand, we won't
see what might be going on,
this is California after all.
And you can see that in this
app, I have a nice big title.
I have a label indicating
where a particular
earthquake happened.
I have a graphic indicating the
-- well, indicating the strength
or the severity of that
earthquake; the date and time
of that earthquake,
and its magnitude
on the Richter's scale.
And then when I press -- or when
I tap one of these earthquakes,
I also get an action
sheet allowing me to see
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I also get an action
sheet allowing me to see
that earthquake on the U.S.
Geological Survey website
and to see its location in Maps.
Now there's a lot of strings,
a lot of text in this interface
and where does it all come from.
Well, I need to figure
that out to make sure
that my application is
properly internationalize.
So to start with let's take
a look at that action sheet.
I happen to know
that that's brought
up from my tableView's
delegate which happens
to be my mainView
Controller too.
And I just have a
straightforward method called
presentActionsForearthquake
that shows those actions.
And here you can
see that to present
that alert sheet I'm
using the new iOS 8 class,
UIAlertController or I'm
adding alert actions.
But here I'm just passing
the title the string directly
to my UIAlertAction.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
That means that even if I'm
running this application
in Swedish or Hindi I'm still
going to see this English text.
So I'm just going to wrap this
in NSLocalizedString
like I showed you.
And I'm also going to put
in a comment indicating
what this string is for.
And that's all I have to do to
insure that this text will come
from my localized strings when
running in other languages.
Now I also have the same
problem with my mapsAction title
and even with my Cancel title.
I could adjust those
here but in the interest
of time let's just
pretend that I did.
Now there's of course
a bunch more text here.
I showed you the name
of the earthquake
or rather the location of
the earthquake and the dates
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
or rather the location of
the earthquake and the dates
and the magnitude
of that earthquake.
Now those are going to
be in my tableView cell
because this is just a
standard tableView application.
And when I select my cell I have
a handy configureWithEarthquake
method that hooks up
my interface for me.
Now if I zoom in here a
little bit you can see
that I'm just passing
the location
of that earthquake straight
over to my location label.
And that's just text that
comes from the USGS data feed.
However I'm not passing the date
directly to that date label.
Instead I'm passing it
through a dateFormatter
that I've configured
as a property.
And the same is true
with my magnitude.
I'm not passing it directly.
I'm not using string of format.
Instead I'm passing it
through a numberFormatter.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Instead I'm passing it
through a numberFormatter.
I'm just going to Command
click that property
so that it shows in Xcode.
I'll scroll down just
a little bit here
so this is more visible.
And you can see that this
property is just a lazily
initialized numberFormatter
where I'm saying that I want
that magnitude to be
presented in a decimal format.
And because earthquakes
use a logarithmic scale,
we tend to always want to
present a fractional portion.
So I just tell my
formatter I always want
to show the decimal separator.
And that I want to show at
least one fractional digit
and actually so as to
avoid overflowing my label,
I only want to show
one fractional digit.
And for that date I'm just
telling my dateFormatter
that I want to use
a medium style
and for the time I want
to use a short style.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and for the time I want
to use a short style.
For the date I don't really
care if the earthquake happened
on a Saturday or a Wednesday.
I just care about the
actual day of the month
and the month and the year.
And for the time I don't really
care about the milliseconds
at least in this app, I
just want to know the --
to the minute time
of that earthquake.
So we've done a lot of
work to actually make sure
that we're getting everything
from localized resources
and that we're passing our
data through formatters.
Now what does that
actually get us?
Well, we haven't translated the
app yet but if I just stop it
and go to my Edit Scheme Sheet
I can look under the Options
and I have my Application
Language pop up
and my Application
Region pop up.
Now this is big menu so I
am going to zoom back out.
And I'm going to choose Sweden
so I can see how our manager
would see this application
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
when he's back home in Sweden.
I'm just going to close the
sheet and rerun my application.
And you can see that even though
the text is in English still,
a number of things about the
application have changed.
For example, the date and time
are presented differently.
In Sweden evidently the day
of the month comes
before the month whereas
in the United States we tend
to write the month
and then the day.
And in Sweden they use a 24 hour
clock instead of a 12 hour clock
like in the United States.
And finally one of the most
noticeable differences,
in Sweden the comma is the
decimal separator rather
than the period.
And the System Frameworks
handled
that for me just by
using a formatter.
Now let's take a look at our
interface in Interface Builder.
I'm just going to select
that earthquake scene
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I'm just going to select
that earthquake scene
that I'm looking at
in the simulator.
And I'm going to bring
up the Preview Assistant
that we introduced in Xcode 5.
And here I can select the
Preview, and in addition
to allowing me to
preview the application
in different orientations
down in the lower right I can
also select a language in which
to preview the application.
So here if I move over
a little bit you can see
that I only have my
Development Language actually
in this project.
However under the
Separator I also have one
of those pseudo-languages
I mentioned.
A Double Length Pseudo-Language.
So if I select this and
zoom out, what do I see?
Well, all of my labels have
had their text doubled.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Well, all of my labels have
had their text doubled.
And this is to simulate
running your application
in a more verbose language,
a language that uses more
text to say something.
For example, German tends to
use about 30 percent more space
than English does to say
about the same thing.
On the other hand,
there are some languages
that use even less space than
English to say the same thing.
And your application's interface
needs to accommodate them all.
Fortunately Auto Layout will
do most of the work for you.
And this Preview
Assistant lets you see
that it's actually working.
For example, I actually do
have an Auto Layout issue
in this preview.
You can see that the
Magnitude field has an ellipsis
in it indicating that its
text is overflowing the label.
Now the largest earthquake
that's ever been recorded was a
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now the largest earthquake
that's ever been recorded was a
9.5 so this probably
isn't an issue.
At least for this app.
However, it is something
that you'll probably want
to take into consideration.
Of course not all of the text
in this preview is doubled.
That's because this heading
that says Prototype Cells
and this background that says
Table View Prototype Content,
those are actually part
of Interface Builder's
user interface,
and not your own text.
Now if I wanted to localize this
graphic because it uses color
and color is another language
and region dependent piece
of information that would
also be very easy in Xcode.
I would just select the
image I want to localize
and then open the
Inspector and go
to the Inspector's
Localization section.
And we have this nice
big Localized button
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And we have this nice
big Localized button
that will turn any resource
into a localized resource.
And that button will just bring
up a pop up alert that asks
where I want --
what localization I
want that resource
to be a part of initially?
Now it can't actually be a part
of the base internationalization
because it doesn't have
a place as an image
into which I can
substitute strings.
However, I can make it a part
of my English localization.
And let's talk about
what we just saw.
We saw how the system
frameworks on iOS
and OS X will really do a lot
of the heavy lifting for you
in internationalization
and localization.
We saw how you can use
the debug-time preview
to check your region support
because after all even
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to check your region support
because after all even
if you don't localize
your application,
your users are still going to
be in different regions all
over the world and use
different conventions.
And we saw how you
can take advantage
of design-time previews and base
internationalizations to ensure
that your application is
properly reactive when it comes
to the length of text
in the interface.
And of course you can localize
other project resources too
as you need to.
Now to talk about the
actual process of localizing
and translating your
application I'm going
to hand things back to Zoltan.
[ Applause ]
>> Thanks, Chris.
So you saw how Chris prepared an
internationalized application.
He structured it to be
language and region independent.
And you saw how the
frameworks provided some
of the localized data for users
around the world for free.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the localized data for users
around the world for free.
So what's left to do?
Well, it turns out that the
bulk of the remaining work is
to translate your
User Facing Strings.
And this is still best done
by an expert in the language
and not just machine
translation.
So your challenge is to extract
those strings from your project.
Then patch them up from your
translator for your translator.
After they've translated
them you have
to integrate them back
into your projects.
Sounds like a lot of work.
Well, I'm pleased to announce
in Xcode 6 we've
streamlined the process.
Xcode will now carefully
examine your IB resources
and your source files
and extract the source
strings for you.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and extract the source
strings for you.
It will generate an
open XLIFF format.
Now this is that mature standard
that's accepted by a number
of translation companies around
the world and it's compatible
with a number of
translation tools.
So when translators
insert their work
into the XLIFF they then
return the XLIFF file to you
and then you simply
import it into your project
and then Xcode will meticulously
create the resources
or update existing resources
to put the translations
where they need to go.
So you no longer have
to run genstrings
or IB tool in order to do this.
[ Applause ]
Thank you.
I'd like to show you that now.
So here's the project that
Chris created earlier.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So here's the project that
Chris created earlier.
I'm just going to navigate to
the project where you find a lot
of the localization
related details.
So here you can see that at the
moment it's only got English
in this project.
So if I want to extract
the source strings
from this project, I simply
go up to the Editor menu
and choose Export
For Localization.
I choose a destination
in the Home folder.
And then Xcode generates
that XLIFF file based
on what it's found
in the projects
and I'll just show
you that quickly.
It's simply an XML file and
down here you can see the source
strings that Chris localized
or internationalized earlier
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
strings that Chris localized
or internationalized earlier
and the comments that he
added to the Translator.
So now imagine that I send
that to my translation team.
I would e-mail it or
upload it to their service.
And after they've
completed their work,
when I want to import
these translations,
I go back to the Editor menu
and choose Import Localizations.
Here's some prepared earlier.
Now I've heard that
smorgasbord is grace in Sweden
but personally I
prefer curry in India.
So we've got some
Hindi translations.
And Xcode is inserting those
translations into the project.
Now you can see that Hindi is
added to the project and that
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now you can see that Hindi is
added to the project and that
when I disclose the
storyboard variant group,
there's string files
waiting for us.
And if choose to run this
application I'll use the new
debug-time menu.
I'll choose Hindi.
I'll choose to preview
it as if a user in India.
And now you can see that
beautiful script in place.
The dates have changed.
The region --
the numberFormatter is
the same as in the U.S..
And this is one of the things I
like about the Preview feature,
it's immediately obvious that
this is not in the right script,
the title of this event.
So in this case you would
ideally use a localized feed.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So in this case you would
ideally use a localized feed.
I also like to point out this is
available on the Command line.
So you can now use
the exportLocalization
and importLocalization
verbs to build this
into your localization workflows
and to automate this
process as you want.
[ Applause ]
So you've seen how Xcode 6 will
now streamline this process
of localizing your application.
How it will help you to
communicate with your translator
in this open XLIFF format.
So now that you've got
a localized application,
you'd like to keep it that way.
And you'd like to build
confidence that it is going
to appeal to a global audience.
And so I'd like to invite Chris
back on the stage to show you
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And so I'd like to invite Chris
back on the stage to show you
to best maintain this
application and build confidence
that it's ready for
a global audience.
>> Thank you, Zoltan.
That's pretty cool stuff.
So of course you
probably don't want
to put off localizing your
application until the very end
of your development process.
That sounds a lot like waterfall
development and we really want
to be iterative these days.
And the expert and
import workflow
that Zoltan showed you
allows you to do that.
It allows you to do
what I like to think
of as continuous localization
because you can export
and import at will.
This lets you stay
localized as you work
and you can use previews
to catch missing
or bogus translations
very easily.
And we even include some tools
that let you prepare your
application for right
to left languages like Arabic
and Hebrew independently
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to left languages like Arabic
and Hebrew independently
of translating your application
into those languages.
That can make it much easier
to actually experiment
with your user interface
even if you don't speak
or read Arabic or Hebrew.
So I'd like just like to
show you that right in Xcode.
So let's say I've been working
on my project for a while.
And I've just received my
Spanish translation back
from my translator.
To import it all I have to do is
as Zoltan showed
select My Project
and then choose Import
Localizations and I'm going
to pull in my Spanish
XLIFF file.
Now what happened here?
Unlike what Zoltan showed
you with Hindi there appears
to be an issue with
this translation.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to be an issue with
this translation.
Well, it turns out that it's
missing the Show Location
and Maps functionality.
I must have actually
exporting this
for localization before I
added that feature to my app.
But that's okay.
I can still import this
incomplete localization
and at least see my application
as it is right now with all
of the localization that has
been completed for Spanish.
So I'm just going
to import that.
And if I just close
my storyboard here,
I can see that now
I have strings
in both Hindi and
Spanish for it.
Now if I want to see how my
application actually runs,
as always, I can just choose
my Application Language,
in this case Spanish now that
I've added that localization.
And I'll also choose the Spain
region so I can see how somebody
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And I'll also choose the Spain
region so I can see how somebody
who speaks Spanish in Spain
would see my application.
Now if I run this, I see
that earthquakes
here isn't localized.
That must have been another
thing that my translator missed.
And if I tap an earthquake, I
can see that one of my actions
and the Cancel button are
translated but that button
that I called out
earlier has not been.
Now if I wanted to see this
right in Interface Builder,
I could select my main
storyboard and let's just select
that earthquake scene and bring
up the Preview window again.
The Preview Assistant
I should say.
And if I choose my
Spanish localization
in Interface Builder,
I can see that some
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in Interface Builder,
I can see that some
of my placeholder labels
have been translated.
However, this earthquake's
title is not only all in English
but it's actually been
changed to all capital letters.
And that's actually the
frameworks calling out to me
that they recognize that
this should be coming
from a localized resource
but it wasn't found.
And I can get the same effect
in the Edit Scheme Sheet
when running my application
by choosing this new Show
non-localized strings option.
So if just stop and
rerun my application now
that I've seen -- set that,
I can see that earthquakes
is called
out in all capital letters.
[ Applause ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now I said you can
export and import at will.
And one reason that
you'll want to export is
because you'll be
adding features
to your application as you go.
And you'll want those
new features
that you add to be translated.
And you export in exactly
the same way no matter
when you do it.
You simply select your
project and choose Export
For Localization but I've
already added some localizations
to this app so what happens?
Well, Xcode gives me a
choice of whether I just want
to export strings in the
Development Language or if
when generating the XLIFF files,
it should already
include the strings
in the translations that it has.
This way I can hand those
XLIFF files to my translators
and they can see the work
that they've already
done and won't redo it.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that they've already
done and won't redo it.
Instead they'll only
do the work needed
for the new and changed strings.
So if I save this and replace
the one that was already there,
I can see now in the Home folder
that I have three exported
localizations in XLIFF format.
One in English, one in
Spanish, and one in Hindi.
Now finally I'd like to show
you what your app would look
like in a right to
left language.
For convenience we're just going
to bring up the storyboard again
so we have something
to compare against.
Stop my app from running in
the simulator and I'm going
to Edit My Scheme once more.
This time I'm just going
to set my region back
to the System Region but
I'm going to set my language
to the new Right to
Left Pseudo-Language.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now when you're using a right
to left language on an iPhone
or an iPad or a Mac,
it's not just the text
that goes from right to left.
The entire direction of the
user interface is changed based
on how the user prefers to read.
I'll just also turn off my
Show non-localized strings
setting here.
And let's see how
Auto Layout reacts
to just changing the
user interface direction.
Well, because we use the
concept of leading edge
and trailing edge rather
than left and right
in our Auto Layout for this app,
most of the app just flipped
right to left, just as an Arabic
or Hebrew user would see it.
We have our magnitude all
the way on the left instead
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We have our magnitude all
the way on the left instead
of all the way on the right.
Next to it is our graphic
indicating the severity
of an earthquake and then we
have some text overlapping it.
That indicates that we probably
still have a little bit of work
to do on making this fully
support right to left text.
Now the frameworks do that
but I probably just have a bug
in my Auto Layout constraints.
And this preview helped me
find it before I actually went
to the trouble of translating
my application and I don't have
to understand Hebrew or Arabic
in order to debug that problem.
So what we saw was how you
can update your translations
as you go to keep your
app current and really
to do iterative development
at the same time
that your app is
being translated.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We also saw how you can use
the various kinds of preview
to catch missing
translations before your users
and possibly even before
your QA ever sees them.
And we saw how you can simulate
many different behaviors
between regional formatting
and even right to left text
to ensure your apps work the
best they can for everyone.
Because that's really
what it's all about.
Reaching a global audience.
Our frameworks for iOS and
OS X make that really easy.
Especially if you take advantage
of Xcode's new workflows
for XLIFF, export and import,
and for previewing localizations
at debug time and
at design time.
There's some related sessions.
There was actually one earlier
today called Advanced Topics
in Internationalization that
goes in deep into what you need
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in Internationalization that
goes in deep into what you need
to do in terms of formatting
and code to deal with some
of the subtleties of
internationalization.
For example, mixing right to
left and left to right text.
And that's actually
the sequel to a session
that was held last year
that I'd also encourage you
to check out in the WWDC app.
And as always the Advanced
Topics Internationalization is
going to be available
for streaming soon.
There's also an Apps for China
Get Together tomorrow at 4:30
for anyone who's interested in
tapping this huge new market.
Thank you very much.
[ Applause ]