WWDC Quick Look 💓 By SwiftGGTeam
Unlock the power of grammatical agreement

Unlock the power of grammatical agreement

Watch original video

Highlight

Foundation framework adds new dependency agreement API, includingagreeWithConceptandagreeWithArgumentproperties, andTermOfAddresstype andreferentConceptAttributes that allow apps to automatically handle cross-word grammatical consistency and personalized pronoun selection.

Core Content

The value of syntactic consistency

Language in software affects how users interact every day. Processing language is hard, especially when you don’t speak the language.

(00:34) Apple introduced the Grammar Consistency API in Foundation in 2021 to help apps automatically adjust wording based on how users address themselves. This year there are three important upgrades to this system: dependency consistency, inclusive language, and new language support.

Depend on consistency

(01:17) In many languages, adjectives must be consistent in gender and number with nouns. In Spanish “ensalada pequeña” is correct and “ensalada pequeño” is incorrect. The ending of the adjective must change according to the noun.

This kind of grammatical association across words has been difficult to deal with in the past. Two new property solutions were introduced this year:

agreeWithConceptUsed to agree on words outside the string. For example, the description of food size needs to be consistent with the name of the food:

var options = AttributedString.LocalizationOptions()
options.concepts = [.localizedPhrase(food.localizedName)]

let size = AttributedString(localized: "small", options: options)

Key points:

  • conceptsPass in an object that affects syntax changes but does not directly insert strings -.localizedPhrasePackaging requires agreed phrases
  • in string^[small](agreeWithConcept: 1)The annotation indicates that the word should be consistent with the first concept

agreeWithArgumentUsed to agree on words within the same string:

"^[Our](inflect: true) ^[pizza](arg1) is ^[made](agreeWithArgument: 1) fresh"

Key points:

  • inflect: trueMake the words in the block agree with each other -agreeWithArgument: 1Make the word consistent with the first parameter in the string
  • try to keepinflectKeep blocks short and reduce ambiguity

Inclusive language

08:12TermOfAddressThe type supports three calling methods: masculine, feminine, and neutral. CooperatereferentConceptattribute, the system automatically selects the correct pronoun.

struct DeliveryPerson {
    var name: String
    var avatar: Image
    var preferredTermsOfAddress: [TermOfAddress]
}

var options = AttributedString.LocalizationOptions()
options.concepts = [.termsOfAddress(person.preferredTermsOfAddress)]

let message = AttributedString(
    localized: "\(person.name) is on ^[their](referentConcept: 1) way.",
    options: options
)

Key points:

  • TermOfAddresscan be.masculine.feminine.neutral
  • referentConcept: 1Indicates that the pronoun refers to the first concept
  • The system is based onTermOfAddressAutomatically replace with correct pronoun form
  • Also supports custom pronouns, useMorphology.PronounSpecify specific form

Added language support

(02:29) Spanish support in 2021. French, Italian and Brazilian Portuguese coming in 2022. New this year are European Portuguese and German.

Detailed Content

Grammar annotations in String Catalog

(11:40) In Xcode’s String Catalog, you can directly add syntax attributes to localized strings:

// Spanish: make "nuestro" agree with "pizza"
"^[Our](inflect: true) ^[pizza](arg1)"

// Make "made" agree with the first argument, "pizza"
"^[made](agreeWithArgument: 1) fresh"

Key points:

  • Add properties directly in the String Catalog editor -inflect: trueApplies to words within the same block -agreeWithArgumentSuitable for distant words
  • value1Indicates the same as the first parameter

Food Size Consistency

(12:48) Food size needs to vary according to specific food name:

// Define food sizes with localized names
enum FoodSize: String {
    case small, medium, large

    func localizedName(for food: Food) -> String {
        // Return a size name that agrees with the food gender
    }
}

// Format the size buttons
var options = AttributedString.LocalizationOptions()
options.concepts = [.localizedPhrase(food.localizedName)]

let sizeButton = AttributedString(
    localized: "\(size.localizedName(for: food))",
    options: options
)

Key points:

  • localizedPhrasePass in the food name as concept
  • size name passedagreeWithConceptAgree on food names
  • In Spanish, pizza (feminine) corresponds to “pequeña” and sandwich (masculine) corresponds to “pequeño”

Custom pronouns

(10:19) If the default masculine/feminine/neutral is not enough, you can useLocalizedTermOfAddressSpecify specific pronouns:

let customPronouns = LocalizedTermOfAddress(
    language: "en",
    pronouns: [
        Morphology.Pronoun(
            pronoun: "they",
            morphology: Morphology(grammaticalCase: .nominative)
        ),
        Morphology.Pronoun(
            pronoun: "them",
            morphology: Morphology(grammaticalCase: .accusative)
        ),
        // ... other cases
    ]
)

Key points:

  • Specify target language
  • List all required pronoun forms
  • Each pronoun contains morphological and grammatical case information
  • English requires 5 pronoun forms

Core Takeaways

  1. Add syntax consistency to multi-language applications

    • If the app supports Spanish, French, German, etc., useinflect: trueandagreeWithArgumentAutomatically handles adjective and noun agreement
    • No need to write special logic for each language
    • Entry: Add attribute annotation in String Catalog
  2. Implement personalized pronoun support

    • Add to user profilepreferredTermsOfAddressField
    • useTermOfAddressandreferentConceptAutomatically select the correct pronoun
    • Entrance:TermOfAddress.masculine / .feminine / .neutral
  3. Fix syntax errors in existing localizations

    • Check whether adjectives and nouns in localized strings such as Spanish and French are consistent
    • useagreeWithConceptHandling inflections across strings
    • Entry: in String CatalogagreeWithConceptandagreeWithArgumentproperty

Comments

GitHub Issues · utterances