В Xcode 26 и более поздних версиях каталоги строк могут генерировать средства доступа Swift, заменяющие ключи локализации, введённые вручную. В этом руководстве сводка выбора в небольшом приложении для Mac переносится на типизированные свойства и функции, а затем проверяется, что именно защищает компилятор.

Задача намеренно ограничена: показать заголовок окна и сводку с двумя целочисленными значениями. Все подписи и значения вымышлены. Вы создадите контракт каталога, подключите его к SwiftUI и проверите диагностику компилятора и отображаемый результат.

Что делает средство доступа к локализации проверяемым во время компиляции?

В Xcode 26 Apple добавила встроенную генерацию символов для каталогов строк. Для записи без подстановок создаётся статическое свойство; для записи с подстановками — функция с типизированными параметрами. Оба варианта возвращают LocalizedStringResource. В новых проектах Xcode 26 генерация включена по умолчанию; в существующих проектах может потребоваться включить параметр сборки. Практическое руководство: изучение локализации в Xcode

Полезное изменение происходит в месте вызова. Строковый литерал может задавать ключ поиска, не ссылаясь на объявление Swift. Сгенерированное средство доступа обращается к члену, который должен существовать, а сгенерированная функция требует аргументы, соответствующие её сигнатуре. Из этих задокументированных механизмов следует практический вывод: опечатка в имени члена или несовместимый аргумент приведут к ошибке компилятора.

У этой защиты есть чёткие границы. Swift может проверить, что средство доступа существует и его аргументы подходят. Он не может определить, описывает ли формулировка нужный интерфейс и соответствуют ли два допустимых целочисленных аргумента правильным значениям. Рассматривайте средства доступа как проверяемый программный интерфейс к вашим сообщениям.

Настройте небольшое приложение для Mac и контракт его сообщений

Используйте Xcode 26 или более позднюю версию и цель приложения SwiftUI для macOS. Для этого примера задайте целевую версию macOS 15 или новее. Сам тип LocalizedStringResource доступен начиная с macOS 13; более высокая целевая версия примера — это выбранное предварительное условие, а не минимальная версия для этого типа. Ресурс представляет локализуемый текст, поиск которого можно отложить до момента, когда он понадобится. LocalizedStringResource

Добавьте каталог через File > New > File from Template. В разделе Resource выберите String Catalog, назовите его Workbench и включите в цель приложения. Apple указывает, что каждый каталог представляет таблицу; отдельная таблица здесь позволяет объединить два сообщения примера. Локализация и варианты текста с помощью каталога строк

В редакторе проекта откройте Build Settings, отфильтруйте настройки по Generate String и задайте Generate String Catalog Symbols значение Yes для действующей конфигурации цели. Это документированный параметр для старых проектов. Использование сгенерированных символов локализуемого содержимого в коде

Выберите исходную локализацию на английском языке в Workbench.xcstrings. Добавьте две записи с помощью кнопки + на панели инструментов редактора каталога. Комментарии определяют смысл сообщений, включая назначение их аргументов.

Ключ Исходное значение на английском Комментарий
TITLE Selection overview Заголовок над сводкой выбора.
SUBTITLE %1$(selectedCount)lld selected; %2$(availableCount)lld available Сводка выбора. selectedCount — число выбранных элементов; availableCount — общее число доступных элементов, включая выбранные.

Для SUBTITLE можно добавить каждую подстановку через меню автодополнения Xcode: введите %, выберите целочисленную подстановку и задайте ей имя selectedCount или availableCount. Apple документирует именованные переменные и сгенерированные параметры для этих спецификаторов формата. Выберите каждую запись и изучите разделы Generate Swift Symbol и Example Usages в инспекторе Attributes. Использование сгенерированных символов локализуемого содержимого в коде

Предполагаемый контракт — свойство заголовка и функция подзаголовка, принимающая два значения Int. Перед продолжением проверьте фактические имена в инспекторе: Apple указывает, что имена символов используют и ключ, и его значение. В примерах ниже используются .Workbench.title и .Workbench.subtitle(selectedCount:availableCount:) согласно задокументированному Apple шаблону ключа в верхнем регистре. Практическое руководство: изучение локализации в Xcode

Этот контракт явно задаёт важное различие: availableCount включает выбранные элементы. Без такого комментария вызывающий код может обоснованно трактовать это число как количество оставшихся элементов. Обе трактовки будут соответствовать типам, поэтому документирование смысла — часть создания полезного средства доступа.

Используйте сгенерированные средства доступа в полноценном окне

После создания каталога выберите Product > Build. Замените объявление шаблонного приложения и представление содержимого приведённой программой, оставив в цели ровно одно объявление @main. Для этой программы каталог является обязательным ресурсом; вставка Swift-кода в отдельный файл сама по себе не создаст средства доступа.

import Foundation
import SwiftUI

@main
struct SelectionOverviewApp: App {
    var body: some Scene {
        WindowGroup {
            SelectionOverviewView(
                selectedCount: 3,
                availableCount: 12
            )
        }
    }
}

struct SelectionOverviewView: View {
    let selectedCount: Int
    let availableCount: Int

    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text(.Workbench.title)
                .font(.title2)

            Text(
                .Workbench.subtitle(
                    selectedCount: selectedCount,
                    availableCount: availableCount
                )
            )
        }
        .padding(24)
        .frame(minWidth: 360, minHeight: 140)
    }
}

При активной исходной локализации на английском языке пример должен показывать Selection overview, а под ним — 3 selected; 12 available. Значения фиксированы, чтобы можно было проверить расположение аргументов без кода управления выбором.

