Para um rótulo reutilizável no macOS, aceite mensagens localizáveis como LocalizedStringResource, mantenha um caminho separado com verbatim: para texto literal e preserve a interpolação até a localização. Este tutorial implementa esse contrato para um contador de itens no desktop e verifica a extração separadamente da exibição.

O que a API de texto reutilizável deve garantir?

Suponha que um app para Mac precise de um resumo compacto que mostre a quantidade de itens e o rótulo de uma coleção fictícia, como Sample Set. O componente reutilizável precisa distinguir três entradas: uma mensagem escrita pelo app que precisa de tradução, uma chave de localização existente do SwiftUI e um texto que deve aparecer exatamente como foi fornecido.

A Apple recomenda LocalizedStringResource para representar e transmitir strings localizáveis por exibições personalizadas e outro código Swift. As orientações atuais mostram propriedades de exibições personalizadas desse tipo sendo exibidas com Text. Use-o como contrato principal para mensagens ao projetar um componente novo. Preparando o texto do app para tradução.

A tabela de decisão a seguir apresenta um design de API baseado nesses comportamentos documentados. Os rótulos explícitos dos argumentos deixam a intenção de quem chama clara para revisão, sem depender de duas sobrecargas de string concorrentes e sem rótulos.

Intenção de quem chama Ponto de entrada proposto Caminho de renderização
Passar uma mensagem traduzível com contexto opcional SummaryLabel(localized:) Text(resource)
Passar uma chave do SwiftUI, incluindo interpolação do SwiftUI SummaryLabel(key:) Text(key, tableName:bundle:)
Exibir um rótulo exato SummaryLabel(verbatim:) Text(verbatim:)
Fornecer texto já composto por quem chama SummaryLabel(text:) Armazene o Text fornecido

Mantenha LocalizedStringKey disponível quando o componente precisar especificamente do comportamento baseado em chaves do SwiftUI. A Apple documenta que um literal de string passado diretamente a Text cria uma chave de localização, enquanto uma variável String normalmente segue um caminho que ignora a localização. Portanto, um wrapper que aceita apenas String altera o significado de chamadas que, de outro modo, pareceriam semelhantes. LocalizedStringKey.

Crie um componente completo com pontos de entrada explícitos

Use um projeto de app SwiftUI para macOS no Xcode 26 ou posterior, com o destino de implantação definido como macOS 26 neste exemplo. Substitua as declarações geradas do app e da exibição de conteúdo pelo programa completo abaixo; mantenha apenas uma declaração @main no destino. Todos os rótulos e quantidades são fictícios. O código foi analisado com base nas APIs documentadas, mas não foi compilado aqui porque este ambiente não tem um compilador Swift.

import Foundation
import SwiftUI

struct SummaryLabel: View {
    private let text: Text

    init(localized resource: LocalizedStringResource) {
        text = Text(resource)
    }

    init(
        key: LocalizedStringKey,
        tableName: String? = nil,
        bundle: Bundle? = nil,
        comment: StaticString? = nil
    ) {
        text = Text(
            key,
            tableName: tableName,
            bundle: bundle,
            comment: comment
        )
    }

    init(verbatim value: String) {
        text = Text(verbatim: value)
    }

    init(text: Text) {
        self.text = text
    }

    var body: some View {
        text
            .font(.callout)
            .padding(8)
    }
}

struct ContentView: View {
    @State private var itemCount = 2
    private let collectionLabel = "Sample Set"

    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            Stepper(value: $itemCount, in: 0...12) {
                Text("Item count")
            }

            SummaryLabel(
                localized: LocalizedStringResource(
                    "summary.item-count",
                    defaultValue: "\(itemCount) items",
                    comment: "Summary below the item-count control. The integer is the number of items."
                )
            )

            SummaryLabel(
                key: "Collection: \(collectionLabel)"
            )

            SummaryLabel(verbatim: collectionLabel)

            SummaryLabel(
                text: Text(
                    "Preview",
                    comment: "Heading for a preview of the current item selection."
                ).bold()
            )
        }
        .padding(20)
        .frame(minWidth: 320)
    }
}

@main
struct TextContractDemoApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

O inicializador do recurso separa deliberadamente a chave estável summary.item-count da mensagem padrão, \(itemCount) items. A Apple documenta uma chave estática, um valor padrão localizável, uma tabela, uma localidade, um pacote e um comentário para o tradutor nesse inicializador. O valor padrão é usado quando a chave não está presente na tabela especificada. Inicializador de LocalizedStringResource.

O inicializador verbatim: estabelece uma garantia igualmente clara: exibir a string fornecida sem localização. Funciona tanto com um argumento literal quanto com uma variável. Use esse caminho para o rótulo fictício da coleção quando a grafia exata for o conteúdo a exibir. Text.init(verbatim:).

O ponto de entrada text: permite que quem chama construa texto localizado ou estilizado antes de fornecê-lo. Este componente adiciona tipografia e espaçamento compartilhados; quem chama ainda escolhe a semântica da mensagem. Passar Text é uma alternativa flexível, então um componente que precise impor um contrato mais restrito pode omitir esse inicializador.

Em que diferem a extração e a formatação em tempo de execução?

Trate a localização como duas verificações distintas. Durante uma compilação, o Xcode descobre expressões localizáveis no código-fonte e atualiza o Catálogo de Strings. Durante a execução, o app resolve a mensagem e substitui os argumentos. A sessão da Apple sobre Catálogos de Strings descreve explicitamente o reconhecimento de literais usados para instanciar LocalizedStringResource no ponto de chamada de uma exibição personalizada. Ela também identifica a configuração de compilação Use Compiler to Extract Swift Strings. Descobrir Catálogos de Strings.

