Inclusivity with Voice & Language

May 30 2025 · Swift 5.9, iOS 17, Xcode 15.3

Lesson 04: Grammatical Agreement

Demo: Grammatical Agreement

Episode complete

Play next episode

Next

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In the previous lesson, you used string catalog techniques to implement regular plurals (just add “s”) and create a not-quite-right French localization. In this lesson, you’ll:

Inflecting

Pluralization

You’ll start by using inflection instead of Vary by Plural.

^[%1$lld %2$@ %3$@](inflect: true)

Gender

There’s one more place you can use inflect — in the item description, to make “un” agree with the gender of the item argument. Edit the string:

C'est ^[un %@](inflect: true) d'homme qui n'est jamais aussi bien porté que par une femme.

Agreeing With Argument

There’s another place in this string that needs gender agreement. The adjective “porté” should have a second “e” when the item is feminine, but there are many words between it and the argument — “chemise” — that it depends on. Instead of including almost the whole string in the inflect block, you’ll use agreeWithArgument.

C'est ^[un %@](inflect: true) d'homme qui n'est jamais aussi bien ^[porté](agreeWithArgument: 1) que par une femme.

Agreeing With Concept

Now, the only missing agreement is the color button labels: For a feminine item, “rouge” is OK, but the other three colors should all get a final “e” to match the item’s gender. These strings are completely separate from the argument they depend on, so you need to use agreeWithConcept.

var options: AttributedString.LocalizationOptions {
  var options = AttributedString.LocalizationOptions()
  options.concepts = [.localizedPhrase(item.name)]
  return options
}
color: AttributedString(localized: "red", options: options, comment: "color")
color: AttributedString(localized: "blue", options: options, comment: "color")
color: AttributedString(localized: "green", options: options, comment: "color")
color: AttributedString(localized: "black", options: options, comment: "color")
let color: AttributedString
@Binding var colorChoice: AttributedString?
@State var colorChoice: AttributedString?
^[noir](agreeWithConcept: 1)
^[bleu](agreeWithConcept: 1)
^[vert](agreeWithConcept: 1)
^[rouge](agreeWithConcept: 1)

TermsOfAddress

Close the assistant editor and switch App Language back to English for your final task. You’ll set up the app to use the model’s preferred term of address in this string:

"🏃🏻‍➡️\(model.name) is \(model.height) cm tall. He wears size \(model.size)."
let model = Model(name: "Sam",
                  height: 170, size: "M",
                  preferredTermsOfAddress: [.feminine])
options.concepts = [
  .localizedPhrase(item.name),
  .termsOfAddress(model.preferredTermsOfAddress)]
Text(
  AttributedString(
    localized: "🏃🏻‍➡️\(model.name) is \(model.height) cm tall. He wears size \(model.size).",
    options: options),
    comment: "Description of model")
^[He](referentConcept: 2)
^[Il](referentConcept: 2)
let model = Model(name: "Sam",
                  height: 170, size: "M",
                  preferredTermsOfAddress: [.neutral])
See forum comments
Cinema mode Download course materials from Github
Previous: Grammatical Agreement Next: Conclusion