Apple документирует возможность использовать сгенерированные ресурсы в SwiftUI, в том числе в Text, и через инициализатор Foundation String(localized:). Если существующий интерфейс Mac требует разрешённый String, преобразуйте сгенерированный ресурс на этой границе. Практическое руководство: изучение локализации в Xcode

Например, после создания каталога в ту же цель приложения можно добавить следующую полноценную вспомогательную функцию:

import Foundation

func selectionSummary(
    selectedCount: Int,
    availableCount: Int
) -> String {
    String(
        localized: .Workbench.subtitle(
            selectedCount: selectedCount,
            availableCount: availableCount
        )
    )
}

Возвращая LocalizedStringResource из собственного интерфейса, вы сохраняете ресурс для последующего поиска; возвращая String, вы разрешаете его при выполнении инициализатора. Выбирайте вариант в зависимости от требований принимающего интерфейса. Apple описывает это различие между отложенным и немедленным поиском в документации Foundation. LocalizedStringResource

Примеры сверены с полученной документацией. Здесь они не компилировались, поскольку в доступной среде нет Swift и Xcode.

Почему важны начальная точка и метки аргументов

Начальная точка — это неявный синтаксис члена в Swift. Он сокращает обращение к члену типа, если окружающий контекст позволяет Swift определить тип. Это обычный синтаксис Swift, а не специальный оператор строкового ключа. Выражения — неявное выражение члена

Для сгенерированных символов локализации члены таблицы по умолчанию Localizable доступны напрямую, тогда как именованная таблица вводит пространство имён таблицы. Поэтому в этом примере перед именем члена указано .Workbench. Apple документирует обе формы. Использование сгенерированных символов локализуемого содержимого в коде

Метки selectedCount: и availableCount: относятся к вызову функции. Swift различает метки аргументов, указанные в месте вызова, и имена параметров, используемые внутри функции. Если для параметра требуется метка, вызывающий код должен её указать. Функции — метки аргументов и имена параметров

Понятные метки помогают избежать ошибок, но оба аргумента здесь имеют один и тот же тип. Перестановка двух целочисленных значений останется допустимой в Swift. Поэтому контракт сообщения и проверка отображаемого результата дополняют проверки компилятора.

Перенесите существующие ключи, сохранив их смысл

Для уже существующих локализуемых строк Apple предлагает процесс рефакторинга. Выберите записи в каталоге строк, щёлкните по ним, удерживая Control, и выберите Refactor > Convert Strings to Symbols. Проверьте предварительный просмотр, при необходимости измените предложенные имена символов или параметров и выберите Convert. Использование сгенерированных символов локализуемого содержимого в коде

Сначала перенесите одну логически связанную группу, например заголовок и сводку этого окна. Перед принятием изменений сравните старое сообщение с новым контрактом: используют ли они одну таблицу, описывают ли один и тот же элемент интерфейса и сохраняют ли смысл каждой подстановки? Проверьте все существующие локализованные значения, которых касается изменение ключа, вместо того чтобы считать, что рефакторинг гарантирует их корректность.

Для места вызова, которое рефакторинг не обновил, возьмите сгенерированный пример использования из инспектора каталога и замените эту ссылку вручную. Затем соберите приложение и проверьте получившийся текст. Не удаляйте старую запись, пока не учтёте все её места вызова.

Если в установленной версии Xcode нет встроенной генерации, для этого процесса потребуется более новая версия инструментов. Apple также поддерживает извлечение строк из локализуемых API в каталоги и рекомендует извлечение как начальный процесс. Это поддерживаемый способ работы с локализацией, однако он сам по себе не предоставляет контракт сгенерированных средств доступа, описанный здесь. Практическое руководство: изучение локализации в Xcode

Проверьте перенос с помощью короткой последовательности диагностик

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

  1. Соберите неизменённый пример, чтобы получить рабочую исходную точку.
  2. Временно внесите опечатку в имя члена заголовка и выполните сборку. Для несуществующего члена должна появиться диагностика компилятора. Восстановите имя.
  3. Временно передайте значение String туда, где для подзаголовка требуется Int. Выполните сборку, чтобы проверить несовпадение типов, затем восстановите целочисленное значение.
  4. Запустите приложение, задав selectedCount значение 3 и availableCount значение 12. Убедитесь, что числа стоят на нужных местах.
  5. Измените только значение заголовка в каталоге на Current selection, выполните сборку и проверьте отображаемый заголовок. Убедитесь, что сгенерированная сигнатура осталась такой, какую использует код.

Если член неожиданно отсутствует, сначала проверьте сгенерированный пример использования для записи каталога. Затем проверьте параметр генерации, включение каталога в цель и имя таблицы. Диагностика компилятора указывает на неработающую ссылку; эти проверки помогают отличить опечатку от отсутствующего сгенерированного объявления.

Наконец, проверьте настоящий интерфейс. Согласно документации Apple, для этого откройте Product > Scheme > Edit Scheme, затем Run > Options и перед запуском выберите App Language. Повторите проверку для локализаций, которые поддерживает ваш проект. Тестирование локализаций при запуске приложения

Для предварительной проверки макета в Xcode также есть Double-Length Pseudolanguage, которая расширяет локализуемый текст и помогает выявить проблемы с размерами. Проверьте сводку при небольшой ширине окна: успешная компиляция не гарантирует, что текст поместится. Тестирование локализаций

В результате завершённого переноса в каждом месте вызова используется настоящий член Swift, у каждой переменной задокументировано назначение, а путь к нужной записи каталога остаётся проверяемым. Сохраняйте проверки компилятора и окна вместе: первые проверяют контракт средства доступа, вторые подтверждают, что пользователь видит нужное сообщение.

Источники