Недавно я работал над Swift-пакетом, в котором были строки, требующие локализации. Документация Apple по этой теме кажется немного устаревшей. В ней всё еще предлагается использовать специальные директории для каждого языка для локализации ресурсов и строк.

Но на WWDC 2023 Apple представила String Catalogs. Это гораздо удобнее — просто JSON-файл, который Xcode может заполнить всеми строками, которые нужно локализовать. Большинство примеров, которые можно найти, относятся к приложениям, а не к пакетам. Поэтому я потратил некоторое время на то, чтобы разобраться, как использовать String Catalogs в Swift-пакете.

Хорошие новости — это возможно! Начнем с примера Swift Package. Вот пример файла Package.swift:

// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "SwiftPackageLocalized",
    platforms: [
        .iOS(.v15),
        .macOS(.v12),
    ],
    products: [
        .library(
            name: "SwiftPackageLocalized",
            targets: ["SwiftPackageLocalized"]),
    ],
    targets: [
        .target(
            name: "SwiftPackageLocalized"),
    ]
)

Итак, первый шаг — добавить параметр defaultLocalization:

let package = Package(
    name: "SwiftPackageLocalized",
    defaultLocalization: "en", // set the default localization
    …
)

Следующий шаг — добавить Strings Catalog в Xcode (File → New → File from Template…):

Теперь мы можем добавить наш Strings Catalog в процесс обработки ресурсов в Package.swift. Итоговый файл будет выглядеть так:

// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "SwiftPackageLocalized",
    defaultLocalization: "en",
    platforms: [
        .iOS(.v15),
        .macOS(.v12),
    ],
    products: [
        .library(
            name: "SwiftPackageLocalized",
            targets: ["SwiftPackageLocalized"]),
    ],
    targets: [
        .target(
            name: "SwiftPackageLocalized",
            resources: [
                .process("Localizable.xcstrings")
            ]
        ),
    ]
)

Наконец, мы можем использовать локализованные строки в нашем коде:

let myString = String(
    localized: "MY_STRING",
    defaultValue: "Wow, a localized string!",
    bundle: Bundle.module
)

Соберите пакет, и вы увидите, что Strings Catalog теперь содержит строки и готов к локализации на другие языки:

В следующем посте я покажу, как добавить переводы автоматически с помощью ИИ.