Untuk app Mac dengan panel milik framework, tentukan fallback pada dua tingkat: bahasa yang dipilih setiap bundle dan teks yang dikembalikan setiap pesan saat pencariannya gagal. Gunakan lokalisasi pengembangan dalam bahasa Inggris dan nilai default bahasa Inggris yang eksplisit untuk pesan yang Anda miliki.

Panduan ini menerapkan kontrak tersebut untuk jendela desktop sederhana yang berisi label milik app Workspace dan label milik framework Panel ready. Label-label ini bersifat sintetis. Tugasnya adalah memastikan pesan tersebut tetap dapat dibaca saat bahasa atau terjemahannya tidak tersedia, sambil mempertahankan lokalisasi normal jika terjemahan tersedia.

Apa yang harus dijanjikan oleh kontrak fallback?

Terapkan kontrak ini untuk pesan milik app dan framework: gunakan lokalisasi yang tersedia dan dipilih melalui pencocokan bahasa sistem; gunakan bahasa Inggris sebagai lokalisasi pengembangan saat tidak ada bahasa pilihan yang cocok; dan kembalikan nilai default bahasa Inggris yang eksplisit untuk suatu pesan jika pencarian string-nya gagal. Setiap pesan harus mencantumkan bundle dan tabel string yang memilikinya.

Pemilihan bahasa mempertimbangkan bahasa pilihan pengguna dan lokalisasi yang tersedia. Bahasa pilihan pertama yang tidak tersedia tidak berarti bahasa Inggris langsung ditampilkan: bahasa pilihan lain mungkin cocok terlebih dahulu. Panduan bundle Apple yang diarsipkan menjelaskan urutan pemilihan tersebut, lalu lokalisasi pengembangan jika tidak ada bahasa pilihan yang cocok. Dokumentasi saat ini mendefinisikan CFBundleDevelopmentRegion sebagai pengenal bahasa fallback bundle. Mengakses Konten Bundle, CFBundleDevelopmentRegion.

Gunakan tabel keputusan berikut saat menentukan hasil yang diharapkan. Tabel ini memisahkan pemilihan resource dari pencarian pesan, alih-alih menganggap semua terjemahan yang tidak tersedia sebagai kondisi yang sama.

Kondisi Kontrak untuk pesan yang Anda miliki Hal yang perlu diperiksa
Bahasa pilihan memiliki terjemahan yang tersedia Tampilkan terjemahan tersebut Bundle, tabel, dan kunci
Bahasa pilihan pertama tidak tersedia, tetapi bahasa pilihan lain cocok Izinkan pencocokan bahasa sistem memilih lokalisasi yang tersedia Urutan preferensi dan resource yang disertakan
Tidak ada lokalisasi pilihan yang cocok Gunakan resource pengembangan bahasa Inggris bundle Bahasa pengembangan dan resource bahasa Inggris
Pencarian yang dipilih tidak dapat menemukan pesan Kembalikan nilai default bahasa Inggris yang eksplisit untuk pesan tersebut defaultValue milik pesan
Pencarian framework secara tidak sengaja mengarah ke bundle app Perbaiki argumen bundle Kepemilikan resource
Terjemahan tersedia tetapi teksnya tidak sesuai Perbaiki terjemahan Konten katalog dan peninjauan

Tabel ini menggabungkan aturan pemilihan resource Apple dengan perilaku nilai default yang didokumentasikan untuk initializer Swift. Ini adalah kebijakan implementasi yang diturunkan dari API tersebut, bukan fitur fallback tersendiri di String Catalog. Pencarian yang berhasil tetapi menghasilkan teks yang tidak sesuai tidak memenuhi kondisi terdokumentasi initializer untuk menggunakan nilai default: pencarian gagal. String.init(localized:defaultValue:table:bundle:locale:comment:).

Konfigurasikan resource sumber bahasa Inggris di setiap target pemilik

