Streaming is available in most browsers,
and in the Developer app.
-
Unlock the power of grammatical agreement
Discover how you can use automatic grammatical agreement in your apps and games to create inclusive and more natural-sounding expressions. We'll share best practices for working with Foundation, showcase examples in multiple languages, and demonstrate how to use these APIs to enhance the user experience for your apps. For an introduction to automatic grammatical agreement, watch “What's new in Foundation” from WWDC21.
Chapters
- 0:00 - Introduction
- 1:28 - Grammatical agreement
- 3:12 - Dependency agreement
- 8:07 - Inclusive language
- 11:05 - Demo
- 17:31 - Wrap-up
Resources
Related Videos
WWDC23
WWDC22
WWDC21
-
Download
♪ ♪ Alla: Hello, my name is Alla Shashkina, and I am an engineer in the Internationalization team. I am here to help you with language. Today we'll unlock the power of grammatical agreement. Language in software impacts our daily interaction with it. The words in your app matter. Handling language in software can be hard, especially when you don't speak that language. In 2021, we introduced new APIs in Foundation that help your apps with grammatical agreement. Today, I'd like to introduce new features in Foundation that will unlock a different level of user experience for your apps through natural language that is grammatically more correct, better sounding, and more inclusive. So let's dive in.
We'll start with a very short recap of why we think handling grammatical agreement is important. We'll walk you through different examples in languages that we've added support for since 2021. We'll talk about new APIs in grammatical agreement space and introduce dependency agreement. We went one step further and asked ourselves, how can we help you make the language in your app not just more grammatically correct, but also more inclusive? Grammar should not be something you should worry about when you build your app. We believe well-designed APIs can help ease the linguistic complexity and help you scale. Rich and grammatically correct words in your UI make the user experience flawless and enjoyable. Different languages present their own set of challenges. All of this linguistic complexity is what we take into consideration when we design new APIs. Our goal is to pack all that into simple, easy-to-use interfaces. Let's briefly review how grammatical agreement enhances user experience throughout the system in different languages. New APIs introduced in 2021 let you specify a range of words that need to change based on users' preferred term of address, as well other words within the inflectable range. If a user selects a feminine term of address, iPhone will greet her in a feminine setting in Spanish when she's setting up her phone for the first time. Last year, three more languages joined Spanish. French speaking users enjoy a more personalized experience when they choose to select their term of address. The software throughout the system will change the words to reflect that, just like this example in the Notes app. Personalized strings are pervasive across the system experience. Setting up your phone, working with Shared Notes, or managing your Calendar, the language is adapting to match your settings, just like here, in Italian or Brazilian Portuguese.
This year, we've added support for grammatical agreement to two new locales: European Portuguese and German. Now let's talk about what's new in grammatical agreement in Foundation this year. Languages are complex, but good APIs are not. Very often, words in the UI need to change their form based on another word. To help you visualize it, let me walk you through an example from our food ordering app. This is Spanish. In Spanish, adjectives need to agree with the nouns they describe. Here, the food size "pequeño" needs to agree with the food it describes, "ensalada." This is a very common use case in other languages as well, where word agreement happens between certain parts of speech. And since these words are separated in the UI, handling this kind of agreement is not easy. We created a new API that fixes this type of dependency agreements easily. The fix is very simple and requires very few code changes.
Here, we want a string containing the food size, "pequeño," to agree with the food name, "ensalada." This year, we are introducing a new property to LocalizationOptions, concepts, which allows us to specify objects that affect grammatical agreement, but are not formatted into the strings like arguments are. We use a localizedPhrase concept for a string value we want to agree with, in this case, "ensalada." Lastly, we need to annotate the word that needs inflection with agreeWithConcept. A value of 1 here means that we are asking for grammatical agreement with the first object in the concepts array. Note that we use 1-based indexing. The agreeWithConcept attribute is also new this year, but you can use it even if your app runs on older devices. When that is the case, we will simply ignore the attribute. Now that we've introduced these changes, let's take a look at our UI.
Observe that the word "pequeño" has changed to "pequeña." This is the correct form to use when describing "ensalada" in Spanish. Now let's look at other places where we need linguistic enhancements.
Here in the sentence "Our salad contains lettuce, cheese, tomatoes and ham," the Spanish words "nuestro" and "hecho" both need to agree with the noun "ensalada." Luckily, we only need to facilitate grammatical agreement within the string, so we don't need any code changes. First, let's make "nuestro" agree with the food by annotating it with the inflect attribute. When we use the inflect attribute on a block that has an argument, it will try to make every word grammatically agree with the argument. However, there is one more word we need to inflect, "hecho." We try to keep inflect blocks as short as possible to help with ambiguity, so we cannot annotate "hecho" with inflect: true. This year, we are introducing another new attribute called agreeWithArgument.
Unlike agreeWithConcept, where you need to make changes to the code base by passing the value of the food name, the agreeWithArgument attribute does not require any code changes and is an easy way to facilitate agreement not possible with the inflect attribute. We can use agreeWithArgument to indicate that "hecho" should agree with an argument that is elsewhere in the string. Here, a value of 1 means that we want the word to agree with the first argument in the string. With these changes made, let's take a look at the UI again.
Now both words are formatted to grammatically agree with "ensalada," and we use fully correct Spanish in our localization. Next, let's look at a similar but yet different example.
This is French. In French, demonstrative adjectives need to agree with the nouns they describe. Notice that the sizes, as well as the button with the quantity, are already fixed for Spanish as we applied agreeWithConcept and inflect attributes. Let's fix this demonstrative case in French. The fix is really easy. Wrap both the adjective and the argument with an inflect: true block and let the Engine do its magic. Et voila, grammatically correct food just tastes better. To recap, dependency agreement makes it possible to change words based on other words they depend on. Use agreeWithConcept attribute when you want a word to agree with another word or phrase that does not exist within the same sentence. Use agreeWithArgument attribute for situations where you want a word to agree with another word or phrase, and both of them are in the same string.
Now let's talk about new APIs for Inclusive language. Let's take a look at our Caffé app again.
Let's say, we've picked a small sandwich and a small juice for our lunch and put in an order. Since we're really hungry, we want to check the status of our delivery. It looks like Tony is delivering our order soon. When localizing user interface, it's good practice to use gender-neutral language . At the same time, using gendered language in the UI feels more personal and sounds more natural. Let's try to personalize this string for Tony, who uses he and him pronouns.
First, we need to change the model for the delivery person to include their preferred term of address. To represent that, we add a new property of type TermOfAddress, which is new this year.
Then, we can set the term of address to any of masculine, feminine, or neutral. Since we want to refer to Tony using he and him pronouns, we choose masculine.
Next, we need to annotate the strings where pronouns need to change. To do that, we use the new referentConcept attribute.
A value of 1 indicates that the referent of the pronoun should be the first concept in the LocalizationOptions. You can apply referentConcept to any third-person personal pronoun, and the engine will figure out what to replace it with. Now let's pass a termsOfAddress inflection concept when inflecting the string. We assign this to the concepts property of LocalizationOptions, just like we did earlier for grammatical agreement. Let's see how this changes our UI in English.
Notice how "their" and "they" have been replaced by "his" and "he." You can use the same localized string to refer to other people too. Use a feminine term of address when you want to refer to someone using she and her pronouns. And use a neutral term of address when you want to refer to someone using they and them pronouns. You can also further personalize pronouns by using localized term of address. In a localized term of address, you have to specify the language it applies to, in this case, English. And list all pronoun forms that you wish to use using the new Morphology.Pronoun type. In English, we have to list five pronouns.
Each Pronoun consists of the pronoun form in the target language, and a Morphology describing when it should be used. Please refer to our documentation for detailed instructions on constructing pronouns. Using this API is a great way to enhance the personalization of your app. We use this technique to tailor the language used in localized strings in iOS. Now let me show how all these new features are working live in a demo. I hope everyone is hungry for some delicious food from our Caffè app now. Let me launch it in Spanish.
Let's see what's on the menu.
Let's order a pizza this time.
Here is the same grammar issue we just discussed. In Spanish, determiners and adjectives need to agree with nouns. To make two words agree with each other, we can use inflect: true attributes. So let's apply this easy fix to the words "nuestro" and "pizza." First, let's locate this string in our String Catalog.
To make "nuestro" agree with the argument "pizza," we enclose both of them in an inflect: true block.
Next, let's also fix the adjective "hecho" that needs to agree with "pizza" in the same sentence. We want to use agreeWithArgument attribute here. We generally try to keep the inflect: true block as short as possible to help with ambiguity. Because "hecho" is distant from the inflect block, we need to use "agreeWithArgument" attribute this time.
The value of 1 here indicates that we want "hecho" to agree with the first argument in the string, in this case, "pizza." Let's run our app again.
Now this looks like a great localization experience in Spanish. Now let's see how we can use the new agreeWithConcept attribute to fix up the food sizes here. Since pizza is feminine, the adjective that describes it should be "pequeña." We have already defined the localizedNames for the food sizes. To fix the agreement, we want to convert localizedNames into a method that agrees with the specific food item. Next, we want to pass the food name when formatting the SIZE_BUTTON. Here, we will define the new property to LocalizationOptions, concept. Concepts are objects that affect grammatical inflection but are not interpolated into strings the way that arguments are. Here, we use the localizedPhrase concept to insert the string that we want to grammatically agree with.
And we should remember to use options, which is defined when initializing the string.
Next, we want to modify our Spanish string catalog.
We want to annotate this with the new attribute agreeWithConcept.
Here the value of 1 indicates that we want this argument to agree with the first concept we passed to the LocalizationOptions. Lastly, let's update the FoodSizeView, where the user selects the size of the pizza they want, with the new method.
Now let's run our app again and finally order the pizza.
Amazing, our food sizes are correctly agreeing with the pizza here. Let's try sandwich, which is masculine in Spanish. This looks great. Now let's launch our app in English, and finally put an order for a pizza.
I will opt for a huge one this time. And let's make it two. Why not? Looks like Tony is going to deliver our order soon. The gender neutral language here is great, but we happen to know that Tony set his pronouns to be he/him/his. This is something we could easily fix. To do that, let's extend the model for the delivery person to include preferredTermsofAddress.
And let's extend our instance of Tony and indicate that he prefers to use masculine pronouns.
Next, we want to change the string itself.
Here, we want to substitute "they" with the pronoun depending on the termsOfAddress of the delivery person. To do this, we use the new referentConcept attribute.
Here the value of 1 means that the referent of the pronoun "they" has to be the first concept which passed in LocalizationOptions.
We can apply this to any third person personal pronoun in this sentence.
Next, we want to pass the termsOfAddress as a concept in LocalizationOptions. Let's initialize LocalizationOptions for deliveryMessage.
Here, we can also use termsOfAddress concept to provide termsOfAddress that we can use for grammatical agreement.
And lastly, let's use the new LocalizationOptions when we initialize the string.
Now let's try running our app again.
Okay, huge pizzas, two. Let's make it three.
Now that we've applied the agreement, this looks so much more personal.
There are a lot of great new features in Foundation this year, and they are ready for you to try in your apps today. Inflect: true supports even more languages this year. Our new dependency agreement APIs will help you agree words within same string, or even completely out of context. Finally, the new termsOfAddress inflection concept and referentConcept attributes in Markdown will help make your language be more personalized. Please refer to our documentation for language-level support. I hope you'll love these new features. We're looking forward to seeing them beautify the language in your apps soon. Thank you. Oh, and my pizza has arrived. Thank you, Tony. ♪ ♪
-
-
4:08 - agreeWithConcept
// Formatting the string var options = AttributedString.LocalizationOptions() options.concepts = [.localizedPhrase(food.localizedName)] let size = AttributedString(localized: "small", options: options)
-
8:45 - Preferred terms of address
// A person who is delivering the food order struct DeliveryPerson { // The person's preferred name var name: String // An avatar for the delivery person var avatar: Image // The person's preferred terms of address. This list may contain more than // one option, we will use the first applicable one for the language that's // used in the UI. var preferredTermsOfAddress: [TermOfAddress] } // Formatting the message in Swift var options = AttributedString.LocalizationOptions() options.concepts = [.termsOfAddress(person.preferredTermsOfAddress)] let message = AttributedString(localized: "\(person.name) is on ^[their](referentConcept: 1) way.”, options: options)
-
-
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.