Kurz vor dem Abschluss einer Version liefert ein Übersetzungsdienstleister üblicherweise mehrere .xcloc- oder .xliff-Dateien zurück. Sie direkt per Doppelklick in den alltäglichen Arbeitsbereich eines Entwicklers zu importieren, wirkt zunächst schnell. Tatsächlich können dadurch jedoch veraltete Übersetzungsschlüssel, falsche Zielsprachen und beschädigte Platzhalter gemeinsam in das Projekt gelangen. Zuverlässiger ist ein temporäres Abnahmeverzeichnis auf einem Cloud-Mac: Zuerst wird aus dem aktuellen Commit eine Referenz exportiert, anschließend werden die gelieferten Dateien vorab geprüft und erst danach importiert, auf Änderungen untersucht und gebaut.
Abnahmeumgebung festschreiben
Der Abnahmeknoten sollte mit einem sauberen Commit beginnen. Verwenden Sie weder einen Arbeitsbereich erneut, in den bereits Lokalisierungen importiert wurden, noch ein Verzeichnis mit nicht eingecheckten Änderungen. Für jede Lieferung lässt sich ein temporärer Branch oder ein separates Worktree anlegen:
git fetch origin
git worktree add ../localization-review origin/main
cd ../localization-review
git switch -c review/localization-batch
xcodebuild -version
git status --short
Protokollieren Sie xcodebuild -version, den Commit-SHA, das Ziel-Scheme und die Liefercharge. Nutzt das Team mehrere Xcode-Versionen, sollte außerdem DEVELOPER_DIR ausdrücklich gesetzt werden. So verwenden interaktive Terminals und automatisierte Jobs nicht versehentlich unterschiedliche Toolchains.
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
xcode-select -p
git rev-parse HEAD
Maßstab für die Lokalisierungsabnahme ist nicht, ob sich eine Datei öffnen lässt. Entscheidend ist, dass derselbe Commit mit derselben Xcode-Toolchain und denselben Exportparametern nachvollziehbare Ergebnisse erzeugt.
Bei der Ausführung auf einem Cloud-Mac von GPUMini prüfen Sie zunächst in der Konsole die aktuell verfügbaren Konfigurationen und wählen dann den Knoten für die Abnahme aus. Diese Aufgabe benötigt normalerweise keine hohe Parallelität. Wenn nach dem Import jedoch ein großes Projekt vollständig kompiliert werden soll, müssen ausreichend Arbeitsspeicher und freier Speicherplatz eingeplant werden.
Referenz aus dem aktuellen Projekt exportieren
Bei einer .xcodeproj-Datei kann der Export über den Projektparameter erfolgen. Projekte mit einem Workspace verwenden stattdessen -workspace und müssen ein gemeinsam nutzbares Scheme bereitstellen. Das folgende Beispiel exportiert vereinfachtes Chinesisch, Japanisch und Französisch. Weitere Sprachen lassen sich durch zusätzliche -exportLanguage-Parameter ergänzen:
mkdir -p Artifacts/Baseline
xcodebuild \
-project ExampleApp.xcodeproj \
-scheme ExampleApp \
-exportLocalizations \
-localizationPath Artifacts/Baseline \
-exportLanguage zh-Hans \
-exportLanguage ja \
-exportLanguage fr
Speichern Sie nach Abschluss des Exports zunächst die Dateiliste, anstatt die erhaltenen Übersetzungen sofort zu überschreiben:
find Artifacts/Baseline -type f -print0 \
| sort -z \
| xargs -0 shasum -a 256 > Artifacts/baseline.sha256
Die Referenz beantwortet drei Fragen: Welche übersetzbaren Einheiten enthält das aktuelle Projekt, wie lautet der Ausgangstext und welche Zielsprachen erkennt Xcode? Enthalten die gelieferten Dateien Schlüssel, die in der Referenz nicht vorkommen, basiert die Übersetzung häufig auf einem älteren Commit. Enthält die Referenz dagegen viele neue, noch nicht übersetzte Einheiten, wurden aktuelle Funktionen möglicherweise nicht in den Lieferumfang aufgenommen.
Struktur und Platzhalter vor dem Import prüfen
XLIFF ist im Kern XML. Prüfen Sie zuerst mit den Systemwerkzeugen das Format und lesen Sie danach die Sprachattribute sowie die Anzahl der Übersetzungseinheiten aus. XML sollte nicht mit regulären Ausdrücken umgeschrieben werden. Die Vorabprüfung darf die Daten lesen; Korrekturen sollten im Lokalisierungswerkzeug oder mit einem geprüften Skript vorgenommen werden.
find Incoming -name "*.xliff" -print0 |
while IFS= read -r -d '' file; do
echo "Checking $file"
xmllint --noout "$file"
xmllint --xpath \
'string(/*[local-name()="xliff"]/*[local-name()="file"][1]/@target-language)' \
"$file"
echo
done
Abweichende Platzhalter sind der wichtigste Grund, einen Import zu blockieren. %@, %d, Positionsparameter und von String Catalog erzeugte Variablen müssen in Ausgangs- und Zieltext semantisch übereinstimmen. Es genügt nicht, lediglich die Prozentzeichen zu zählen, denn %%, Formatbreiten und Positionsparameter haben unterschiedliche Bedeutungen. Empfehlenswert ist, source und target jeder trans-unit mit einem XML-Parser getrennt auszulesen, die Platzhalter zu normalisieren und anschließend als Multimengen zu vergleichen.
| Prüfpunkt | Sperrbedingung | Vorgehen |
|---|---|---|
| XML-Struktur | xmllint liefert einen Wert ungleich null |
Lieferdatei zurückweisen |
| Zielsprache | Stimmt nicht mit der Dateicharge überein | Sprachzuordnung korrigieren und erneut exportieren |
| Übersetzungseinheiten | Unbekannte ID vorhanden | Commit der Referenz prüfen |
| Platzhalter | Typ oder Anzahl stimmt nicht überein | Übersetzung korrigieren und erneut prüfen |
| Leere Übersetzung | Zieltext einer wichtigen Oberfläche ist leer | Klären, ob ein Fallback zulässig ist |
Bei benutzerseitig sichtbaren Formatzeichenfolgen sollten außerdem Zeilenumbrüche, Escape-Zeichen und Pluralzweige stichprobenartig geprüft werden. Die Reihenfolge der Platzhalter darf sich je nach Sprache ändern. Bei Positionsparametern müssen die Indizes jedoch gültig bleiben.
In ein getrenntes Verzeichnis importieren und Änderungen prüfen
Nach bestandener Vorabprüfung werden die .xcloc-Pakete einzeln importiert. Erfassen Sie den Status unmittelbar nach jedem Import, damit sich die Lieferung, die eine Auffälligkeit verursacht hat, leichter ermitteln lässt:
mkdir -p Artifacts/Logs
for package in Incoming/*.xcloc; do
name="$(basename "$package" .xcloc)"
xcodebuild \
-project ExampleApp.xcodeproj \
-importLocalizations \
-localizationPath "$package" \
2>&1 | tee "Artifacts/Logs/import-${name}.log"
test "${PIPESTATUS[0]}" -eq 0 || exit 1
git status --short
done
Ein erfolgreicher Import bedeutet noch nicht, dass die Abnahme abgeschlossen ist. Prüfen Sie zunächst mit git diff --stat den Umfang der Änderungen und lesen Sie anschließend die Unterschiede jeder einzelnen Datei. Erwartbare Änderungen sollten sich auf String Catalogs, Zeichenfolgenressourcen oder die jeweiligen Sprachverzeichnisse beschränken. Werden Schemes, Build-Einstellungen, Signaturkonfigurationen oder nicht betroffene Projektdateien verändert, muss der Vorgang angehalten und die Ursache geklärt werden.
git diff --stat
git diff --check
git diff -- '*.xcstrings' '*.strings' '*.stringsdict' 'project.pbxproj'
git diff --check erkennt unter anderem einige nachgestellte Leerzeichen und Spuren von Konflikten, kann aber die Bedeutung einer Übersetzung nicht beurteilen. Es empfiehlt sich, eine Übersicht der hinzugefügten, entfernten und geänderten Übersetzungseinheiten zu erzeugen und zusammen mit den Importprotokollen als Pipeline-Artefakt zu speichern.
Prüfung mit Build und erneutem Export abschließen
Führen Sie abschließend einen sauberen Build des Ziel-Schemes aus. Enthält das Projekt mehrere Anwendungsziele oder Erweiterungen, muss der tatsächliche Veröffentlichungspfad abgedeckt werden. Es reicht nicht, nur das kleinste Bibliotheksziel zu bauen.
set -o pipefail
xcodebuild \
-project ExampleApp.xcodeproj \
-scheme ExampleApp \
-configuration Release \
-destination 'generic/platform=iOS Simulator' \
clean build |
tee Artifacts/Logs/localization-build.log
Exportieren Sie nach einem erfolgreichen Build erneut XLIFF aus dem Projekt mit den importierten Übersetzungen und vergleichen Sie das Ergebnis mit der Referenz. Durch diesen erneuten Export lässt sich erkennen, ob Übersetzungen nicht tatsächlich in das Projekt übernommen wurden, Sprachcodes falsch zugeordnet sind oder weiterhin unübersetzte Einheiten bestehen. Reine Sortierungsunterschiede und von Werkzeugen erzeugte Metadaten sollten beim Vergleich ignoriert werden. Relevant sind ausschließlich Ausgangstext, Zieltext, Status und Anmerkungen der Übersetzungseinheiten.
Eine wartbare Abnahmepipeline sollte vier Arten von Nachweisen eindeutig speichern: Informationen zu Toolchain und Commit, den Bericht der Vorabprüfung, eine Zusammenfassung der Importänderungen und das Build-Protokoll. Bei einem Fehler sollte das Arbeitsverzeichnis nicht automatisch gelöscht, sondern zunächst zur Untersuchung erhalten bleiben. Nach erfolgreichem Abschluss wird das temporäre Worktree dagegen entfernt, damit die nächste Lieferung keinen alten Zustand übernimmt.
Das abschließende Gate lässt sich auf folgende Bedingungen reduzieren: XML ist parsbar, die Zielsprache ist korrekt, die Platzhaltermengen stimmen überein, es gibt keine unbekannten Übersetzungseinheiten, der Änderungsumfang entspricht den Erwartungen und das Ziel-Scheme lässt sich erfolgreich bauen. Damit dient der Cloud-Mac als reproduzierbarer Knoten für die Lokalisierungsabnahme und nicht als weitere Importumgebung, deren Zustand nur durch menschliche Erinnerung gewahrt wird.
Häufig gestellte Fragen
Warum sollte vor der Prüfung eine neue XLIFF-Referenz exportiert werden?
Sie bildet die Übersetzungseinheiten, Quelltexte und Zielsprachen des aktuellen Projekts ab und macht veraltete oder unbekannte Einträge sichtbar.
Bedeutet ein erfolgreicher XLIFF-Import, dass die Übersetzung fertig ist?
Nein. Platzhalter, Pluralregeln und Dateidifferenzen müssen geprüft werden; zusätzlich ist ein sauberer Build des betroffenen Schemas erforderlich.
Sollte der Import direkt im Hauptarbeitsbereich erfolgen?
Nein. Eine temporäre Branch oder ein getrenntes Worktree schützt den Hauptstand. Nur geprüfte Ressourcenänderungen sollten übernommen werden.
Für Entwicklungs- und Build-Aufgaben einen Cloud-Mac auswählen
Zwei M4-Konfigurationen, vier Mietzeiträume und vier verfügbare Knoten vergleichen und anschließend die Bereitstellung passend zur Aufgabe abschließen.