Untuk contoh ini, gunakan instalasi Xcode terkini, app SwiftUI macOS yang menargetkan macOS 13 atau lebih baru, dan target framework Swift dinamis tertanam bernama PanelKit. Tautkan dan sematkan framework tersebut di app. Ini adalah prasyarat proyek untuk contoh ini; nama framework tersebut tidak mengidentifikasi produk yang sudah ada.

Tetapkan bahasa Inggris sebagai bahasa pengembangan untuk kedua target, lalu pastikan CFBundleDevelopmentRegion pada setiap bundle hasil build bernilai en. Sediakan resource sumber bahasa Inggris yang sesuai di kedua target. Pengenal bahasa pengembangan menjelaskan bahasa fallback; pengenal itu tidak menyediakan konten pesan yang hilang. Apple mendokumentasikan en sebagai pengenal bahasa Inggris. CFBundleDevelopmentRegion.

Buat katalog Localizable.xcstrings terpisah untuk setiap target. Di Xcode, pilih File > New > File from Template, pilih String Catalog, lalu beri nama Localizable. Tetapkan satu katalog ke target app dan katalog lainnya ke target framework. Memisahkan kepemilikan resource memungkinkan setiap pencarian diverifikasi secara mandiri. Apple mendokumentasikan alur pembuatan katalog dan mendukung beberapa katalog. Melokalkan dan memvariasikan teks dengan katalog string.

Setelah menambahkan kode di bawah, pilih Product > Build. Xcode mengekstrak pemanggilan yang dapat dilokalkan ke dalam katalog. Pastikan workspace.title muncul di katalog app dan panel.ready muncul di katalog framework, dengan nilai sumber bahasa Inggris yang dimaksud. Tambahkan bahasa yang didukung menggunakan tombol tambah di bilah sisi katalog dan masukkan terjemahan untuk pesan terkait. Melokalkan dan memvariasikan teks dengan katalog string.

Kelengkapan katalog dan kebenaran pencarian runtime perlu diperiksa secara terpisah. Entri terjemahan di katalog framework tidak membantu pemanggilan yang mencari di bundle app. Apple secara eksplisit menginstruksikan kode yang memuat string di luar bundle utama untuk meneruskan bundle yang terkait dengan target tersebut. Menyiapkan teks app Anda untuk diterjemahkan.

Tetapkan bundle, kunci, tabel, dan nilai default untuk setiap pesan

Gunakan kunci sintetis yang stabil dan nilai default bahasa Inggris yang mudah dibaca. Initializer Swift yang menerima defaultValue mendukung penggunaan kunci yang berbeda dari teks sumber yang ditampilkan. Nilai default-nya dikembalikan jika pencarian string yang dilokalkan dari bundle gagal. Parameter table memilih tabel string; jika dihilangkan, Localizable yang dipilih. String.init(localized:defaultValue:table:bundle:locale:comment:).

Letakkan pesan framework di framework

Tambahkan berkas sumber Swift lengkap ini ke target framework dinamis PanelKit. Kelas penanda didefinisikan di target tersebut agar Bundle(for:) mengidentifikasi bundlenya. Apple mendokumentasikan pendekatan berbasis kelas ini sebagai alternatif untuk makro #bundle saat ini. Menyiapkan teks app Anda untuk diterjemahkan.

import Foundation

private final class PanelBundleAnchor: NSObject {}

public enum PanelText {
    public static var resourceBundle: Bundle {
        Bundle(for: PanelBundleAnchor.self)
    }

    public static var ready: String {
        String(
            localized: "panel.ready",
            defaultValue: "Panel ready",
            table: "Localizable",
            bundle: resourceBundle,
            comment: "Status label above the framework panel."
        )
    }
}

Framework mencari pesannya sebelum mengembalikan String ke app. Ini menetapkan batas kepemilikan yang jelas: framework mengendalikan kunci, teks sumber, tabel, dan bundle resource. App menerima teks hasilnya untuk ditampilkan.

Tampilkan pesan app dan framework bersama-sama

Ganti berkas titik masuk app yang dibuat otomatis dengan contoh lengkap ini. Contoh ini mengasumsikan modul framework tertaut bernama PanelKit dan berisi berkas sebelumnya. Pertahankan hanya satu titik masuk app di target app.