A interpolação precisa chegar a um tipo que ofereça suporte à localização antes de se tornar uma string comum concluída. A Apple explica que o construtor de interpolação do SwiftUI mantém a chave de formato e os valores dos argumentos separados, permitindo a localização antes da substituição. Converter uma String já interpolada em uma chave não consegue reconstruir esses argumentos tipados originais. Novidades no Swift.

Este trecho de diagnóstico mostra a diferença; não é um segundo app. Todos os valores usados no trecho são definidos localmente.

import SwiftUI

let count = 2

// Ordinary String interpolation has already produced "2 items".
let completed: String = "\(count) items"
let exactDisplay = Text(completed)

// Looks up the completed value as a key.
// This does not restore a count placeholder.
let completedValueLookup = Text(LocalizedStringKey(completed))

// Preserves localization-aware interpolation from the beginning.
let messageKey: LocalizedStringKey = "\(count) items"
let interpolatedDisplay = Text(messageKey)

Criar LocalizedStringKey a partir de uma variável é uma forma documentada de solicitar uma consulta em tempo de execução. É útil quando a variável contém intencionalmente uma chave conhecida. Isso não garante que o Xcode tenha extraído todos os valores possíveis dessa variável para um catálogo. Mantenha explicitamente as chaves dinâmicas intencionais ou use declarações literais de recursos para as mensagens finitas do seu app. O comportamento da consulta e o fallback estão documentados em Text.init(_:tableName:bundle:comment:).

Preserve a mensagem inteira, incluindo a pontuação e as posições dos marcadores, em uma única expressão localizável. Neste exemplo, mantenha Collection: \(collectionLabel) junto. Montar uma mensagem concluída a partir de fragmentos resolvidos separadamente deixaria a cargo de quem chama definir a ordem e os espaços.

Adicione o catálogo e configure o comportamento de plural

Primeiro, adicione um Catálogo de Strings por meio de File > New > File from Template, selecione String Catalog e dê a ele o nome Localizable. Em seguida, escolha Product > Build. A Apple documenta que a compilação preenche o catálogo com base nas APIs localizáveis e o atualiza quando as mensagens do código-fonte mudam. Localizar e variar texto com um catálogo de strings.

No exemplo, inspecione a entrada summary.item-count e o inteiro interpolado. Clique na entrada com o botão direito enquanto mantém Control pressionado e escolha Vary by Plural. Na localização de origem em inglês, defina One como %lld item e Other como %lld items, mantendo o marcador inteiro fornecido pelo Xcode. Ao adicionar outras localizações, inclua as formas necessárias; as categorias de plural dependem do idioma. Localizar e variar texto com um catálogo de strings.

A interpolação fornece a quantidade, mas não cria por si só a forma singular. O tutorial prático da Apple demonstra como adicionar variantes de plural no catálogo e como o sistema seleciona a variante correspondente em tempo de execução. Por isso, uma compilação bem-sucedida e uma mensagem extraída são apenas parte da verificação. Tutorial prático: Explore a localização com o Xcode.

Use esta pequena matriz de aceitação após configurar as formas de plural de origem. Estes são resultados esperados para o programa ilustrativo, não resultados de uma execução relatada.

Verificação Resultado esperado
Compile e inspecione summary.item-count Uma entrada de mensagem com substituição de inteiro
Defina a quantidade como 0 0 items
Defina a quantidade como 1 1 item
Defina a quantidade como 2 2 items
Inspecione a linha do rótulo exato Sample Set permanece literal
Inspecione a mensagem da coleção O rótulo é um argumento dentro da mensagem completa

Diagnostique separadamente as entradas ausentes e a exibição incorreta

Se uma mensagem estiver ausente do catálogo, primeiro inspecione o tipo de origem. Um parâmetro String pode ter apagado a expressão localizável antes de ela chegar ao componente. Verifique o destino do catálogo, compile o esquema que contém o ponto de chamada e confirme a configuração Use Compiler to Extract Swift Strings. A Apple descreve a extração como uma operação do esquema e da plataforma atuais, então inspecione a configuração que realmente compila a mensagem. Descobrir Catálogos de Strings.

Se uma entrada existir, mas o app exibir uma chave ou um texto de fallback, inspecione a configuração da consulta. O inicializador de Text baseado em chave pesquisa na tabela e no pacote especificados; se os valores forem omitidos, ele seleciona a tabela padrão e o pacote principal. Uma chave ou tabela ausente produz a representação em string da chave. Portanto, um fallback legível pode ocultar uma consulta incompleta. Text.init(_:tableName:bundle:comment:).

Ao mover o componente para um framework ou pacote, decida onde ficarão as mensagens. Mensagens pertencentes ao componente precisam do pacote de recursos dele; os recursos pertencentes a quem chama devem manter as informações de consulta fornecidas. As orientações atuais da Apple permitem passar #bundle às APIs de localização para identificar o pacote do destino que contém o código. Da mesma forma, tabelas nomeadas precisam ter catálogos correspondentes. Preparando o texto do app para tradução.

Por fim, não presuma que toda interpolação aceita pelo SwiftUI também possa ser usada em um recurso do Foundation. LocalizedStringKey tem seus próprios métodos de interpolação, incluindo variantes com estilo de formato e formatador. Escolha o tipo da mensagem antes de compor a expressão e consulte as operações de interpolação compatíveis quando um argumento não compilar. LocalizedStringKey.StringInterpolation.

Um componente de texto reutilizável está pronto quando quem chama consegue expressar sua intenção com clareza e verificá-la nas duas etapas: a compilação gera a mensagem pretendida no catálogo, e o app em execução no Mac exibe a substituição, a forma plural ou o rótulo exatos. Mantenha essas verificações junto ao contrato da API sempre que o componente mudar.

Fontes