För en återanvändbar macOS-etikett tar du emot lokaliserbara meddelanden som LocalizedStringResource, har en separat verbatim:-väg för bokstavlig text och bevarar interpolation fram till lokaliseringen. Den här handledningen bygger upp det kontraktet för en räknare av objekt på skrivbordet och kontrollerar extrahering separat från visning.
Vad bör det återanvändbara text-API:et utlova?
Anta att en Mac-app behöver en kompakt sammanfattning som visar ett antal objekt och en syntetisk samlingsetikett, till exempel Sample Set. Den återanvändbara komponenten måste skilja mellan tre typer av indata: ett meddelande skrivet av appen som behöver översättas, en befintlig SwiftUI-lokaliseringsnyckel och text som måste visas exakt som den tillhandahålls.
Apple rekommenderar LocalizedStringResource för att representera och skicka lokaliserbara strängar genom anpassade vyer och annan Swift-kod. I den aktuella vägledningen visas anpassade vyegenskaper av den typen som renderas med Text. Använd den som det primära meddelandekontraktet när du utformar en ny komponent. Förbereda appens text för översättning.
Följande beslutstabell visar en API-design som härletts från dessa dokumenterade beteenden. De uttryckliga argumentetiketterna gör anroparens avsikt tydlig vid granskning, utan att förlita sig på två konkurrerande, oetiketterade strängöverlagringar.
| Anroparens avsikt | Föreslagen ingångspunkt | Renderingsväg |
|---|---|---|
| Skicka ett översättningsbart meddelande med valfri kontext | SummaryLabel(localized:) |
Text(resource) |
| Skicka en SwiftUI-nyckel, inklusive SwiftUI-interpolation | SummaryLabel(key:) |
Text(key, tableName:bundle:) |
| Visa en exakt etikett | SummaryLabel(verbatim:) |
Text(verbatim:) |
| Skicka text som anroparen redan har satt samman | SummaryLabel(text:) |
Lagra den angivna Text-instansen |
Behåll LocalizedStringKey som alternativ när komponenten specifikt behöver SwiftUIs nyckelbaserade beteende. Apple dokumenterar att en strängliteral som skickas direkt till Text skapar en lokaliseringsnyckel, medan en String-variabel normalt använder en väg som hoppar över lokalisering. En wrapper som bara tar emot String ändrar därför innebörden hos anrop som annars ser likadana ut. LocalizedStringKey.
Bygg en komplett komponent med uttryckliga ingångspunkter
Använd ett macOS SwiftUI-app projekt i Xcode 26 eller senare, med målversionen macOS 26 i det här exemplet. Ersätt de genererade deklarationerna för appen och innehållsvyn med hela programmet nedan; behåll bara en @main-deklaration i målet. Alla etiketter och antal är syntetiska. Koden har granskats mot de dokumenterade API:erna, men har inte kompilerats här eftersom den här miljön saknar en Swift-kompilator.
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()
}
}
}
Resursinitialiseraren skiljer avsiktligt den stabila nyckeln summary.item-count från dess standardmeddelande, \(itemCount) items. Apple dokumenterar en statisk nyckel, ett lokaliserbart standardvärde, en tabell, en språkvariant, ett paket och en kommentar till översättaren för den här initialiseraren. Standardvärdet används när nyckeln saknas i den angivna tabellen. LocalizedStringResource-initialiseraren.
Initialiseraren verbatim: utlovar lika tydligt att den angivna strängen visas utan lokalisering. Den fungerar både med ett literalargument och med en variabel. Använd den här vägen för den syntetiska samlingsetiketten när dess exakta stavning är det som ska visas. Text.init(verbatim:).
Ingångspunkten text: låter anroparen skapa lokaliserad eller formaterad text innan den skickas vidare. Komponenten lägger till gemensam typografi och mellanrum; anroparen väljer fortfarande meddelandesemantiken. Att skicka Text är en reservutväg, så en komponent som måste upprätthålla ett snävare kontrakt kan utelämna den initialiseraren.
Hur skiljer sig extrahering från formatering vid körning?
Behandla lokalisering som två separata kontroller. Under ett bygge hittar Xcode lokaliserbara källuttryck och uppdaterar strängkatalogen. När appen körs slår den upp meddelandet och ersätter dess argument. Apples genomgång av strängkataloger beskriver uttryckligen hur literaler som används för att skapa LocalizedStringResource på en anropsplats för en anpassad vy identifieras. Den tar också upp bygginställningen Use Compiler to Extract Swift Strings. Identifiera strängkataloger.
Interpolation måste nå en lokaliseringstyp innan den blir en vanlig, färdig sträng. Apple förklarar att SwiftUIs interpolationsbyggare håller formatnyckeln och argumentvärdena åtskilda, vilket gör det möjligt att lokalisera före ersättningen. Om du konverterar en redan interpolerad String till en nyckel går det inte att återskapa de ursprungliga typade argumenten. Nyheter i Swift.
Det här diagnostikfragmentet visar skillnaden; det är inte en andra app. Alla värden som används i fragmentet definieras lokalt.
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)
Att skapa LocalizedStringKey från en variabel är ett dokumenterat sätt att begära uppslagning vid körning. Det är användbart när variabeln avsiktligt innehåller en känd nyckel. Det innebär inte att Xcode extraherar varje möjligt värde i variabeln till en katalog. Hantera avsiktliga dynamiska nycklar uttryckligen, eller använd literaldeklarationer av resurser för de begränsade meddelanden som appen äger. Uppslagsbeteendet och reservvärdet beskrivs i Text.init(_:tableName:bundle:comment:).
Bevara hela meddelandet, inklusive interpunktion och platserna för platshållare, i ett enda lokaliserbart uttryck. I det här exemplet ska Collection: \(collectionLabel) hållas samman. Om meddelandet byggs av separata, redan uppslagna delar måste anroparen ansvara för deras ordning och mellanrum.
Lägg till katalogen och konfigurera pluralformer
Lägg först till en strängkatalog via File > New > File from Template, välj String Catalog och döp den till Localizable. Välj sedan Product > Build. Apple dokumenterar att katalogen fylls i när appen byggs, utifrån lokaliseringsbara API:er, och uppdateras när källmeddelanden ändras. Lokalisera och variera text med en strängkatalog.
För exemplet granskar du posten summary.item-count och dess interpolerade heltal. Ctrl-klicka på posten och välj Vary by Plural. I den engelska källspråksvarianten anger du %lld item för One och %lld items för Other, och behåller heltalsplatshållaren som Xcode tillhandahåller. Lägg till de obligatoriska formerna när du lägger till andra språkvarianter; pluralformerna beror på språket. Lokalisera och variera text med en strängkatalog.
Interpolation skickar med antalet, men skapar inte i sig singularformen. I Apples kodgenomgång visas hur pluralvarianter läggs till i katalogen och hur systemet väljer rätt variant vid körning. Därför räcker det inte att bygget lyckas och att meddelandet extraheras; det är bara en del av verifieringen. Kodgenomgång: Utforska lokalisering med Xcode.
Använd den här lilla acceptansmatrisen när du har konfigurerat pluralformerna för källspråket. Det här är förväntade resultat för det illustrativa programmet, inte rapporterade körningsresultat.
| Kontroll | Förväntat resultat |
|---|---|
Bygg och granska summary.item-count |
En meddelandepost med en heltalsersättning |
Sätt antalet till 0 |
0 items |
Sätt antalet till 1 |
1 item |
Sätt antalet till 2 |
2 items |
| Granska raden med den exakta etiketten | Sample Set förblir bokstavlig text |
| Granska samlingsmeddelandet | Etiketten är ett argument i det fullständiga meddelandet |
Felsök saknade poster separat från felaktig visning
Om ett meddelande saknas i katalogen kontrollerar du först källtypen. En String-parameter kan ha tagit bort det lokaliserbara uttrycket innan det nådde komponenten. Kontrollera katalogens mål, bygg schemat som innehåller anropsplatsen och verifiera Use Compiler to Extract Swift Strings. Apple beskriver extrahering som något som utförs för det aktuella schemat och plattformen, så granska den konfiguration som faktiskt kompilerar meddelandet. Identifiera strängkataloger.
Om en post finns men appen visar en nyckel eller reservtext granskar du uppslagskonfigurationen. Den nyckelbaserade Text-initialiseraren söker i den angivna tabellen och paketet; om värden utelämnas används standardtabellen och huvudpaketet. Om en nyckel eller tabell saknas visas nyckelns strängrepresentation. En läsbar reservtext kan alltså dölja en ofullständig uppslagning. Text.init(_:tableName:bundle:comment:).
När du flyttar komponenten till ett ramverk eller paket bestämmer du var meddelandena hör hemma. Meddelanden som tillhör komponenten behöver resursbunten för komponenten; resurser som tillhör anroparen ska behålla den uppslagsinformation som anroparen angett. Apples aktuella vägledning stöder att #bundle skickas till lokaliserings-API:er för att ange paketet för det innehållande målet. Namngivna tabeller behöver också motsvarande kataloger. Förbereda appens text för översättning.
Utgå slutligen inte från att varje interpolation som SwiftUI accepterar också fungerar i en Foundation-resurs. LocalizedStringKey har egna interpolationsmetoder, däribland formatbaserade varianter och varianter med formatterare. Välj meddelandetyp innan du sätter ihop uttrycket och kontrollera vilka interpoleringsoperationer som stöds om ett argument inte går att kompilera. LocalizedStringKey.StringInterpolation.
En återanvändbar textkomponent är klar när anroparna tydligt kan uttrycka sin avsikt och verifiera den i båda stegen: bygget skapar den avsedda katalogposten och den körande Mac-appen visar rätt ersättning, pluralform eller exakta etikett. Behåll de kontrollerna tillsammans med API-kontraktet varje gång komponenten ändras.
Källor
- Förbereda appens text för översättning — Apple
- LocalizedStringKey — Apple
- init(_:defaultValue:table:locale:bundle:comment:) — Apple
- init(verbatim:) — Apple
- Identifiera strängkataloger — Apple
- Nyheter i Swift — Apple
- init(_:tableName:bundle:comment:) — Apple
- Lokalisera och variera text med en strängkatalog — Apple
- Kodgenomgång: Utforska lokalisering med Xcode — Apple
- LocalizedStringKey.StringInterpolation — Apple