import Foundation
import SwiftUI
import PanelKit

@main
struct FallbackDemoApp: App {
    var body: some Scene {
        WindowGroup {
            VStack(alignment: .leading, spacing: 12) {
                Text(verbatim: String(
                    localized: "workspace.title",
                    defaultValue: "Workspace",
                    table: "Localizable",
                    bundle: .main,
                    comment: "Heading for the main workspace."
                ))

                Text(verbatim: PanelText.ready)
            }
            .padding(24)
        }
    }
}

Pencarian app secara eksplisit menggunakan .main; pencarian framework menggunakan bundle resource-nya sendiri. Keduanya menyediakan nilai default bahasa Inggris. Ini mengikuti pemilihan bundle dan parameter nilai default yang didokumentasikan Apple. Build dan jalankan proyek di Xcode untuk memvalidasi konfigurasi target secara menyeluruh; contoh-contoh ini belum dijalankan di sini. String.init(localized:defaultValue:table:bundle:locale:comment:).

Untuk implementasi yang sudah ada dan menggunakan Bundle.localizedString(forKey:value:table:), berikan value yang tidak kosong dan mudah dibaca jika Anda memerlukan hasil yang mudah dibaca untuk kunci yang hilang. Apple mendokumentasikan bahwa kunci yang hilang akan mengembalikan kunci itu sendiri jika value tidak ada atau kosong, dan mengembalikan value jika nilainya tidak kosong. Karena itu, kunci seperti panel.ready memerlukan fallback eksplisit jika menampilkan pengenal tersebut melanggar kontrak pesan. localizedString(forKey:value:table:).

Tentukan apakah framework boleh memilih bahasa yang berbeda

Meneruskan bundle yang benar menentukan lokasi pencarian. Konfigurasi lokalisasi campuran memengaruhi hubungan pemilihan lokalisasi dengan app yang memuatnya. Apple menyediakan Boolean CFBundleAllowMixedLocalizations, yang ditampilkan sebagai Localized resources can be mixed, untuk mengambil string yang dilokalkan dari framework. CFBundleAllowMixedLocalizations.

Penjelasan perilaku ini di Swift Forums menyatakan bahwa mengaktifkan kunci tersebut di Info.plist app memungkinkan bundle lain memilih lokalisasi di luar lokalisasi yang didukung app utama. Tanpa pilihan itu, bundle utama membatasi pemilihannya. Ini adalah diskusi penjelasan yang lebih lama, dan dapat digunakan bersama referensi kunci Apple terkini. Lokalisasi Swift package manager.

Untuk jendela contoh, sebaiknya samakan cakupan bahasa yang didukung oleh app dan framework, dengan resource pengembangan bahasa Inggris di keduanya. Jangan sertakan pemilihan bahasa framework secara independen dalam kontrak awal. Jika perilaku yang Anda inginkan adalah mengizinkan framework menggunakan terjemahan tambahan, atur Boolean CFBundleAllowMixedLocalizations app ke YES dan uji konfigurasi tersebut secara eksplisit. Lokalisasi Swift package manager.

Mengaktifkan kunci ini tidak menyediakan terjemahan atau nilai default untuk pesan yang hilang. Tanggung jawab tersebut tetap berada pada berkas resource dan pemanggilan pencarian. Demikian pula, nilai default yang diberikan pada pemanggilan Anda menentukan hasil pemanggilan itu saat pencarian gagal; nilai tersebut tidak menetapkan fallback bahasa Inggris universal untuk setiap kontrol sistem atau pesan framework.

Hindari menggunakan argumen locale pada initializer String ini sebagai pengalih bahasa terjemahan. Apple secara eksplisit mendokumentasikan bahwa argumen tersebut mengendalikan pelokalan nilai interpolasi, seperti angka, dan tidak mengubah lokal yang digunakan untuk mencari string yang dilokalkan. Gunakan konfigurasi bahasa dan kontrol pengujian yang didukung untuk tugas ini. String.init(localized:defaultValue:table:bundle:locale:comment:).

