Build Multilingual Ready Apps - WWDC24

Peter Yaacoub •


Introduction

Creating multilingual ready apps ensures a broader reach and a better user experience. This article outlines key concepts and best practices from the WWDC24 session on building multilingual ready apps, focusing on handling keyboard interactions, text rendering, and localization.

Remember the Keyboard

To remember the keyboard language and layout, override UIResponder’s textInputContextIdentifier property. This approach is primarily applicable in UIKit and not directly achievable in SwiftUI without subclassing.

override var textInputContextIdentifier: String? {
    return "YourIdentifier"
}

Stay Above the Keyboard

UIKit

Set or override UIResponder’s inputAccessoryView property to place a view above the keyboard.

SwiftUI

Use a ToolbarItem or ToolbarItemGroup with the keyboard placement to achieve the same effect.

Check for Marked Text

Before making changes to text in a text field, ensure there is no marked text that is yet to be confirmed by using UITextInput’s markedTextRange property.

if let range = textInput.markedTextRange, !range.isEmpty {
    // Handle marked text
}

Ensure searches are locale-aware, case, and diacritic insensitive by using a String’s localizedStandardRange(of:) method.

let text = "This is an Example"
let range = text.localizedStandardRange(of: "example")

To highlight search strings within results, modify the color instead of text weight or italicization.

let attributedText = NSMutableAttributedString(string: "Search Result")
attributedText.addAttribute(.backgroundColor, value: UIColor.yellow, range: range)

Render Language Scripts Correctly

Use the system’s default fonts for proper spacing and sizing across different scripts. Avoid overriding UIView’s clipsToBounds if it contains text to ensure readability.

For consistent typesetting in SwiftUI, use the typesettingLanguage(_:isEnabled:) method.

Text(verbatim: "Hi!")
    .typesettingLanguage(.init(languageCode: .english))

Format Names

Use a formatter to ensure names are used correctly across different cultures and languages.

let personName = PersonNameComponents(givenName: "John", familyName: "Doe")
let formattedName = personNameFormatter.string(from: personName)

Localize Hard-Coded Numbers

Utilize AttributedString with the localized parameter for automatic number localization.

let localizedNumber = AttributedString("1234", locale: Locale.current)

Setting the Language

To allow users to change the app’s language within the app settings, set the UIPrefersShowingLanguageSettings value to true in the Info.plist file. You can also create a button that opens the app’s settings page using UIApplication’s openSettingsURLString property.

if let url = URL(string: UIApplication.openSettingsURLString) {
    await UIApplication.shared.open(url)
}

For opening the notification settings page, use openNotificationSettingsURLString.

if let url = URL(string: UIApplication.openNotificationSettingsURLString) {
    await UIApplication.shared.open(url)
}

Conclusion

Building multilingual ready apps involves careful consideration of various aspects, from keyboard interactions to text rendering and localization. By following these guidelines, you can create a more inclusive and user-friendly app that caters to a global audience.