How to use Automatic Grammar Agreement in Swift
Elevate your localization game and enhance user experience
Stop doing manual tweaks on your texts to match the language grammar.
If your application is multi-language, you know what I mean. For example, “Delicious coffee” should translate to “Café delicioso” in Spanish (adjective after the noun). We used to do this modification manually, but now we can let Swift’s Automatic Grammar Agreement feature do it for us.
Let me show you how easily we can achieve this now.
We have a simple coffee shop application that allows our customers to make an order.
You might notice a couple of issues. When we want to add more than 1 item, the text button doesn’t update correctly. In the past, we had to add some logic to handle this.
let itemText = quantity > 1 ? "\\(item)s" : item
let buttonText = "Add \\(quantity) \\(size) \\(itemText)"
However, as we saw here, we can use the inflect parameter in our localization string catalog and leave our code as it is.
Our application supports Spanish as well as English.
As our coffee app uses the same sizes for drinks that for food (small, regular, and large) we need to adjust our texts a little bit.
In Spanish, adjectives need to agree with the noun, so we’ll need to change the text's size depending on the menu item that we’re displaying.
- For Coffee items (Café) 👉🏻 Should show Chico, Mediano, and Grande
- For Croissant (Media Luna) 👉🏻 Should show Chica and Mediana
- For Chicken Sandwich (Sandwich de pollo) 👉🏻 Should show Chico and Mediano
Agree With Concepts
We have a new property to LocalizationOptions, concepts, which allows us to agree with a specific phrase.
How do we use it?
We need to adjust our code and our Localizable catalog as well.
func localizeDescription(describing item: String) -> AttributedString {
var options = AttributedString.LocalizationOptions()
options.concepts = [.localizedPhrase(item)]
switch self {
case .small:
return AttributedString(localized: "Small", options: options)
case .regular:
return AttributedString(localized: "Regular", options: options)
case .large:
return AttributedString(localized: "Large", options: options)
}
}
Small = ^[chico](agreeWithConcept: 1)
Medium = ^[mediano](agreeWithConcept: 1)
The number 1 corresponds to the parameter that we pass in the concepts array.
With that small adjustment, our size texts will automatically agree with the item that the user selects.
Agree With Arguments
We might have another scenario where our text is fully localized, and it’s adapted depending on the parameters that we use.
If you pay attention, we show a message when the user selects any food item. Depending on the item, we must agree the verb done (”hecho” in Spanish) to the item name.
- For Media Luna 👉🏻 we must use Hecha
- For Sandwich 👉🏻 we must use Hecho
In our demo, we have a string localizable with one argument: the item name.
^[Nuestro %@](inflect: true) es hecho en el día
To make this grammatically correct, we can use the agreeWithArgument
option directly in our string!
^[Nuestro %@](inflect: true) es ^[hecho](agreeWithArgument: 1) en el día
The number we pass in agreeWithArgument
corresponds to the parameter number that our string has. In our case, is just 1.
Conclusion
Incorporating Automatic Grammar Agreement into your Swift applications is a game-changer, particularly if you support multiple languages.
By harnessing this powerful set of features provided by Swift, you not only save time and effort, but also mitigate the risk of potential linguistic errors that can arise from manual adjustments.
Let me know if you would like to access the full code that I use for this demo. I'll be happy to share it