Aby rozwiązać klucz lokalizacyjny frameworka, przekaż zarówno jego pakiet zasobów, jak i tabelę ciągów. Z tego poradnika dowiesz się, jak sprawić, by etykieta należąca do frameworka wyświetlała się poprawnie w aplikacji na Maca, a następnie sprawdzić, czy wynik pochodzi z tabeli, a nie z tekstu zastępczego.

Zadanie jest celowo niewielkie: wyświetlenie syntetycznej etykiety Open panel z katalogu Panel.xcstrings należącego do frameworka. Potrzebujesz projektu aplikacji na Maca w Xcode oraz kontrolowanego przez siebie celu frameworka. Główny przykład korzysta z Xcode 26 lub nowszego i jest przeznaczony dla macOS 12 lub nowszego; Apple dokumentuje, że inicjalizator zlokalizowanego ciągu jest dostępny od macOS 12. Dokumentacja inicjalizatora Swift.

Przed zmianą kodu ustal pakiet, tabelę i klucz

Traktuj zlokalizowany komunikat jako wyszukiwanie z trzema jawnymi współrzędnymi. Pakiet wskazuje właściciela zasobu, tabela wskazuje grupę ciągów w tym pakiecie, a klucz wskazuje wpis w tej tabeli. Interfejsy API Apple do lokalizacji przyjmują osobno pakiet i tabelę, ponieważ zasoby ciągów mogą znajdować się zarówno w frameworkach, jak i w celach aplikacji. Przygotowanie tekstu aplikacji do tłumaczenia.

W tym przykładzie przed otwarciem katalogu zapisz poniższy kontrakt. Są to przykładowe nazwy, a nie nazwy wymagane przez Apple.

Element Przykładowa wartość Zastosowanie
Właściciel zasobu Cel Twojego frameworka Zawiera katalog
Plik katalogu Panel.xcstrings Przechowuje tekst źródłowy tabeli i tłumaczenia
Argument tabeli Panel Wybiera ten katalog bez rozszerzenia
Klucz PANEL_OPEN_ACTION Identyfikuje komunikat
Angielska wartość źródłowa Open panel Dostarcza czytelny tekst interfejsu
Komentarz Label for the action that opens the panel. Wyjaśnia zastosowanie komunikatu

Przekazanie table: "Panel" wybiera tabelę reprezentowaną przez Panel.xcstrings. Jeśli nie ustawisz tabeli, zostanie wybrana Localizable. Podobnie nieustawienie pakietu powoduje, że inicjalizator ciągu przeszukuje główny pakiet aplikacji. Dlatego klucz znajdujący się w katalogu frameworka wymaga zarówno pakietu tego frameworka, jak i prawidłowej tabeli. Parametry zlokalizowanego ciągu w Swift.

Dzięki temu masz przydatną kolejność diagnostyczną: najpierw sprawdź właściciela, potem tabelę, a na końcu wpis. Szukanie alternatywnych zapisów klucza nie pomoże, jeśli wyszukiwanie jest skierowane do zasobów aplikacji, a komunikat należy do frameworka.

Dodaj katalog ciągów do celu frameworka

W Xcode wybierz File > New > File from Template, wybierz platformę, przefiltruj wyniki według string i wybierz String Catalog. Nazwij plik Panel. Upewnij się, że katalog należy do celu frameworka, obok źródła frameworka, które będzie się do niego odwoływać. Przepływ pracy Apple z katalogami pozwala używać własnych nazw, a w przykładzie frameworka Apple katalog jest tworzony w celu frameworka. Lokalizowanie i różnicowanie tekstu za pomocą katalogu ciągów, Przykład lokalizacji frameworka Apple.

W przykładzie użyto klucza semantycznego, zamiast traktować wyświetlany tekst jako klucz. Użycie PANEL_OPEN_ACTION jako identyfikatora i Open panel jako domyślnej wartości pozwala jawnie określić oba elementy w kodzie. Apple obsługuje taki układ za pomocą inicjalizatora, który przyjmuje statyczny klucz i osobną domyślną wartość lokalizacyjną. Inicjalizator Swift ze statycznym kluczem.

