لحل مفتاح ترجمة في إطار عمل، مرّر كلاً من حزمة موارده وجدول السلاسل النصية الخاص به. يوضّح هذا الدليل كيفية إظهار تسمية يملكها إطار عمل على نحو صحيح في تطبيق Mac، ثم التحقق من أن النتيجة جاءت من الجدول لا من نص احتياطي.
المهمة صغيرة عن قصد: عرض التسمية الاصطناعية Open panel من كتالوج Panel.xcstrings الخاص بإطار عمل. ستحتاج إلى مشروع تطبيق Mac في Xcode وهدف إطار عمل تتحكم فيه. يستخدم المثال الرئيسي Xcode 26 أو إصداراً أحدث ويستهدف macOS 12 أو إصداراً أحدث؛ وتوثّق Apple أن مُهيّئ السلاسل المترجمة متاح بدءاً من macOS 12. توثيق مُهيّئ Swift.
حدّد الحزمة والجدول والمفتاح قبل تغيير الشيفرة
تعامل مع الرسالة المترجمة على أنها عملية بحث لها ثلاث إحداثيات صريحة. تحدد الحزمة مالك المورد، ويحدد الجدول مجموعة السلاسل النصية ضمن تلك الحزمة، ويحدد المفتاح مُدخلاً ضمن ذلك الجدول. تكشف واجهات Apple للترجمة عن الحزمة والجدول كلٌّ على حدة، لأن أهداف إطارات العمل والتطبيقات يمكن أن يحتوي كل منها على موارد سلاسل نصية. إعداد نص تطبيقك للترجمة.
في هذا المثال، دوّن العقد التالي قبل فتح الكتالوج. هذه أسماء توضيحية وليست أسماء تفرضها Apple.
| الجزء | القيمة النموذجية | الغرض |
|---|---|---|
| مالك المورد | هدف إطار العمل الخاص بك | يحتوي على الكتالوج |
| ملف الكتالوج | Panel.xcstrings |
يخزّن النص المصدر للجدول وترجماته |
| وسيطة الجدول | Panel |
تحدد ذلك الكتالوج من دون امتداده |
| المفتاح | PANEL_OPEN_ACTION |
يحدد الرسالة |
| القيمة المصدرية بالإنجليزية | Open panel |
توفر نصاً مقروءاً للواجهة |
| التعليق | Label for the action that opens the panel. |
يشرح استخدام الرسالة |
يؤدي تمرير table: "Panel" إلى تحديد الجدول المُمثّل بالملف Panel.xcstrings. أما ترك الجدول من دون تعيين فيحدد Localizable. وبالمثل، فإن ترك الحزمة من دون تعيين يجعل مُهيّئ السلاسل يبحث في الحزمة الرئيسية للتطبيق. لذلك يحتاج المفتاح المطابق في كتالوج إطار عمل إلى حزمة إطار العمل والجدول الصحيح معاً. معاملات السلاسل المترجمة في Swift.
يوفر ذلك ترتيباً مفيداً للتشخيص: تحقّق من المالك أولاً، ثم الجدول، ثم المُدخل. لن يفيد البحث عن تهجئات بديلة للمفتاح إذا كانت عملية البحث موجّهة إلى موارد التطبيق بينما الرسالة تخص إطار عمل.
أضف كتالوج السلاسل النصية إلى هدف إطار العمل
في Xcode، اختر File > New > File from Template، وحدد المنصة، واكتب string في مرشح البحث، ثم اختر String Catalog. سمّ الملف Panel. تأكد من أن الكتالوج تابع لهدف إطار العمل، إلى جانب مصدر إطار العمل الذي سيشير إليه. يتيح سير عمل الكتالوجات لدى Apple استخدام أسماء مخصصة، كما ينشئ عرضها التوضيحي لإطار العمل الكتالوج داخل هدف إطار العمل. ترجمة النصوص وتغييرها باستخدام كتالوج السلاسل النصية، عرض Apple التوضيحي لترجمة إطار العمل.
يستخدم المثال مفتاحاً دلالياً بدلاً من جعل النص المعروض هو المفتاح. باستخدام PANEL_OPEN_ACTION كمعرّف وOpen panel كقيمة افتراضية، تصرّح الشيفرة بكلا الجزأين بوضوح. تدعم Apple هذا الترتيب عبر المُهيّئ الذي يقبل مفتاحاً ثابتاً وقيمة ترجمة افتراضية منفصلة. مُهيّئ المفتاح الثابت في Swift.
بعد إضافة المصدر أدناه، ابنِ هدف إطار العمل. يكتشف Xcode استدعاءات واجهات البرمجة القابلة للترجمة أثناء عمليات البناء ويحدّث الكتالوجات ذات الصلة. افتح Panel.xcstrings وتحقق من احتوائه على PANEL_OPEN_ACTION، والقيمة المصدرية الإنجليزية Open panel، والتعليق التوضيحي. إذا كان المُدخل مفقوداً، فتحقق من عضوية المصدر في الهدف ومن بناء الهدف الذي يحتوي عليه. توفر Apple أيضاً Editor > Assistant لفحص الشيفرة المرتبطة بمُدخل في الكتالوج. ملء كتالوج السلاسل النصية وفحصه.
حل الرسالة داخل إطار العمل
ضع ملف المصدر الكامل هذا في هدف إطار العمل. فهو يعرّف السلسلة المترجمة وتسمية SwiftUI صغيرة يمكن لتطبيق Mac الحاوي عرضها. كما يتضمن طريقة تشخيصية مستخدمة في القسم التالي. تمت مراجعة الشيفرة وفق التواقيع الموثقة من Apple؛ ولم تُنفّذ هنا لعدم توفر مترجم Swift.
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)
}
}
يُقيَّم التعبير #bundle في الموضع الذي تكتبه فيه. داخل مصدر إطار العمل هذا، يوفّر الحزمة المرتبطة بهدف إطار العمل. إذا نقلت التعبير نفسه إلى مصدر هدف التطبيق، فسيقدّم حزمة التطبيق بدلاً من ذلك. وبالنسبة إلى هدف حزمة Swift، توثّق Apple أن الماكرو يوفّر حزمة موارد الهدف. أبقِ عملية البحث بجوار الموارد التي يملكها ذلك الهدف. ماكرو الحزمة في Foundation.
يُرجع التصريح قيمة String عادية تم حل ترجمتها بالفعل. يستخدم العرض Text(verbatim:) لعرض تلك النتيجة صراحةً. العرض العام مجرد تسمية؛ أضفه إلى عرض تطبيق موجود حيث يلزم ظهور النص.
استخدم صنفاً من إطار العمل عندما لا يتوفر ماكرو الحزمة
تدعم Apple أيضاً تحديد حزمة إطار العمل عبر صنف معرّف فيه. بالنسبة إلى إطار عمل تقليدي يحتوي على موارده الخاصة، فإن مزوّد الرسائل التالي بديل كامل. استخدمه بدلاً من تصريح PanelMessages السابق، واحتفظ بمتطلبات الكتالوج والنشر الموضحة أعلاه.
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."
)
}
}
يجب تجميع الصنف المرساة ضمن إطار العمل الذي تريد استخدام موارده. توثّق Apple أن Bundle(for:) يعيد الحزمة المرتبطة بالصنف المُمرّر، بما في ذلك حزمة إطار العمل عند الاقتضاء. أما الصنف المرساة الذي يُجمّع ضمن التطبيق فسيحدد التطبيق. بالنسبة إلى موارد الحزم أو الموارد الموضوعة في حزمة منفصلة، اختر حزمة مواردها الفعلية؛ فموقع الصنف وحده لا يحدد ملكية تلك الموارد. المُهيّئ المعتمد على صنف الحزمة، تحديد حزمة الموارد باستخدام الماكرو.
أثبت أن النص المقروء جاء من عملية بحث ناجحة
إن رؤية Open panel على الشاشة لا تكفي لإثبات نجاح البحث في الكتالوج. يعيد المُهيّئ defaultValue عند فشل البحث، لذا قد يمثّل النص الظاهر نفسه عملية بحث ناجحة أو قيمة احتياطية. هذا السلوك مفيد لنصوص الواجهة المقروءة، لكنه قد يخفي حزمة أو جدولاً غير صحيحين أثناء التطوير. سلوك القيمة الافتراضية في Swift.
تعالج طريقة lookupReport() في ملف المصدر الأول هذا الالتباس. فهي تجري بحثاً باستخدام علامة احتياطية مميزة يجب ألا تُستخدم كقيمة حقيقية في الكتالوج. افحص القيمة التي تعيدها من التطبيق قيد التشغيل أو من سياق تصحيح أخطاء موجود. إذا أفادت بعدم وجود مُدخل محلول، فتحقق من الموارد المحددة قبل تعديل الترجمات.
ينبثق هذا التشخيص مباشرةً من السلوك الموثق لـ Bundle.localizedString(forKey:value:table:): عند غياب مفتاح وكون القيمة الاحتياطية المقدمة غير فارغة، تعيد الطريقة تلك القيمة. أما عند غياب المفتاح وكانت القيمة الاحتياطية فارغة أو معدومة، فتعيد المفتاح نفسه. تجعل العلامة التمييز بين الإخفاق والنص المصدر المشروع أسهل. القيم التي تعيدها السلاسل المترجمة في Bundle).
| الملاحظة | الفحص التالي |
|---|---|
| يعيد التشخيص رسالة المُدخل المفقود | تأكد من بناء الكتالوج ضمن الحزمة المحددة، ثم تحقق من Panel وPANEL_OPEN_ACTION |
| يحل التشخيص قيمة غير متوقعة | افحص ذلك المُدخل بعينه في الجدول المحدد واللغة المستخدمة في التشغيل الحالي |
| يحل التشخيص القيمة على نحو صحيح لكن الواجهة تعرض قيمة مختلفة | تتبّع القيمة التي تعرضها الواجهة فعلياً |
| تظهر القيمة المصدرية الإنجليزية أثناء تشغيل مترجم | افحص ترجمة المُدخل وإعداد التشغيل؛ فنجاح البحث وحده لا يثبت وجود ترجمة مكتملة باللغة المطلوبة |
الجدول تسلسل لاستكشاف الأخطاء مشتق من عقد البحث. يثبت اختبار العلامة بنجاح أن البحث أعاد مُدخلاً، لكنه لا يثبت اكتمال الترجمة لكل لغة مدعومة. أبقِ حل الموارد واكتمال الترجمة فحصين منفصلين.
اختبر التسمية باللغة المحددة لتطبيق Mac
إذا كان التطبيق يدعم لغات إضافية، فحدد اللغة المطلوبة في الشريط الجانبي للكتالوج وأدخل الترجمة في حقل النص الخاص بذلك المُدخل. ثم اختبر عبر تطبيق Mac الحاوي. توثّق Apple إمكانية إدخال الترجمات مباشرةً في محرر الكتالوج، كما تُحدّث حالة الترجمة لكل مُدخل أثناء العمل. إضافة ترجمات إلى كتالوج السلاسل النصية.
للتحكم في تشغيل التصحيح، اختر Product > Scheme > Edit Scheme، وحدد Run، ثم افتح Options. عيّن App Language إلى لغة يدعمها المشروع، وأغلق المحرر، ثم شغّل تطبيق Mac مجدداً. اختر System Language عندما تريد أن يتبع التشغيل إعداد لغة النظام. اختبار الترجمات عند تشغيل تطبيقك.
لا تستخدم وسيطة locale: في مُهيّئ السلاسل بديلاً عن اختبار اللغة هذا. توثّق Apple أن هذه الوسيطة تتحكم في ترجمة القيم المُدرجة، مثل الأرقام، ولا تغيّر اللغة المستخدمة للبحث عن السلسلة المترجمة. حذفها من المثال مناسب لعدم احتواء التسمية على قيم مُدرجة. وسيطة اللغة المحلية في السلاسل المترجمة في Swift.
أبقِ العقد النهائي صغيراً وواضحاً: يملك إطار العمل Panel.xcstrings، ويحدد البحث Panel، ويحدد PANEL_OPEN_ACTION التسمية. تحقّق من المُدخل باستخدام التشخيص، ثم تحقق من الترجمة المعروضة بلغة التشغيل المختارة للتطبيق. يتيح لك هذا التسلسل تصحيح بحث الموارد قبل قضاء الوقت في صياغة نص قد لا يقرأه التطبيق أصلاً.
المصادر
- إعداد نص تطبيقك للترجمة — Apple
- ترجمة النصوص وتغييرها باستخدام كتالوج السلاسل النصية — Apple
- تطبيق عملي: استكشاف الترجمة باستخدام Xcode — Apple
init(localized:defaultValue:table:bundle:locale:comment:)— Appleinit(localized:table:bundle:locale:comment:)— Applebundle()— Appleinit(for:)— ApplelocalizedString(forKey:value:table:)— Apple- اختبار الترجمات عند تشغيل تطبيقك — Apple