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
- Przygotowanie tekstu aplikacji do tłumaczenia — Apple
- Lokalizowanie i różnicowanie tekstu za pomocą katalogu ciągów — Apple
- Ćwiczenie z kodowaniem: odkrywanie lokalizacji w Xcode — Apple
init(localized:defaultValue:table:bundle:locale:comment:)— Appleinit(localized:table:bundle:locale:comment:)— Applebundle()— Appleinit(for:)— ApplelocalizedString(forKey:value:table:)— Apple- Testowanie lokalizacji podczas uruchamiania aplikacji — Apple