Lös en lokaliseringsnyckel i ett ramverk genom att ange både dess resurspaket och dess strängtabell. Den här guiden visar hur du får en etikett som ägs av ett ramverk att visas korrekt i en Mac-app och sedan kontrollerar att resultatet hämtades från tabellen i stället för från reservtext.

Uppgiften är avsiktligt liten: visa den syntetiska etiketten Öppna panel från ramverkets katalog Panel.xcstrings. Du behöver ett Mac-approjekt i Xcode och ett ramverksmål som du kontrollerar. Huvudexemplet använder Xcode 26 eller senare och har macOS 12 eller senare som målplattform; Apple dokumenterar att initieraren för lokaliserade strängar finns tillgänglig från och med macOS 12. Dokumentation för Swift-initieraren.

Identifiera paketet, tabellen och nyckeln innan du ändrar kod

Se ett lokaliserat meddelande som en sökning med tre uttryckliga koordinater. Paketet identifierar resursägaren, tabellen identifierar en grupp strängar i paketet och nyckeln identifierar en post i tabellen. Apples lokaliserings-API:er exponerar paketet och tabellen separat eftersom både ramverk och appmål kan innehålla strängresurser. Förbereda appens text för översättning.

Skriv ned följande kontrakt innan du öppnar katalogen. Det här är exempel på namn, inte namn som Apple kräver.

Del Exempelvärde Syfte
Resursägare Ditt ramverksmål Innehåller katalogen
Katalogfil Panel.xcstrings Lagrar tabellens källtext och översättningar
Tabellargument Panel Väljer katalogen utan filändelsen
Nyckel PANEL_OPEN_ACTION Identifierar meddelandet
Engelsk källtext Öppna panel Tillhandahåller läsbar gränssnittstext
Kommentar Etikett för åtgärden som öppnar panelen. Förklarar hur meddelandet används

table: \"Panel\" väljer tabellen som representeras av Panel.xcstrings. Om tabellen inte anges väljs Localizable. Om paketet inte heller anges söker stränginitieraren i huvudappens paket. En matchande nyckel i en ramverkskatalog kräver därför både ramverkets paket och rätt tabell. Parametrar för lokaliserade strängar i Swift.

Det här ger dig en användbar felsökningsordning: kontrollera först ägaren, sedan tabellen och till sist posten. Att söka efter alternativa stavningar av nyckeln löser inte problemet om sökningen riktas mot appens resurser när meddelandet tillhör ett ramverk.

Lägg till strängkatalogen i ramverksmålet

I Xcode väljer du File > New > File from Template, väljer plattform, filtrerar efter string och väljer String Catalog. Döp filen till Panel. Kontrollera att katalogen tillhör ramverksmålet, tillsammans med ramverkskällkoden som ska referera till den. Apples arbetsflöde för kataloger tillåter egna katalognamn, och i Apples demonstration av ramverkslokalisering skapas katalogen i ramverksmålet. Lokalisera och anpassa text med en strängkatalog, Apples demonstration av ramverkslokalisering.

Exemplet använder en semantisk nyckel i stället för att använda den visade texten som nyckel. Med PANEL_OPEN_ACTION som identifierare och Öppna panel som standardvärde anger koden båda delarna uttryckligen. Apple stöder detta upplägg med initieraren som tar emot en statisk nyckel och ett separat standardvärde för lokaliseringen. Swift-initierare med statisk nyckel.

Bygg ramverksmålet efter att du har lagt till källkoden nedan. Xcode hittar lokaliserbara API-anrop under byggen och uppdaterar relevanta kataloger. Öppna Panel.xcstrings och kontrollera att den innehåller PANEL_OPEN_ACTION, den engelska källtexten Öppna panel och den förklarande kommentaren. Om posten saknas kontrollerar du källfilens måltillhörighet och om målet som innehåller källfilen byggdes. Apple tillhandahåller också Editor > Assistant för att granska koden som hör till en katalogpost. Fylla i och granska en strängkatalog.

Lös upp meddelandet i ramverket

Placera den här kompletta källfilen i ramverksmålet. Den definierar den lokaliserade strängen och en liten SwiftUI-etikett som den innehållande Mac-appen kan visa. Den innehåller också en diagnostikmetod som används i nästa avsnitt. Koden har kontrollerats mot Apples dokumenterade signaturer; den kördes inte här eftersom en Swift-kompilator inte var tillgänglig.

import Foundation
import SwiftUI

public enum PanelMessages {
    public static var openPanel: String {
        String(
            localized: "PANEL_OPEN_ACTION",
            defaultValue: "Open panel",
            table: "Panel",
            bundle: #bundle,
            comment: "Label for the action that opens the panel."
        )
    }

    public static func lookupReport() -> String {
        let missingMarker = "__PANEL_LOOKUP_MISSING__"
        let result = #bundle.localizedString(
            forKey: "PANEL_OPEN_ACTION",
            value: missingMarker,
            table: "Panel"
        )

        if result == missingMarker {
            return "No entry resolved from the selected bundle and table."
        }

        return "Resolved table value: \(result)"
    }
}

public struct PanelActionLabel: View {
    public init() {}

    public var body: some View {
        Text(verbatim: PanelMessages.openPanel)
    }
}

Uttrycket #bundle utvärderas där du skriver det. I den här ramverkskällfilen tillhandahåller det paketet som hör till ramverksmålet. Om du flyttar samma uttryck till källkod i appmålet tillhandahåller det i stället appens paket. För ett Swift-paketmål dokumenterar Apple att makrot tillhandahåller målets resurspaket. Placera sökningen nära resurserna den äger. Foundations paketmakro.