Po dodaniu poniższego źródła zbuduj cel frameworka. Podczas kompilacji Xcode wykrywa wywołania lokalizowalnych interfejsów API i aktualizuje odpowiednie katalogi. Otwórz Panel.xcstrings i sprawdź, czy zawiera PANEL_OPEN_ACTION, angielską wartość źródłową Open panel oraz komentarz objaśniający. Jeśli brakuje wpisu, sprawdź przynależność źródła do celu oraz to, czy cel zawierający to źródło został zbudowany. Apple udostępnia też funkcję Editor > Assistant, która pozwala sprawdzić kod powiązany z wpisem katalogu. Wypełnianie i sprawdzanie katalogu ciągów.

Rozwiąż komunikat wewnątrz frameworka

Umieść ten kompletny plik źródłowy w celu frameworka. Definiuje on zlokalizowany ciąg i niewielką etykietę SwiftUI, którą może wyświetlić zawierająca ją aplikacja na Maca. Zawiera też metodę diagnostyczną używaną w następnej sekcji. Kod sprawdzono pod kątem zgodności z udokumentowanymi sygnaturami Apple; nie został tu uruchomiony, ponieważ kompilator Swift nie był dostępny.

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)
    }
}

Wyrażenie #bundle jest obliczane w miejscu, w którym je zapiszesz. W tym źródle frameworka zwraca pakiet powiązany z celem frameworka. Jeśli przeniesiesz to samo wyrażenie do źródła celu aplikacji, zwróci ono pakiet aplikacji. W przypadku celu pakietu Swift Apple dokumentuje, że makro zwraca pakiet zasobów tego celu. Umieść wyszukiwanie obok zasobów, do których się odnosi. Makro pakietu w Foundation.

Deklaracja zwraca zwykły String, którego lokalizacja została już rozwiązana. Widok używa Text(verbatim:), aby jawnie wyświetlić ten wynik. Widok publiczny to tylko etykieta; dodaj go do istniejącego widoku aplikacji w miejscu, w którym ma pojawić się tekst.

Użyj klasy frameworka, gdy makro pakietu jest niedostępne

Apple umożliwia też znalezienie pakietu frameworka za pomocą klasy zdefiniowanej w tym frameworku. W przypadku typowego frameworka zawierającego własne zasoby poniższy kod stanowi kompletną alternatywną funkcję dostarczającą komunikat. Użyj jej zamiast wcześniejszej deklaracji PanelMessages i zachowaj opisane wyżej wymagania dotyczące katalogu i minimalnej wersji systemu.

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."
        )
    }
}

Klasa kotwicząca musi być skompilowana w frameworku, którego zasobów chcesz użyć. Apple dokumentuje, że Bundle(for:) zwraca pakiet powiązany z przekazaną klasą, w tym pakiet jej frameworka, jeśli ma to zastosowanie. Klasa skompilowana w aplikacji wskazywałaby na aplikację. W przypadku zasobów pakietu Swift lub zasobów umieszczonych w osobnym pakiecie wybierz właściwy pakiet zasobów; samo położenie klasy nie określa, do kogo należą te zasoby. Inicjalizator pakietu oparty na klasie, Wybór pakietu zasobów za pomocą makra.

Sprawdź, czy czytelny tekst pochodzi z udanego wyszukiwania

Samo wyświetlenie Open panel na ekranie nie dowodzi, że wyszukiwanie w katalogu się powiodło. W razie niepowodzenia wyszukiwania inicjalizator zwraca defaultValue, dlatego ten sam widoczny tekst może oznaczać zarówno udane wyszukiwanie, jak i użycie wartości zastępczej. To przydatne zachowanie w przypadku czytelnego tekstu interfejsu, ale podczas pracy nad aplikacją może ukryć błędny pakiet lub tabelę. Działanie wartości domyślnej w Swift.