Uji bahasa yang hilang secara terpisah dari pesan yang hilang

Jalankan pemeriksaan lokalisasi melalui Product > Scheme > Edit Scheme. Pilih Run, buka Options, pilih App Language, tutup dialog, lalu jalankan kembali app Mac. Apple mendokumentasikan alur kerja ini untuk menguji lokalisasi tanpa mengubah pengaturan seluruh sistem. Jangan ubah pemilihan wilayah saat menyelidiki masalah yang hanya berkaitan dengan bahasa. Menguji lokalisasi saat menjalankan app.

Gunakan matriks pengujian berikut sebagai alat diagnostik khusus proyek. Untuk memeriksa perutean bundle, gunakan sementara penanda pengujian bahasa Inggris yang berbeda, seperti App translation sample dan Framework translation sample, dalam lokalisasi non-sumber yang didukung. Ini adalah konten diagnostik, bukan terjemahan atau pengenal bahasa.

  1. Verifikasi perilaku sumber. Jalankan dengan bahasa Inggris dipilih. Harapkan Workspace dan Panel ready.
  2. Verifikasi perutean resource terjemahan. Pilih lokalisasi pengujian yang didukung. Harapkan penanda berbeda dari kedua katalog pemilik.
  3. Verifikasi nilai default untuk pesan yang hilang. Dalam perubahan pengujian sementara, ubah kunci pencarian framework menjadi panel.ready.probe, biarkan defaultValue tetap sama, dan pastikan entri pengujian tersebut tidak disertakan dalam katalog pengujian. Harapkan Panel ready saat pencarian gagal. Setelah itu, pulihkan kunci semula.
  4. Verifikasi pemilihan bahasa yang tidak didukung. Uji daftar preferensi yang tidak memiliki bahasa yang cocok. Pastikan kedua bundle yang Anda miliki menggunakan resource pengembangan bahasa Inggrisnya. Uji juga bahasa pilihan pertama yang tidak didukung diikuti bahasa pilihan yang didukung, karena kasus tersebut memiliki hasil yang berbeda.
  5. Verifikasi lokalisasi campuran jika diaktifkan. Uji bahasa yang hanya tersedia di framework. Catat perilaku yang diinginkan dan uji pengaturan lokalisasi campuran app terhadapnya.

Pemeriksaan ketiga mengisolasi pencarian yang gagal; pemeriksaan keempat mengisolasi pencocokan bahasa. Hanya menguji baris katalog yang belum diterjemahkan dapat mengaburkan kondisi tersebut karena konfigurasi resource yang dihasilkan juga memengaruhi pencarian. Hasil yang diharapkan untuk kunci yang hilang berasal dari initializer Swift, sedangkan pemilihan bahasa pilihan mengikuti aturan bundle. String.init(localized:defaultValue:table:bundle:locale:comment:), Mengakses Konten Bundle.

Jika hasilnya berbeda, periksa bundle yang sebenarnya memiliki resource tersebut. developmentLocalization melaporkan nilai yang terkait dengan CFBundleDevelopmentRegion; preferredLocalizations melaporkan lokalisasi yang tersedia, diurutkan berdasarkan preferensi bahasa. Bandingkan properti ini pada Bundle.main dan PanelText.resourceBundle. Properti ini membantu mendiagnosis konfigurasi, tetapi pesan yang ditampilkan tetap menjadi pemeriksaan akhir untuk setiap pencarian. developmentLocalization, preferredLocalizations.

Kontrak fallback yang baik membuat setiap hasil dapat dijelaskan: bahasa yang dipilih berasal dari pencocokan bundle, pesan berasal dari tabel pemiliknya, dan pencarian yang gagal mengembalikan nilai default yang eksplisit serta mudah dibaca. Terapkan aturan tersebut pada setiap pesan app dan framework yang Anda miliki, lalu verifikasi semuanya bersama-sama di jendela desktop tempat pengguna menemukannya.

Sumber