Deklarationen returnerar en vanlig String vars lokalisering redan har lösts. Vyn använder Text(verbatim:) för att visa resultatet uttryckligen. Den offentliga vyn är bara en etikett; lägg till den i en befintlig appvy där texten ska visas.

Använd en ramverksklass när paketmakrot inte är tillgängligt

Apple stöder också att ett ramverkspaket hämtas via en klass som definieras i ramverket. För ett konventionellt ramverk som innehåller egna resurser är följande en komplett alternativ meddelandeleverantör. Använd den i stället för den tidigare deklarationen av PanelMessages och behåll katalogen och distributionskraven som beskrivits ovan.

import Foundation

private final class PanelBundleAnchor: NSObject {}

public enum PanelMessages {
    public static var openPanel: String {
        String(
            localized: "PANEL_OPEN_ACTION",
            defaultValue: "Open panel",
            table: "Panel",
            bundle: Bundle(for: PanelBundleAnchor.self),
            comment: "Label for the action that opens the panel."
        )
    }
}

Ankarklassen måste kompileras in i ramverket vars resurser du vill använda. Apple dokumenterar att Bundle(for:) returnerar paketet som hör till den angivna klassen, inklusive dess ramverkspaket när det är tillämpligt. En ankarklass som kompileras in i appen identifierar appen i stället. För paketresurser eller resurser som placerats i ett separat paket väljer du deras faktiska resurspaket; en klass placering avgör inte i sig vem som äger dessa resurser. Paketinitierare baserad på klass, Val av resurspaket med makrot.

Bekräfta att den läsbara texten kom från en lyckad sökning

Att se Öppna panel på skärmen är inte tillräckligt bevis för att katalogsökningen lyckades. Initierarens defaultValue returneras när sökningen misslyckas, så samma synliga text kan stå för antingen en lyckad sökning eller en reservtext. Det här beteendet är användbart för läsbar gränssnittstext, men kan dölja ett felaktigt paket eller en felaktig tabell under utvecklingen. Swift-beteende för standardvärde.

Metoden lookupReport() i den första källfilen undanröjer den tvetydigheten. Den utför en sökning med en särskiljande reservmarkör som inte får användas som ett verkligt katalogvärde. Granska dess returvärde i den körande appen eller i en befintlig felsökningskontext. Om den rapporterar att ingen post löstes upp undersöker du de valda resurserna innan du ändrar översättningarna.

Den här diagnostiken följer direkt av det dokumenterade beteendet hos Bundle.localizedString(forKey:value:table:): när en nyckel saknas och den angivna reservtexten inte är tom returnerar metoden reservtexten. Om nyckeln saknas och reservtexten är nil eller tom returneras nyckeln i stället. Markören gör det enklare att skilja ett fel från legitim källtext. Returvärden för lokaliserade strängar i Bundle).

Observation Nästa kontroll
Diagnostiken returnerar meddelandet om saknad post Bekräfta att katalogen byggdes in i det valda paketet och kontrollera sedan Panel och PANEL_OPEN_ACTION
Diagnostiken löser upp ett oväntat värde Granska den exakta posten i den valda tabellen och språket som används i den aktuella körningen
Diagnostiken löser upp korrekt värde men gränssnittet skiljer sig Spåra vilket värde gränssnittet faktiskt visar
Den engelska källtexten visas under en översatt körning Granska postens översättning och körkonfigurationen; en lyckad sökning bevisar inte i sig att den begärda översättningen finns

Tabellen är en felsökningssekvens som härletts ur sökkontraktet. Ett lyckat markörtest visar att sökningen returnerade en post, men det visar inte att alla språk som stöds har en färdig översättning. Kontrollera resursupplösning och översättningarnas fullständighet var för sig.

Testa etiketten på det språk som Mac-appen körs med

För en app som stöder fler språk väljer du det relevanta språket i katalogens sidofält och anger översättningen i textfältet för den posten. Testa sedan via den innehållande Mac-appen. Apple dokumenterar direkt inmatning av översättningar i katalogredigeraren och uppdaterar varje posts översättningsstatus medan du arbetar. Lägga till översättningar i en strängkatalog.

Välj Product > Scheme > Edit Scheme, välj Run och öppna Options för att styra felsökningskörningen. Ställ in App Language på ett språk som stöds av projektet, stäng redigeraren och kör Mac-appen igen. Välj System Language om du vill att körningen ska följa systemets språkinställning. Testa lokaliseringar när du kör appen.

Använd inte stränginitierarens argument locale: som ersättning för det här språktestet. Apple dokumenterar att argumentet styr lokaliseringen av interpolerade värden, till exempel tal, och inte ändrar lokalen som används för att söka efter den lokaliserade strängen. Exemplet utelämnar argumentet eftersom etiketten inte innehåller några interpolerade värden. Swift-parametern locale för lokaliserade strängar.

Håll det slutliga kontraktet litet och tydligt: ramverket äger Panel.xcstrings, sökningen väljer Panel och PANEL_OPEN_ACTION identifierar etiketten. Kontrollera posten med diagnostiken och verifiera sedan den visade översättningen på appens valda körspråk. Då kan du rätta resurssökningen innan du lägger tid på formuleringar som appen kanske aldrig läser in.

Källor