Metoda lookupReport() z pierwszego pliku źródłowego rozwiązuje tę niejednoznaczność. Wyszukuje ciąg, używając charakterystycznego znacznika zastępczego, którego nie należy używać jako prawdziwej wartości katalogu. Sprawdź jej wartość zwracaną w uruchomionej aplikacji lub w istniejącym kontekście debugowania. Jeśli metoda zgłosi brak rozwiązanego wpisu, przed edycją tłumaczeń sprawdź wybrane zasoby.

Ta diagnostyka wynika bezpośrednio z udokumentowanego działania Bundle.localizedString(forKey:value:table:): gdy brakuje klucza, a przekazana wartość zastępcza nie jest pusta, metoda zwraca tę wartość. Jeśli brakuje klucza, a wartość zastępcza jest nil lub pusta, metoda zwraca sam klucz. Znacznik ułatwia odróżnienie błędu od prawidłowego tekstu źródłowego. Wartości zwracane przez zlokalizowany ciąg z pakietu).

Obserwacja Co sprawdzić dalej
Diagnostyka zwraca komunikat o brakującym wpisie Potwierdź, że katalog został wbudowany w wybrany pakiet, a następnie sprawdź Panel i PANEL_OPEN_ACTION
Diagnostyka rozwiązuje nieoczekiwaną wartość Sprawdź dokładnie ten wpis w wybranej tabeli oraz język używany podczas bieżącego uruchomienia
Diagnostyka rozwiązuje właściwą wartość, ale interfejs wyświetla coś innego Prześledź, jaką wartość faktycznie wyświetla interfejs
Podczas uruchomienia w tłumaczeniu pojawia się angielska wartość źródłowa Sprawdź tłumaczenie wpisu i konfigurację uruchomienia; samo udane wyszukiwanie nie dowodzi, że istnieje wymagane tłumaczenie

Tabela przedstawia kolejność postępowania w razie problemów, wyprowadzoną z kontraktu wyszukiwania. Udana próba ze znacznikiem potwierdza, że wyszukiwanie zwróciło wpis, ale nie dowodzi, że każde obsługiwane językowo tłumaczenie jest gotowe. Sprawdzaj rozwiązywanie zasobów i kompletność tłumaczeń osobno.

Przetestuj etykietę w języku wybranym w aplikacji na Maca

Jeśli aplikacja obsługuje dodatkowe języki, wybierz odpowiedni język na pasku bocznym katalogu i wpisz tłumaczenie w polu tekstowym tego wpisu. Następnie przetestuj aplikację w jej docelowej wersji na Maca. Apple dokumentuje bezpośrednie wpisywanie tłumaczeń w edytorze katalogu, który na bieżąco aktualizuje stan tłumaczenia każdego wpisu. Dodawanie tłumaczeń do katalogu ciągów.

Aby ustawić język uruchomienia debugowania, wybierz Product > Scheme > Edit Scheme, zaznacz Run i otwórz Options. Ustaw App Language na język obsługiwany przez projekt, zamknij edytor i ponownie uruchom aplikację na Maca. Wybierz System Language, jeśli język uruchomienia ma być zgodny z ustawieniem językowym systemu. Testowanie lokalizacji podczas uruchamiania aplikacji.

Nie używaj argumentu locale: inicjalizatora ciągu zamiast tego testu językowego. Apple dokumentuje, że ten argument steruje lokalizacją interpolowanych wartości, takich jak liczby, i nie zmienia lokalizacji używanej do wyszukiwania zlokalizowanego ciągu. W przykładzie go pominięto, ponieważ etykieta nie zawiera wartości interpolowanych. Parametr lokalizacji w zlokalizowanym ciągu Swift.

Końcowy kontrakt pozostaje niewielki i jawny: właścicielem Panel.xcstrings jest framework, wyszukiwanie wybiera Panel, a PANEL_OPEN_ACTION identyfikuje etykietę. Sprawdź wpis za pomocą diagnostyki, a następnie sprawdź wyświetlane tłumaczenie w języku wybranym dla uruchomienia aplikacji. Dzięki temu najpierw poprawisz wyszukiwanie zasobów, zanim poświęcisz czas na tekst, którego aplikacja może w ogóle nie odczytywać.

Źródła