Stanford University Developing iOS 7 Apps: Lecture 18 – Localization, Adding UI to Setti


[ Music ]>>Stanford University.>>Okay. Well, welcome
to lecture number 18 of CS193P, fall 2013/14. Before I talk about what I’m
going to talk about today, let’s talk a little
bit about what’s coming up because we’re right at
the end of the quarter here. So on Wednesday —
next lecture — we are going to have
this alternate final presentation day. And a few of you have already
said that you wanted to do that. And really, the only thing you
need to do to sign up to do that if you want to use
this Wednesday as opposed to the following Thursday
normal final presentation time to do your presentation, is
to submit the Keynote slides, okay, by tomorrow at noon. That’s very important. If I don’t see your
slides by tomorrow at noon, then you’re basically not going
to be presenting on Wednesday. And then you’ll be forced
to present next Thursday. So the only thing I’ll say
about your Keynote slides, make sure that they’re
widescreen format, okay, 1280 by 720. If you are submitting PowerPoint
or something else, you know, you’re taking your
chances because I’m going to convert them to Keynote. So if they have fonts and
stuff, convert them — you’re in good shape;
if not, you know, you’re slides might
look a little wonky. You just submit them
normally, right? Just do the normal
class submit script. You submit it as
your final project. And of course, you
can submit again, all the way up until
the deadline. And the other thing we’re
going to do on Wednesday after we have a few
people, you know, do their final presentations —
which by the way, I, you know, really encourage all of you
to come and be an audience for those people just
because you’ll get to see some final presentations; you’ll get a little
bit of bonus. I’ll talk a little bit about
the final presentations. If I see something, I’m
like, “Oh, let’s make sure that this doesn’t happen
next Thursday or whatever.” Also, after that’s
done, if you’re planning to do a live demo,
Wednesday will be a great time because I’ll have
this whole setup here. And you can try and
hook up your device, and using this wireless
thing that I use, and this thing right here —
which let me set that up — to show your demo and make
sure that it’s working, make sure your device
works, all that stuff so that you can have
a nice, smooth demo. Okay? So we’ll be doing
all that on Wednesday. Otherwise I’m not going to
present a particular topic. So it’s one of those things
where, again, I encourage you to come be an audience
for the people who are doing alternate
presentation, but it’s not a mandatory. I mean, all these lectures at the end here are
not mandatory per se. But that’s what’s
going on, on Wednesday. Okay? Any questions about that? All right. And then Friday, no
section on Friday. I think it might even
be officially start of final exam period on Friday. I’m not one hundred
percent sure. But in any case, no section. We’ve moved your project
deadline, as you know, to Sunday night at midnight. And when you submit your final
project, submit your slides. Okay? Assuming you’re
not submitting them by noon tomorrow, make sure you
submit them by Sunday night. And just put them
right at the top level of whatever you submit. Just whatever the top
level directory is, just put them there
— Keynote slides. The final presentations
are a week from Thursday, so the normally scheduled
final exam period for this class, 12:15 to 3:15. The presentation is required. Some people say,
“Is it optional?” No, it’s required. You get two and a half
minutes this quarter, which is a long time. Usually we only give
two minutes. And seems like a long
time; when you get up there it will seem short. And again, widescreen
aspect ratio. And the order is
going to be random. You’re not going to find out
until the day you get it, so don’t even send me something
that I says, “Oh, I got a flight to catch, so let me go first.” Okay? If you got
a flight to catch, then go on Wednesday, okay? Go the day after tomorrow
because for fairness, I’m going to put it
in a random order that will be revealed
at the beginning. Okay? Any questions about that? We’re about to find — any questions about the final
project submission process or due date Sunday night? Okay. Excellent. So today’s two topics,
localization — really, it’s
internationalization that I’m going to
be talking about — and then settings,
which is a UI. You can add UI to the
settings application to control certain settings
about your application. And the two demos
I’m going to do, I’m going to internationalize
PhotoMania, and I’m going to add a setting to Bouncer. Okay? That way we’ll get
both of these things demoed. All right. So let’s talk about
internationalization. There’s really two steps
to internationalization: There’s something we called
“internationalization” — sometimes abbreviated I-18-N
because there’s 18 letters in there; I-18-N,
internationalization — and then there’s localization. “Internationalization”
is the process of making your app
possible to be localized. Okay? Making it so that
your app can be shipped in multiple different languages. “Localization” is the process
of actually translating that — your application — to
another language, okay? So it’s really a
two-step process. Internationalization, that’s something you
do as the developer. Localization, usually hire
someone to go do that. I don’t recommend using Google
Translate to localize your app. You get some very
strange results. You want a professional
localizer who understands the idioms
of the local language. There’s really two things
that need to be localized: One is your storyboard
and one is kind of all the literal strings
in your application. So let’s talk about
the storyboards first. The way we localize storyboards in iOS 7 is we only change
the strings that appear in the storyboard, and we
let Auto Layout resize things to fit wider and
shorter strings. Okay? That’s a great side
benefit of having Auto Layout, is that localization now
is just about the strings when it comes to the storyboard. But the first thing we need to do before we do any
localization is to go to our project settings and set
the list of all the languages that we are going to
support localization for. Okay? So you know, as
you release new versions of your app, you’ll support
a few more languages. You’ll go back to this project
settings and add more languages. One thing that’s a little
tricky about this is you’re used to going to your
project settings, which is that upper left-hand
top part of the navigator. But actually, what we’ve
been setting the settings of there is the target, the
app that you’re building. Here you want to
actually set the settings of the project itself. So you can see where
that little bubble points to right there that
says PhotoMania. That’s a little popup actually;
you’re going to click that and switch up to
editing the project. And when you do, there’s
not a whole lot of settings for the whole project. You’re seeing them
all right here. And you’re just going to go
down to the bottom there. It says localizations. It’s just a list of languages. These are pre-supported
languages because these languages need
to match up with the languages that the operating system, iOS,
supports so that when people go to settings and other apps, that’s in whatever
language as well. So when you hit that
little plus button down in the lower left-hand
corner, it’s going to be a popup with a list of languages. You’re not going to just type
in the word Arabic or French; it’s going to be something
you’re going to pick from a list of supported languages for iOS. And you can also see that there’s a language
there called base, right? And there’s a switch that says
use base internationalization. The concept of base
internationalization is that there’s going
to be a localization. It’s not a localization that
is in anybody’s language; it’s just the base localization. And that’s going to be kind
of like all the defaults: The default storyboard strings, default strings throughout
your app are going to come out of the base localization. And then all these
other localizations, like English even, but French,
and German, and whatever, those are going to
modify those strings. And so if you forget
to localize a string, the base localization
will shine through, okay? And so we’ll see what that
looks like when it comes to storyboards in a second here. So the storyboards
look like this. You select a storyboard. And when you do the
thing I showed you on the previous slide, then your
storyboards are going to look like this in the file navigator. You see how there’s
main, iPhone, storyboard? And now it has a little
triangle that you can click and it now is showing
underneath it main, iPhone, storyboard again — base. So that’s your base storyboard. And then for French, it says
main, iPhone, dot strings. So that’s just the strings
only for the storyboards that have been extracted, okay? When we did that previous thing,
it extracted those out there. And when you click on the
storyboard and if you go to the file inspector, you can
see this little thing showing there where there’s base —
there will always be base — and then however many languages
you want to translate to. Now, here notice that
English is not even checked; that’s because I’m going to
assume that my base is English. Okay? Now, you don’t
always want to assume that. And you could even
mostly assume that but still have an
English dot strings file that changed a couple
of things if you wanted. Or you could have the
whole thing be, you know, explicitly in a strings
file for English. But here I have not
even checked English. So whatever’s in my base
storyboard, that’s what’s going to ship when I’m in
the language English. But in French I have
a localizable without strings file, which
I’ll show you in a second, which is going to change all
the strings in my storyboard. So what does that look like? The French language strings? I’m going to postpone
showing what that looks like until we talk about
strings in general. And so let’s talk
about literal strings. So the storyboard
strings are going to be in this thing I showed
you in the last slide. But there’s other strings
inside your app that aren’t in the storyboard,
like things that come up in alert messages,
the alert buttons. All those things are
not in your storyboard, but they need be
localized as well. And the way we get those strings to be localizable is using
these macros here that start with NS localized string. So there’s NS localized
string with default value; there’s NS localized
string from table; there’s NS localized string. And each of these macros takes a
little bit different arguments. But the main thing they’re doing
is you’re giving a key that’s going to be looked
up in a strings file and it’s going to
return a value. The different variants
just determine: What’s the default value
if I can’t find the thing in the string, and which
dot strings file am I going to look in? Okay, for our storyboard
there’s always one string file associated. But when we have literal strings
inside of our code, we can split up all the translations into
different files if we want. In the demo I’ll do that. I’ll put them in a
little separate file just for one view controller. So for example, if you had the
literal string hello, at sign, quote, hello in your app
and that is going to appear in the UI, then you would change that to NS localized
string at hello comma. And then, the last
argument there is a comment to the localizers, okay? So you can assume the
localizers speak your language, whatever your base language is, and you’re giving
them a comment. You’re telling them
what is this hello? Where does it appear? What’s its environment? So here I’m saying
it’s a greeting at the start of the application. So the person would
know in French to make that be bonjour or whatever. Right? So that’s how you
change all your literal strings to these NS localized
string, one of these variants. Now what are these
things actually doing, these NS localized string? They’re actually calling
a method in NS bundle. Okay? NS bundle is a class that
kind of collects everything about your app, okay,
into an API for accessing the
resources of it. And we can use it to
access strings files, and we do that with this method in bundle called
localized string for key value table, right? Exactly what you would think:
Key is what we’re looking up in the strings files;
value is the default there; and table is which
table to look in. The bundle can also be used,
by the way, to find URLs to resources like
images, things like that. If you drag an image
— a JPEG image — right into the top
level of your navigator, then you can use NS
bundle main bundle. There’s something
called URL for resource, and you give it the
name of that JPEG file. It will give you a URL to it. Sometimes you need a
full URL to some image. Or if you’re not using image
named, you need some full URL. So NS bundle is a
class for you to kind of understand a little
bit as well. But we don’t usually — well, sometimes we’ll call
this localized string for key, and I’ll do it in
the demo as well. But we can use the
macros, we should. But there’s a significant
limitation on those macros, the NS localized string:
All the arguments have to be literal strings, including
the comment; the key; the value; the table name; etc.
They can’t be variables. They have to be literal things. At sign quote something,
at sign quote something for every argument of
those localized strings. And then let’s talk
about why that is. The answer for that is there’s
a command line utility called genstrings — short
for generate strings — which will look through
a dot M file for all those NS
localized string macros and extract them all out
into a strings file for you. Okay? And that’s how you
get the base string file that you will then
localize to other languages. Okay? And we’ll show
this in the demo as well. And so, for example, we had
that NS localized string at sign hello, greeting
at start of application. That would get turned into
the following two lines there in a strings file:
Comment, greeting is started by application, and
then hello equals hello. And the French person
would come along and they would change
hello equals bonjour. Now, when you do genstrings and you get dot strings
files generated — and you might get multiple
of them because remember, one of the NS localized
strings is NS localized string from table, so you might
specify table name. And so it might be making
multiple dot strings files for you. You just take those
dot strings files, drag them into your application,
into your Xcode project, and then inspect them
with a file inspector. And when you do, you’re
going to see this button, the top button there
that says localize. And when you click that,
then you’ll get a list of the languages, okay? And you can click however
many of the languages you want to support localizing
this string file for. And then in your file navigator
you’ll see a dot strings file for every language. You can click on it. And then you — usually what
you’ll do is you’ll click on it and you’ll see hello
equal hello. You’ll take that entire file
or all the strings files, ship them off to a localizer —
maybe with a demo of your app or something like that — they’ll translate all the
strings and send them back. And then you just plop them into
your Xcode project and ship it. Okay. So the way that these
bundles are arranged is inside a bundle — and your
application is the main bundle, so that’s the top level
of your application — inside are these
lproj directories. And the name of the
lproj directory is like a little two-letter
symbol for the language. So there’s EN dot
lproj; that’s English. There’s FR dot lproj;
that’s French. And inside the lproj is
all the strings files for localizing to that language. Okay? It’s as simple as that. So you might have, you
know, 25 dot lprojs if you support 25 languages. In all them there will be a copy of the strings files
that are edited. You can look more about
NS bundle offline, but there are ways to also
associate strings files not just with your main bundle of your
app, but if you had a framework or something else, you could
associate it with frameworks because bundle, in
addition to main bundle. it has this bundle
for class method. Okay? And so it knows
where that class came from, whether it was a framework
or your main bundle. And it will give you the bundle,
and then you can get a path for a resource or do localized
string for key value table. Okay. Couple of things about
debugging localization. There’s a really nice user
default that you can set, NS show non-localized strings. And every time one of those
NS localized string — I say methods, but
really they’re macros — any time one of those does not
find an entry in a string file, you’ll get a little log. Okay? So then you’ll know that
your localizer missed one. Okay. So that’s important
to know. So that way when you’re doing
your QA of your localizations to make sure that they’re
really working as good. I’ve seen some people complain that sometimes they’ll add
some strings to a localization and test it and it’s like, “Oh, it’s not getting
the new changes.” I haven’t seen that in iOS 7,
but if you do, building clean and reinstalling seems
to solve that problem. I don’t know exactly
the circumstances that supposedly happens under, but it can’t hurt
to build clean. Okay. So that’s strings. And we’ll see all this
happening in the demo. There’s more to localization,
though, than just strings unfortunately. There’s also the
concept of a locale. So your user not only might
speak a different language, they might live in any
number of different locales. An easy one to think
about is English. In America we speak English. In Great Britain
they speak English. But there are local
idioms and the way that we express currency, the way we even just express
numbers — big numbers — the commas and the periods
are swapped, for example. Things just are all
slightly different. So even though language in both of those countries
would be English, the locales would be different. So there’s a whole other
system here for locales. And users set their language and their locale using
the settings app. And your application it’s
just supposed to adapt. Okay? And you adapt by
using some of these methods that take a locale
as an argument or that use a locale
under the covers. Okay? You can find out
what current locale is with these methods, and you can
also have this nice autoupdating current locale, which if the
user changes their locale, it will just automatically
update underneath the covers; although, you probably want to
listen to this radio station, too, because if it changes, you
might have to redraw your UI. Right? If they change? But it’s pretty unusual for
the user to change their locale or their language while
they’re in the middle of running your app,
but it could happen. Okay. You should be
prepared for that to happen. So what are some of the things
that are different in a locale? Well, there’s numbers. Now, there’s a lot going
on with formatting numbers. It seems like it’s
really simple, but there’s actually a
lot to think about here. But I’m going to look at
two pretty simple cases. One is displaying numbers
and one is reading numbers. So for displaying number on
screen you’re probably want to do string with
format percent G. “Percent G” just means
generic floating point number. But you don’t want
to do that, okay? What you want to do
is use this method in NS number formatter
called localized string from number, number style. Okay. And there’s
different number styles like decimal and spell out. We’ll even spell it out. Like, if you put
a four in there, it will say four, f-o-u-r. Okay, spell it out. So there’s different
formats for doing that. And that will give you back
a string that you can put in the UI that will
display the number in a way that’s appropriate
for the locale you’re in. And especially, again, a
large number like a thousand in the US might be one comma
zero zero zero point zero zero; whereas in Great Britain it
would be one period zero zero zero comma zero zero. Okay. And so this
would get that right. Then there’s parsing
numbers, reading them. You really probably want
here to just say int value or float value of a
string, which will parse it and try it interpret a float
or an int as the input. But that’s not really
the right way to do it. You should use the
number formatter here. So you just create a formatter,
set the style of number that you’re trying to read in — same thing as we
saw above there — and then you’re going to get
the parse number as in NS number by calling number from string. Okay? And that’s going
to look in that string, parse it like a currency
or just a decimal number. And so if the person types in one period zero zero
zero comma zero zero, you’ll get a thousand if they’re
in the Great Britain locale. Make sense? Whereas in the US you
wouldn’t get that. One period zero zero zero
probably will give you one or might even give you nil because that’s not
really even a number. Dates — another complicated
one you have to be careful of. All I’m going to say about
dates is familiarize yourself with the concept
that our calendar, the Gregorian calendar, is not
the only calendar in the world. Okay? There are other
calendars out there. And there’s mechanism in iOS
for dealing with all of them, but you have to know
how to do it. I can’t cover it all
in one lecture — even if I had a whole lecture
devoted to it probably. But you want to look at
classes like NS calendar, search through the
documentation. Kind of familiarize yourself. If you’re really going
to do a multi-language, multi-locale application, and
dates are part of your UI, you really want to understand
what you’re doing there, okay? For formatting simple dates
there’s this nice method, localize string from
date with the date style. You can get away with a lot
by just using this one, okay? But if you’re doing anything
more complicated with dates like you’re writing the
calendar app or something, then you obviously want to
really understand dates better. Strings, an interesting thing:
If you’re searching in a string, okay, especially if you’re
searching case insensitively to try and find a word in
a string, you don’t want to use the range
of string method; you want to use this
range of string method — range of string options
range locale — and pass the current locale. And this is especially true
with case insensitivity and when diacritics are involved because different
languages treat the diacritics differently. Okay? And case sensitivity
is different in different languages. So you would definitely want
to use this method for that. UI image is kind of
an interesting one. What if you were writing an
app, some kind of driving app or something like that
and you have a stop sign? The stop sign is pretty much
the same in almost all locales. So you’re good to go. But other signs, like yield
signs and things like that, can be quite different and your
user wouldn’t even recognize a yield sign in their locale. You might want to
have a different image and have the image
be localizable. Okay? Really easy to do. You just put the image
for each locale, you know, in its lproj — sorry — for
the languages in its lproj and then you pull it out. But even there, if
you have a language that might have different
locales that have a different sign
with the same language on it, amazingly stop is
“stop” in most languages, even though “stop” is
obviously not a word in French. If you go to France, you’ll
see stop signs that say “stop,” which is kind of strange. But there might be locales
where things are different, so you might have to do a
little extra work on top of UI image image named. Okay? You might have to say,
“Oh, if I’m in this locale, then it looks like this.” Now, again, that’s only if
you’re doing an application that has imagery like road signs or whatever that’s
very locale-specific. Okay? That’s something a
localizer will hopefully help you. All right? You’ll put a yield sign
up, and they’ll say, “Oh, wait a second in” — you
know, I don’t know — “Sweden that looks different.” Or, you know, “In
Afghanistan it’s this.” And so your localizers
will hopefully help you. But UI image, image named will
look in the lprojs for you. Okay? You might still have
to locale on top of that. So the demo we’re going to do here is internationalizing
PhotoMania. So I’m going to start with
the PhotoMania that we had at our last lecture, last week. So here’s PhotoMania. And PhotoMania is UI here. It’s amazing, it’s actually
pretty easy to localize because PhotoMania, primarily
what it displays is its content. Right? If you look at
almost all of this UI, it’s just only displaying
what’s coming back from Flickr. It hardly has any
other text in it. That’s actually very
good UI design. Generally, you want as
high a percentage of the UI to be what you’re displaying —
so if you’re photo viewing app, you would want photo
everywhere and just a little bit of controls around the edges. But there is a couple of places. You can see this guy right
here has quite a few strings in it right there. And there’s some miscellaneous
strings that we load up as part of these prototype cells that
might need to be localizable. But let’s start, like I
said, with adding the ability to have these other languages. And we do that by clicking
here to edit our project. But again, we don’t want to be editing the target;
we want to edit this. So this is something right here. Don’t forget this
step right here. We want the project. And when we do that, now you’ll
see there’s localization. Here’s the localizations
down here. And we are going to
use base localization, which means our storyboard
is going to be our base and we’re going to modify
the strings after that. So I’m going to add French. So let’s add French. It’s asking me, “What
existing stuff do you want to make strings files for?” And I’m just going to say
all of it, all my storyboards and don’t worry too much
about info P list dot strings. There’s a little bit
in there to localize, like your app name can
actually be localized. But most of your stuff
is in your storyboard. So we’ll have both storyboards. And when we do that, it
just adds French here. And if we look up
here, look at this. Now this has a little
triangle that, if we click it, we get to see that
there’s the base storyboard and now there’s string
files for French. Okay? So here’s what a
strings file looks like. It’s got a comment
to the localizer, and then a key, and
then a value. Okay? Now, these
keys right here, how do we know what
matches up with what? Well, most of the time we can
look at the value like done. Well, we know that done is
this done button — easy. But look at title. See, there’s two, three titles. There’s a title right here and
there’s two title right here. It’s like which title is which? Which is this? And which is this title
right here, for example? And you can find that out by
clicking on any of the titles. Like, let’s click on this one because we do definitely
want to localize this one. Go over to the inspector, go
to the identity inspector — it’s part of its identity — and you can see that all
objects have an object ID in a storyboard. You see that? So this one’s 65EYS hit. So that is this one. Okay? So this one is the title
that is the title of that. Now, these other two titles, we
don’t even need to localize them because they are in these
prototypes here, okay? These two prototypes, so they
never appear on the UI, right, these titles and subtitles. We always drive them with whatever our data
source is for our table view. But this one we do
need to localize, and then also this
little subtitle one here, too, which is QCJ. This one also needs
to be localized. So what does it look
like to localize these? Let’s say I’m a localizer
and I’m localizing it. Unfortunately, I don’t
quite know enough French to localize this. So I’m going to show you a
kind of cool way to localize — which is good for testing —
which is just to put a period between every letter like that. Okay. So do a localization
like this as a developer because it’s easy for you to do. Okay? You don’t have
to know the language. And what’s cool about this
is it makes everything wide. So it’s going to
really challenge your UI to make things fit when you
change these strings, right? It might even work for German if
you do this because German tends to be very long words. And it’s also, again, really —
you can do it really quickly. Let’s go ahead and localize
this entire file by doing this. Oops. And another good thing
about this is everywhere in the UI that this appears, it’s going to be really
obvious immediately. Oops. I forgot that one, right? Because this period’s very,
very easy to see in the UI. So we don’t need to do these
two titles or this subtitle. We don’t need to do this because
that’s just a placeholder. We want this subtitle
down here, though, because that’s the
other subtitle. We want this one, too. And so the little URL guy here. And cancel. Okay? So we’ve localized
this entire thing, everything that needs to
be localized to French. And you might even —
when you send this off to the localizer you might even
take these things out of here. So the localizer
on this one, too. The localizer doesn’t even
get confused, you know, like, what’s going on. However, there’s some
arguments to leave them in because you’re going to put that little NS show
non-localized strings — the user default
I talked about — on, and then you’re going to
complaint about all these ones. So its kinda, 6 in one hand,
half dozen in the other, if you want to do that. All right. So now we’ve localized this. What does it look like? So let’s run this and see. All right. So when we run this
UI, it all looks like it’s in English, right? And in fact, if we go over to
our little add photo guy right here, this all looks
to be English and everything looks fine. Okay? Nothing has changed because we’re not
running in French. We’re still running in English. So the base storyboard
is still showing through. Okay, that’s good. That’s a good thing to check, to make sure you
haven’t broken anything by adding a localization. But now let’s go and change
the language to be French. So you do that, you can
do it in the simulator and you can do it
on your device. And you just go here to general,
international, language — we’ll change it to French. Okay. It’s changing
the language. Your application, if it
was running right now, would get that notification
that we talked about that says, “Oh, this has changed.” So you could redraw your UI. But let’s go back and run
here and see what we get. So here’s photographer. Hopefully this is going to
fill in with its normal data. Yes, it does. Let’s go over here
and look here. And you can see that it has done
our little dot language here. We switched it to French and it’s done our
little dot language, but we can’t really
read everything because nothing fits, right? Subtitle doesn’t fit, title. So this is good that it
doesn’t fit, and this is part of the advantage
of doing the dots. Also notice this. This is all still in English. So that’s no good. So let’s fix these things. The things not fitting
is quite easy to fix. We’re just going to go to
the storyboard right here, and I’m going to reset
to use Auto Layout. Okay. Now when I dragged
all these things in, I believe I used the blue lines. So when I reset to suggested
constraints, I think I’m going to get suggested
constraints that work. So let’s go ahead
and take a look. Enter enough and you can see
now all these things fit. See that? Cancel
fits, done, title. Okay? So we did a good
job with our Auto Layout. So Auto Layout is a fundamental
part of localization. Fundamental. Okay? If you don’t have
your Auto Layout right, you cannot do localization because when you
change the strings, everything will be cut
off, and dot dot dot, and all this bad stuff. But what about this
English right here? We got to fix this, we
got to get rid of this. And these are actually
not in my storyboard. These strings, like “Okay,”
and “Add photo,” and “Sorry, this device cannot add a photo,” those are all literal
strings in my code. So let’s go localize those. And those are all in the
thing we added last week. So hopefully you remember
some of this code, which is add photo
view controller. Okay? So here’s add
photo view controller. So one thing I like
to do in anything that I implement is
search for at sign quote. Okay? Because at sign quote is
going to be literal strings. Now, not all literal
strings need to be localized. Okay? But like, this
one does, and this one, and this one, and this one. This one not; this is
a segue identifier. Never appears in the UI. Does not need to be localized. This one also not; this
is the name of an entity in the database — or at least
in this case we don’t put this in the UI, although we do
somewhere else in the UI. A little preview of what
we’re going to do later. And then, of course,
all of these need to be localized, right? This one also. All these things do is alerts. This one not; this is thumbnail. This is just a little
file extension for our thumbnail URL —
never appears in the UI. Here’s another one that
never appears the UI. This is how we’re making
a unique document URL. So here we don’t need to
use a number formatter and all that business. And then here’s some
more of the filter stuff. Notice in the filter
stuff this does not need to be localized, but this does. This appears in the action
sheet; this is just used in the code behind the scenes. So we only have to do these
chrome, blur, noir, and fade. Okay? So that’s the stuff
that needs to be localized. So how are we going
to localize that? Let’s pick one of these. How about let’s pick this
one right here: “Sorry, this device cannot add a photo.” Because we know that’s
going to come up right away. So how would we localize this? Some of this is art of
programming; some of it is kind of what’s a way that’s really
going to work effectively? But I think one of the best
ways to do this is to get rid of this literal string
and replace it with something you
pound sign define. So I’m going to call this
one “Alert can’t add photo.” Okay? And I’m actually going
to put a little comment here and paste that thing back so I can remember what
I originally intended to say in English. And then I’m going to
add a pound sign define for this alert, can’t add photo
that’s an NS localized string — that macro NS localized string. In fact, NS localized
string from table. So I’m going to put those up
here in my alert section here. So I’m just going to pound
sign define can’t add photo to be NS localized
string from table. So I have to give it the string. And here, one thing you could
say here is you could put the English version here. And a nice thing about putting
the English version here is that if you don’t localize it,
you’ll get English at least. But I actually don’t
believe in that strategy because if I’m French and I
get English, it looks bad. It makes my app look bad. It’s almost better
to get some kind of internal thing that’s like,
“Oh, this app is broken.” It will be found in
testing right away. There’s many places that
you would ship your app to get offended if you
throw English in there. They’re kind of like,
“Oh yeah, English. Great.” You know what I mean? So it’s almost better
not to do it. Also, there’s another problem
here, which is that what if this word is a simple
word like “alert” or “yes”? Okay? Well, there can only be
this key into this table once. And so if that yes might want
to be two different words in a different language, there’s
no way to distinguish them. Okay? You would just
yes would be the key, and you can only convert
yes to “oui” or whatever, but you can’t do anything else. So what I do is I
actually put this — this internal define
— into here. So that’s the key. What that means is I have to
provide an English dot strings because otherwise this is
going to appear in the UI because that’s the default. Okay? So I’m going
to have to do that. I also am going to give the
comment for the localizer here, I’m just going to say, “This
is message given to user if the user tries to add a photo but there is an unrecoverable
problem.” Okay. Because that’s
when this is shown. This can’t add photo
happens right here with when can’t add
photo returns no. So this is something like, “I
can’t get where your location is on Earth, but it’s
because you’re restricted. So there’s nothing you can do
about it” or “There’s no camera on this device, so there’s
nothing you can do about it.” So — oops, wrong button there. So it’s an unrecoverable error. So I’m trying to explain to the localizer here what
this message is about. And I’m also going
to put it in a table. I’m using localized string
from table, and I’m going to call the table the “add
photo view controller table.” Okay? So that means that when
I run that genstrings thing, it’s going to generate a strings
file called add photo view controller dot strings. And that’s where it’s
going to put this. So I’m kind of collecting
all the strings for this particular
view controller into one strings file. I could separate it
even more fine grained, or I could put all the strings in my whole app into
one big one. That’s possible, too. Yeah?>>Would it be beneficial to
pass the original string along to the localizer somehow?>>Yeah. So the question
is: Would it be beneficial to let the localizer
see the English string? Absolutely. And when you send this
French dot string — French version of the strings
— off to the French localizer, you’ll want to send the English
one, too, so they can see, “Oh, I see what this is in English.” And in fact, when we do our
localization we’re going to start with the English
one and we’ll go to French. So there’s that one. Now, so I’ve localized that
one string right there. But I got a lot of
other strings in here. So to make this go a little
faster I have a snippet here that does the rest of
the pound sign defines, which I’ve called strings yes. So here it is. So these are all just
pound sign defines for all the other things —
actually, I guess I already did that one so we’ll do that. So you can see that they all
are the same format, right? I’m using the same thing there,
using photo view controller. Actually, I had the arguments in a different order
there so that was wrong. So table comes first;
comment is last. So I put all these in here. And then I just need to
go through with my code and use these things everywhere. So like this one, add photo, is
alert; title; title; add photo. And this one down here is alert;
dismiss button; same thing here, and here, and here, and here. Okay? So I just need to do
that for all my strings. Again, for speed here
I’m just going to do it for this method all
in one spell. So you can see all
the strings in there. Now they’re all changed,
okay, to be like this. Same thing down here
with filtering. So we’ve got a lot of
things here in filter — title of action sheet, cancel
button — all these filters. So I’m going to replace
that as well. Filter localized. There we go. Okay? So same thing there. I’m doing the same strategy. Okay? So everyone
understand what we’re doing with this NS localized string? Any questions about that? So now we’ve localized our
app here, but now we need to create this strings
file and then localize it. So how do we create
the string file? That we do with this
genstrings thing. So let’s go get terminal. So I’m going to run
terminal here. This is one of the only
time I think in this class that I’ve asked you to do that. But here I am in my
home directory here. I can do LS. Here I am. So I’m going to CD to developer. Okay, here’s my developer. I’m going to CD to PhotoMania. Now I’m in the top
level of PhotoMania. I’m going to CD inside that. Here’s all my code. Okay? See all my dot M files? And here you can even see my
lprojs for my storyboard there. So the way I’m going to generate
the strings file here is I’m going to say genstrings star
dot M. And that’s going to look at all my dot M files, look at all those NS localizer
string macros, and it’s going to generate strings
files for all of them. So we did it. Let’s take a look. Start out strings, and sure
enough there’s add photo view controller because we used
that for all the tables here. If we didn’t — say, if we
used a different name here or we didn’t do from table, then it would have
generated other strings files. Okay? But this is
the only one we did. All right. So now let’s just
drag that thing. Let’s go find it. Here it is. This is the strings file. Add photo view controller
strings. I’m just going to drag
this into my project here. Put it right here. Usually we put our strings
file all under view. If we kind of arrange our
storyboards into a place, we’ll put the strings file
there as well because it is part of our view, really, the
localization of our view. And so now we have this add
photo view controller strings. And sure enough, see, it’s
got all these things — this equals that. Okay? Make sense? Now we need to make this
strings file localizable. We go over here to
the file inspector. This one right here
is file inspector. And I got the strings
file selected. I’m going to hit localize. Okay? It’s going to say
“What language is this?” And that’s going to be our
base, and then we’re going to have English and
French created off of that. So I’m going to leave
that be base. So I’ll hit localize. Now when I select
the strings file, instead of having a localize
button, it shows me a list of all the localizations
that I had set up in my project settings. So I’m going to add an
English localization and a French localization. And when I do that, I get a
little triangle over here. And you can see here’s my base. And now I have English
and French, which it has copied
the base to start. Okay? Now I would
localize this to English. So let’s localize
this to English. I have a little snippet for
that, too, somewhere here. PhotoMania,
internationalization. This one’s English. Here it is. Select all, copy, paste. Okay. So I’ve just
made English — the English versions
of all of these things. Everyone understand
what I did there? Right? And then French,
same thing. I could take all these
and put dots in here, but I did that offline
to save us some time. That’s this. Copy, paste. Okay. So I’ve localized
this to French dot French. Okay? So now we have
localization for that. And so now when we run — okay. So when we run, now we
still have some stuff left to localize here. Right? You can see that these
things are still in English. But if we go over to
here, look at this. [Inaudible] we already
saw that from last time. I forgot to mention that maybe. But the maps part of
it is all localized. And when we go over here,
we have all these dots. And now we have these
strings also localized. The add photo here. Okay. Okay? And if we go through
and checked them all, all the other ones would
all have the dots, too. So we’re making good
progress here in terms of our localization. Couple of things, though,
not localized here. One, my photos, right? In French that would be I don’t
know, [inaudible] or something. I don’t know. Actually, it would be M
dot Y, P dot H dot — okay. So we would need
to localize that. Where is that? That is here in photographers. Actually, no, that’s in —
sorry — that’s in core data. Photographer create. Right? So that’s just
a literal string. So we would probably localize
this with NS localized string. Not going to do it because
I’ve already showed you how to do that. What else do we have
that’s not localized? This little line right
here, zero photos. Okay? That’s actually probably
correct in real French. I think photo is French; in
French it’s photo as well. But we want to make sure
that was localizable. That’s another reason we
should do the dot thing because it would be obvious
that there’s no dot here; whereas if you’re just checking
it with French, you’d be like, “Oh yeah, that’s localized,”
but in fact, it’s not. So where is that? That’s down here in — that’s
the one that’s in photographers. You can see it’s just a string with format thing
here for table view. So we would want to do another
NS localized string here, right? And then there’s one other
thing that’s in English: This word “photographer”
right here. Now, you might be surprised;
where does this come from? This is actually being provided by core data table
view controller. Okay? That class that we
gave you many weeks ago. And what happens here is core
data table view controller, when you set a fetch results
controller, it checks to see if your table view has a title. And if it doesn’t have a
title, then it sets the title to be the entity name —
photographer or photo. Okay? Now, this is an
interesting one to localize because I can’t use NS
localized string here. Everyone understand why? Because NS localized string,
all the arguments have to be literals — at
sign, quote, something. So how am I going
to localize this? Well, we can go one level
below the NS localized string to the bundle thing. So let’s take this string. I’m going to take
it out of there. I’m going to go NS bundle, main
bundle, localize string for key. Okay? This can be a variable. So I’m going to make
it be that entity name. The value, this is
the default value if it can’t find that string. So I’ll make that
be the entity name. And then table, this is the
strings table to look in. I’m going to call it entity. So this is a new strings table that I’m going to
have to invent. So how do I invent
this strings table? I can’t use that
gens strings thing because all gens
strings does is look at NS localized string,
those macros. Okay? How am I going to make
a strings file for this? Well, I’m going to use new file. So when you do new file, if
you go down here to resource — you see resource right here — you’ll see that there
is strings file. So I’m going to create a new
file, call it strings file. I’m going to call it entities;
that’s what I said I called it. I’m going to put it where
I keep my view stuff, okay? And I hit create. It makes it, it right here. Entities dot string. I’m going to make it
localizable, the same way as I did the other strings file. That will be our base,
which is nothing. Okay? And then I can say, “Well, I don’t need an English
localization because the names of the entities in the
database are in English.” So I don’t need one. But French I do. Okay? So I’m going
to make a French one. Now if you go over here and
look at French, here it is. And now I can just
say photographer equals photographer. And we’ll put our dots in here. Dot, dot, dot, dot. Whoops. Dot. Okay. So we’ve translated
that to French. And now when we run, we’ll see that we get photographer
along the top here. Okay? So that’s an example
of where you need to localize by actually calling
the bundle thing, as opposed to NS
localized string. Question?>>When you did the macro for the NS localized
you [inaudible]. If I have two dot M
with the same string, could I put that in
the dot H [inaudible]?>>Yeah. Great question. So the question is: When I did
these NS localized strings here I put them in my dot M —
photo view controller dot M — see how I put them
all right in here? Could I put these in a dot H
somewhere and then import them and share them between two? The answer is absolutely
you can do that. When you do genstrings, it’s
legal to put a dot H file there. In fact, genstrings will look
in any file you want, right? So yes, you can do that. All right. So that’s it for localization. I’m just kind of skimming
the surface as far as of localization, but I think
this is a really important one to know if you’re going to
ship a product on the app store because you can really
open up your market by having it localized. It’s not that expensive to have
these strings files localized. Really, more of your cost
is sometimes just QA-ing it. You got to put something
that’s in French in front of French users and make sure
that it uses the right idioms and that it’s understandable. And, you know, if you get a good
localization company doing the localization for you,
they’ll do the QA as well and make sure that, you know, it’s actually user-tested
as well. Okay? All right. Back to the slides. All right. Okay. The last thing
we’re going to talk about here is settings, okay? So settings allows you
to add user interface for your application into
the general settings app. So you can see the screen
capture at the bottom there, that’s the general settings app. And if you scroll down towards
the bottom of very first page of settings, you can see all
these other apps, like Maps and Safari and even
third-party apps — Twitter, Facebook,
Flickr, whatever. Actually, I’m not sure
those are third-party apps; they’re probably iOS 7’s
integration to those things. But your apps could appear
at the bottom of this list. And when you click
on one of those apps, it goes to the next view here. And I’ve shown two
different ones, one for Maps and one for Safari. And you can see that there
are some UI in there. We got some switches, we can
choose from a predefined list of things like where it
says search engine Google. You can click on that and
have a list of things. You can also have
sliders in here. You can group things, etc.
So this UI you can build for your app and have
the settings app do this. This UI is basically a UI
on top of NS user defaults. Okay? So these things — all
these things in the UI — are setting NS user defaults. That’s all they’re doing. And that’s how it’s
communicating with your app, okay? So it’s as simple as that. There’s really not a lot
of UI you can put in here. I’m not going to talk about
all the things you can do. You can look in the
documentation for that. But like I said, sliders,
switches, text fields, typeable text fields,
and also selecting from lists are the main things. The way you add this to your
app is in your app, okay, you go into Xcode
and you say new file. And then under resources
you pick settings bundle. This is the same place we went to add a strings
file a moment ago. Now we’re going to
do settings bundle. And when you do settings
bundle you’ll get this little settings bundle. Add it to your file
navigation there. You can see it. And it’s going to give
you a default kind of an example bundle,
which is really nice because it’s a good starting
point to get started, and what can I do
with this thing? All that UI that you’re going
to build, you don’t build it in a storyboard, you
don’t build it, you know, with graphical interface; you
build it using a property list. Okay? And this property list has
well-defined keys and values. And these keys and values
determine whether you’re doing a text field, or a slider, or
grouping things, or whatever. So you can kind of
see up here some of the property list things
you can set to build this UI. For example, what
you see on screen, I’m going to show
you what that looks like in the settings app, okay? So you see you got a
group is item zero. So this thing is
going to be grouped. The name of the group is
“group,” so it’s going to say group at the top. And then we got a text field,
a toggle switch, and a slider. You see items one,
two, and three? The text field there, you know,
using the alphabetic keyboard, it doesn’t do auto correction, etc. The toggle switch,
its title is enabled. So it’s going to say enabled,
and then there’s going to be a toggle switch there. The slider looks like it
goes from a zero to one. And for all three of them, do you see how it says
name underbar preference, enabled underbar preference,
slider underbar preference in each of those three things? That’s the NS user default
that it’s setting, okay? I don’t really like
those names very much, but that’s what it’s setting. So what is this going
to look like? What would this particular
thing look like? Well, it would look
like this, okay? Grouped, name, enabled with a
switch, and then the slider. Okay? So localization. Let’s talk about
localization settings. You’ve got to have
localization for setting, otherwise when a person’s
French they’re not going to understand how
to do your settings. And it’s done using
strings files. And if you look inside
the settings bundle, you’ll see it comes
with an EN dot lproj; little bit of English
bias there, I think. And in that EN dot lproj — actually, might not
even be English bias. It’s possible that if
you’re developing this and you’re French, it might
create an FR dot lproj for you. I’m not sure, I’ve
never tried that. And then inside this
string’s file is every string that would appear in this
UI that you’re building with equals whatever
it’s supposed to be. Okay? So whatever’s in that base
P list we saw two slides ago, anything that would appear in the UI you can just say
it equals something else. And then you can have as many
dot lprojs as you want here — French dot lproj, whatever. The bad thing is
there’s no way to go to the file inspector
and hit localize. Okay? For some reason
they have not gotten around to having the settings
bundle be localizable in Xcode. It’s got the mechanism there, but there’s no inspector
UI to do it. So how do you localize
this thing? How do I create an FR dot lproj? And the answer is you’re
going to go to finder and find this settings bundle. You can actually
do that from Xcode. I’ll show you how to
do that in the demo. Then you’re going to right-click
on the settings bundle and say show package contents. And that’s going to
show you what’s inside that settings bundle, which
is going to look like this. And you’re going to see
the EN dot lproj there. And now you’re going to
manually create an FR dot lproj. Okay? Really nice
support for it here. And usually I do this by
taking the EN dot lproj and just copying and pasting
it and then renaming it from EN dot lproj
copy to FR dot lproj. And then the root dot
strings that’s inside there, that’s what I would send
off to my localizer. Okay? And that would do the
equals thing for French. So let’s see what this
looks like in Bouncer. Okay? Because Bouncer has some
nice settings that we could set. And what I’m going to do is
make it so the elasticity — you know, the bounciness
of the bouncing ball — is settable in settings. So right now we have the
elasticity set at one, which is kind of the maximum
elasticity that it can have and still settle down. If we had more than one, it
would start getting faster and faster as it
bounced off the walls. It would be more than an
equally elastic rebound. So we’re going to
make it so we can set that elasticity anywhere
from zero to one. Okay? Zero would mean just kind
of hits and dampens immediately. All right. So let’s go get Bouncer. Bouncer. Here’s Bouncer. Okay. Bouncer has not changed
since last it was posted. The elasticity is here, this
elastic, dynamic behavior. And you can see that
we set it to one, okay, by default right now. So we want to be able
to set this elasticity from the settings app. So let’s build the UI for it
first, and then we’ll have to change our code to
use the NS user default that our UI’s going to set. So to do the UI we just do new
file, go to the resource section of iOS, settings bundle. Same place we did strings file
right here, settings bundle. Create the settings bundle. You can call the bundle
whatever you want. Doesn’t really matter. I’m going to call it settings. Here it is. Here’s the settings bundle. And this root dot P list
is what the bundle is, and you can see it
has four items here. Again, group, text field,
toggle switch, slider. Okay? So you get this — every time you create a settings
bundle you get this one. Let’s go ahead and see
what this looks like. Let’s do this over here. [ Pause ] So here’s our Bouncer, and you
can see it’s got full elasticity — bounces pretty good, right? And if we go over to the
settings app right here, if we scroll down to the bottom,
you’ll see that in addition to these other apps,
there’s Bouncer. Okay? If Bouncer
had a nice icon, the icon would look better. But if we click on
Bouncer, here’s the UI. So we got this slider right
here that we can move around and we’ve got the
switch to turn off. But none of this is connected
to Bouncer in any way; this is just the
default stuff we got from creating the settings app. So what I’m going to do is
I’m going to keep the slider, and I’m going to have the
slider go from zero to one — elasticity zero to one. I’m going to get rid of this
enabled switch right here. I’m going to get rid of this
name text field right here. And I’m going to keep the
group, but instead of calling it “group,” I’m going to
call it “elasticity.” So I’m going to have this
really simple UI here that says elasticity
and then has a slider. All right? So let’s go here. Let’s get rid of
this text field. Let’s get rid of
this toggle switch. And so I’m keeping the
group and the slider. I’m going to rename the group
from group to be “elasticity.” And then in my slider let’s look
at some of these things here. Okay, the maximum value is one. That’s good. Okay? That’s maximum
elasticity I want. Minimum zero. So that’s good. I don’t need to change that, but you can obviously
change these things. The default value of .5 — no,
I really want my default value to be one because that’s what
my default value was before, and I want it to start there. And then this is very
important, slider preference. This is going to be
the NS user default that communicates this back. And I’m going to call this
settings underbar elasticity. Okay? When I do the names
of NS user defaults, I like to name scope them,
like, with the name of the class and then an underbar and
then all the items in there. So you kind of give it a
little bit of protection against the same name thing. Here, since this
is set in settings, I’m going to scope
it to be settings. Okay? We could argue there
are better ways to do that. But it’s a simple way to do it. So this is going to be the name of the NS user default
we want in our code. So now let’s go back
to our code and use that NS user default
instead of 1.0 here. So I’m going to get
rid of this 1.0. And in fact, I’m
going to add a method to do this called
reset elasticity. And let’s write that method. Oops. Void. Reset elasticity. And here I’m going to get the
user default right off the bat — NS user default. You know how to do this. Defaults. Standard user
defaults, value for key. And the key is settings,
elasticity. Okay? Again, probably want to pound sign define
there, whatever, yes. But for demo we’ll go here. I’m going to say if it’s set — because it might be that
that’s never been set; no one’s ever gone to the
settings app and set this so it might just
not even be set. So if it’s set, then I’ll do
one thing; if it’s not set, if no one’s ever gone into
settings, then I’m going to set my elasticity to be 1.0,
which is what it was before. But if someone has gone to the
settings app, then I’m going to set my elasticity to be
this elasticity’s float value. Simple as that. Okay? Now, this works
great the first time we ask for the elasticity. But what if someone goes over to
settings while my app is running and changes the elasticity? Okay? We need to
find out about that, and we do that with
a radio station. Okay? So we’re going to listen
to another radio station. We’re already listening to two
radio stations in this app — the resign and become active. So I’m just going to add another
radio station listener here. Notification center,
default center. And then a little
Star Wars there. And then we’re going to
add observer for name. Okay? And this thing
we’re going to — radio station we’re
going to observe — is called NS user defaults
did change notification, exactly what you would
think it would be called. Okay? And we don’t
care who is going to tell us that it changed. And we can do it on this queue. It’s fine. And what are we going
to do when it changes? Well, of course, we are just
going to reset the elasticity. Okay? And that’s why I put
that in a separate method. Okay? So it’s going to call
this, it’s going to read that user default,
update the elasticity. As we know with the dynamic
animator, as soon as you change that elasticity, it’s going to immediately start
affecting the elasticity. Okay? So let’s go
ahead and try this. See if this works. [ Pause ]>>For the slider,
whats the granularity?>>Yeah. So the question
is: What’s the granularity of the slider as we move along? And it depends. If it’s a float, then however
wide the slider is, you know, however many points that
can be divided into, that’s how much granularity
you’re going to get on the float. If it’s an integer — you know,
if you’re making integer — then you’re going to be rounding
off to the nearest integer, right, as you get it
from NS user defaults. But basically granularity
depends on the width available. So it’s actually going
to vary per device. Right? On a wide device you
can get a higher granularity. All right. So here we are; elasticity
is default. Okay? So — oops. This guy’s hard to control. Okay. So we had normal
elasticity going on here. So now I’m going to go
out to the settings app. Okay? I’m going to
go down to Bouncer. Here’s Bouncer’s elasticity. It’s at one. I’m going to crank it
all the way down to zero. Okay? Which is really
low, it doesn’t matter. And let’s go back to Bouncer. And now when this thing
bounces, doesn’t bounce. Okay? Low elasticity. Okay? Make sense? And then we can go back again. Change the elasticity
back to being high. Back here to Bouncer. And now back to bouncing. Okay? Make sense
what we did there? Now, one last thing
I want to show you about this is localization. So here we have settings
elasticity. Well, that’s correct
because we’re in English. But what happens if we go
and change the language here? So let’s go change to French —
international, language, French. All right. So now when we go back
to settings and we go down to look at Bouncer. Okay? So we go back here and it still says
elasticity even though I’m in French right now. So this is all in French. Okay? So we got this all in
French — nice, excellent, all in French, except
for Bouncer is English. Okay? So this person is
immediately deleting Bouncer, this French person
deleting Bouncer because of the English bias. So how do we fix that? Well, we go down here. We want to change this
root dot strings right here to say elasticity
equals elasticity. So this is what we
would want in English. And in French we’d want
this to be the French word, or the dots, or whatever. So how are we going to do this? And this is where we have to go out to the file system
and do this manually. So the way you can go out to the
file system is you select the settings bundle,
right-click on it, and you can see the very first
thing here is show in finder. So I’ll show in finder. Here it is, but it doesn’t
have a little triangle. That’s because it’s a package. Okay? But I can right-click
and say show package contents. Now it will show me
what’s inside of it. Here’s my EN dot lproj. I’m just going to
copy it and paste it. So now I have EN dot lproj two. So I’m going to rename
this to be FR dot lproj. What’s really kind
of interesting about the way the finder works with apps is this will
all be appearing in Xcode at the same time that
you’re typing it. So you don’t have to do
anything special there. As you create these
directories and rename them, Xcode keeps track of it. So here’s the root
dot strings for French and here’s the one for English. So in the French one let’s
change this to our dot. Okay? Oops, sorry. I wanna make sure
this is…okay. So we change this to the dots. And now let’s — yeah. So now let’s run this. Reinstall this Bouncer,
including its settings bundle. All right. So here we have Bouncer. Let’s go over to settings,
look at Bouncer settings, and now we have elasticity
with the dots. Okay? All right. Questions about any of that? Yeah?>>If you have settings in your
app that are frequently used, should you refrain
from also putting them in this [inaudible] settings?>>What a great question. Okay. So the question is:
If I have settings in my app and the user frequently
wants to change them, like let’s say elasticity
is something that, you know, every game you want to play
with a different elasticity or something like that because,
you know, it’s not something that you just kind
of set to taste and then you just leave
it, then you would not want to use the settings app. Okay? Settings that the user
wants to set on a regular basis, that are a normal
part the operation, those want to be in your app. So we would want to have some
way here in Bouncer to be able to set the elasticity — maybe
a gesture, maybe, you know, we’re not using pinching. Maybe pinching could
do it or something. I mean, if it’s something
you want to change a lot,
you want it here. Okay? Or you have a
title bar across the top and have a bar button
for it or something. Really, the settings
app is set it and forget it kind of settings. Right? Settings that are just
maybe something a user tunes that they like and
then it’s set. Okay? It’s not going
to be things that you’re going
to set constantly. Question?>>Suppose that you did have
a way to set them in your app, should you specifically
not put them in your extra settings place?>>Yeah, so the question
is: If I did have a way to set elasticity in my app, should I definitely not
set them in my settings? I would say not necessarily. Like, for example,
you might want to — let’s say elasticity
is something you change with every game. Like, you say new
game and it says, “What elasticity do you want?” It’s possible you might want to have setting apps set the
default elasticity, right, so that when it asks you
about the elasticity, it starts with that default. So it’s possible you
might want to have that. But generally you don’t want
the user confused about, “Where am I setting this? Am I setting it in settings,
or am I setting it here?” So even in that case in
settings you’d probably want to call it default elasticity, and then here you would
call it elasticity or something like that. So good questions. Any other questions
about settings? Okay. So both localization
and settings, you know, there’s obviously a
lot you can do here. And so I’m just kind of trying
to skim the surface enough so that you understand
where to get started, okay, in terms of “How do I make
different UI in settings, and what do I do to make my
app international-izable?” Okay. So that’s pretty much it. Here is just a reminder
of what’s coming up. We talked about this
at the beginning. If you have any questions
about your final projects or about anything
else, I will be here. And I will see you on Wednesday.>>For more, please
visit us at Stanford.edu.

One thought on “Stanford University Developing iOS 7 Apps: Lecture 18 – Localization, Adding UI to Setti

  • July 28, 2018 at 4:00 pm
    Permalink

    59:39 Epic 😀

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *