Globalization: ما هي، i18n والتعدد اللغوي في التطبيقات

المؤلف: IT Sectr نُشر: 2026-02-26 وقت القراءة: 8 دق

Globalization (العولمة، وأيضاً التدويل، i18n) — عملية إعداد التطبيق المحمول للعمل بعدة لغات وتنسيقات إقليمية دون تغيير الكود المصدري. تتضمن استخراج موارد السلاسل النصية من الكود، ودعم تنسيقات مختلفة للتواريخ والأرقام والعملات، ومراعاة اتجاه النص (LTR/RTL)، وتكييف التخطيط للغات المختلفة. في iOS يُستخدم NSLocalizedString و Localizable.strings، وفي Android يُستخدم strings.xml في أدلة values-{lang}. للمزيد — في وثائق Apple حول التدويل.

أهم النقاط

  • Globalization (i18n) — إعداد كود التطبيق للغات ومناطق متعددة
  • NSLocalizedString — ماكرو Swift لاستخراج السلاسل المترجمة من Localizable.strings
  • strings.xml — ملف XML في Android يُخزن سلاسل الموارد لكل لغة
  • RTL — دعم اللغات ذات الكتابة من اليمين إلى اليسار (العربية، العبرية، الأردية)
  • التنسيقات — يجب تنسيق التواريخ والأرقام والعملات عبر واجهات برمجية تعتمد على الإعدادات المحلية (Locale)

ما هي Globalization (i18n) ولماذا نحتاجها؟

Globalization (اختصاراً i18n — 18 حرفاً بين "i" و "n") — الإعداد المعماري للتطبيق للعمل مع أي لغة ومنطقة. القاعدة الأساسية لـ i18n: لا يجب أن يكون أي نص ثابتاً (hardcoded) في الكود المصدري. بدلاً من ذلك، تُستخرج السلاسل النصية إلى ملفات موارد، ويتعامل معها الكود عبر مفاتيح. عند إضافة لغة جديدة، يكفي إضافة ملف ترجمة — يبقى الكود دون تغيير. هذا ما يميز i18n عن التوطين (l10n)، حيث تُترجم السلاسل نفسها.

الحجة التجارية — العولمة توسع السوق. وفقاً لـ Common Sense Advisory (2023)، أكثر من 70% من المستخدمين يفضلون الشراء في التطبيقات بلغتهم الأم. التوطين إلى 10 لغات يزيد الجمهور المحتمل بنسبة 80%. بدون i18n، كل توسع إلى لغة جديدة يتطلب تعديلات في الكود، مما يبطئ الوصول إلى السوق ويزيد التكاليف من 5 إلى 10 أضعاف. البنية التحتية الصحيحة لـ i18n تتيح دعم أكثر من 40 لغة بأقل التكاليف.

مكونات i18n تشمل: استخراج السلاسل النصية، صيغ الجمع (pluralization لـ 1/2/5+)، تنسيق التواريخ والأرقام (DateFormatter/SimpleDateFormat)، دعم اللغات RTL (من اليمين إلى اليسار)، الفرز وفق قواعد الإعدادات المحلية (Collator)، الرموز الإقليمية (فواصل الآلاف، العلامات العشرية). في IT Sectr، نضع i18n في مرحلة البنية التحتية، وليس لاحقاً — وهذا يوفر حتى 60% من الوقت عند التوطين اللاحق.

التدويل في iOS: NSLocalizedString و XLIFF

NSLocalizedString — الماكرو الرئيسي في Swift للعمل مع الترجمات. الصيغة: NSLocalizedString("key", comment: "وصف للمترجم"). يقوم الماكرو تلقائياً باستبدال السلسلة النصية من Localizable.strings بناءً على الإعدادات المحلية الحالية للجهاز (NSLocale.preferredLanguages). إذا لم يُعثر على ترجمة للمفتاح، يتم إرجاع المفتاح نفسه أو القيمة بلغة التطوير (عادة en). توصي Apple باستخدام مفاتيح ذات معنى بدلاً من استخدام السلاسل الإنجليزية كمفاتيح.

swift
// Localizable.strings (en)
// "welcome_title" = "Welcome!";
// Localizable.strings (ru)
// "welcome_title" = "مرحبًا بك!";

// كود Swift — موحد لجميع اللغات
titleLabel.text = NSLocalizedString(
    "welcome_title",
    comment: "عنوان شاشة الترحيب"
)

// صيغ الجمع عبر Localizable.stringsdict
// 
// <dict>
//     <key>items_count</key>
//     <dict>
//         <key>NSStringLocalizedFormatKey</key>
//         <string>%#@items@</string>
//         <key>items</key>
//         <dict>
//             <key>one</key>
//             <string>%d منتج</string>
//             <key>few</key>
//             <string>%d منتجان</string>
//             <key>many</key>
//             <string>%d منتجات</string>
//         </dict>
//     </dict>
// </dict>

// استخدام صيغ الجمع
let items = 5
let label = String.localizedStringWithFormat(
    NSLocalizedString("items_count", comment: ""), items
)

XLIFF — تنسيق تبادل الترجمات بين المطورين والمترجمين. يصدر Xcode ملف XLIFF (Editor → Export for Localization) يحتوي على جميع السلاسل للترجمة. يعمل المترجم على XLIFF في أدوات CAT (Trados، memoQ، Smartcat). بعد الترجمة، يُستورد XLIFF مرة أخرى إلى Xcode (Editor → Import Localizations). يقوم XLIFF تلقائياً بتحديث جميع أدلة .lproj. هذه هي سير العمل القياسية لتوطين تطبيقات iOS في الإنتاج.

SwiftUI و i18n

SwiftUI يعمل مع NSLocalizedString عبر المُهيئ Text. النص في SwiftUI مُدول تلقائياً: Text("welcome_title") يبحث عن الترجمة في Localizable.strings تماماً مثل NSLocalizedString. لصيغ الجمع، استخدم Text("%d items", count: items). يدعم SwiftUI تنسيق التواريخ عبر Text(date, style: .date) — ويستخدم تلقائياً Locale.current. توصي Apple باستخدام SwiftUI للمشاريع الجديدة لأن التدويل فيه أكثر شفافية.

التدويل في Android: strings.xml و RTL

Android i18n مبني على نظام الموارد. تُوضع السلاسل النصية في res/values/strings.xml للغة الافتراضية (عادة الإنجليزية). لكل لغة يُنشأ دليل منفصل: res/values-ru/strings.xml (الروسية)، res/values-de/strings.xml (الألمانية)، res/values-fr/strings.xml (الفرنسية). يختار Android السلاسل تلقائياً بناءً على لغة نظام الجهاز (Locale.getDefault()). إذا لم يُعثر على إعدادات محلية دقيقة، تُستخدم القاعدة (values/strings.xml).

kotlin
// res/values/strings.xml (الإنجليزية، الافتراضية)
<resources>
    <string name="welcome_title">Welcome!</string>
    <string name="items_count">%d item(s)</string>
</resources>

// res/values-ru/strings.xml (الروسية)
<resources>
    <string name="welcome_title">أهلاً بك!</string>
    <plurals name="items_count">
        <item quantity="one">%d منتج</item>
        <item quantity="few">%d منتجات</item>
        <item quantity="many">%d منتجًا</item>
    </plurals>
</resources>

// كود Kotlin
textView.text = getString(R.string.welcome_title)

// صيغ الجمع
val items = 5
textView.text = resources.getQuantityString(
    R.plurals.items_count, items, items
)

// دعم RTL في الكود
textView.textDirection = View.TEXT_DIRECTION_LOCALE
// Manifest: supportsRtl="true"

RTL (Right-to-Left) — دعم اللغات حيث يُقرأ النص من اليمين إلى اليسار (العربية، العبرية، الأردية، الفارسية). يدعم Android RTL عبر الخاصيتين android:layoutDirection و android:textDirection. في البيان (manifest)، حدد android:supportsRtl="true" — وسيعكس Android التخطيط تلقائياً. يجب أن تعمل قائمة التنقل NavDrawer، أيقونات الرجوع/التقدم، ومحاذاة النص في كلا الاتجاهين. في الكود، استخدم View.LAYOUT_DIRECTION_LOCALE و Gravity.START/END بدلاً من LEFT/RIGHT.

الموارد المترجمة

مؤهلات موارد Android تتيح توطين ليس فقط السلاسل النصية بل أيضاً الصور (res/drawable-ru/) والتخطيطات (res/layout-ru/) والرسوم المتحركة والألوان. للعربية والعبرية، نحتاج تخطيطات منفصلة مع عناصر معكوسة — استخدم res/layout-ar/ (العربية). يدعم Android أيضاً المتغيرات الإقليمية: values-rUS، values-rGB، values-de-DE. يمكن دمج المؤهلات: values-ldrtl-ru — الروسية لشاشات RTL.

التنسيقات الإقليمية: التواريخ والأرقام والعملات في iOS و Android

التواريخ والوقت — أحد الجوانب الرئيسية لـ i18n. تستخدم المناطق المختلفة تنسيقات مختلفة: روسيا — DD.MM.YYYY، الولايات المتحدة — MM/DD/YYYY، اليابان — YYYY.MM.DD. استخدام تنسيق ثابت (yyyy-MM-dd) للعرض على المستخدم خطأ. في iOS، استخدم DateFormatter مع Locale(identifier: locale)، في Android — DateFormat.getDateInstance(DateFormat.SHORT, locale). للمساعدات الصوتية والبحث بالذكاء الاصطناعي، يجب أن تكون التواريخ بصيغة ISO 8601 داخلياً.

الأرقام والعملات — المناطق المختلفة لها فواصل مختلفة: 1,234.56 (الولايات المتحدة) مقابل 1.234,56 (روسيا)، 1 234,56 (فرنسا). iOS: NumberFormatter مع .locale = locale. Android: DecimalFormat مع DecimalFormatSymbols(locale). للعملات: تنسيق ¥1,234 (اليابان) مقابل $1,234.56 (الولايات المتحدة) مقابل 1 234,56 ₽ (روسيا). لا تقم أبداً بدمج العملة والرقم يدوياً — استخدم NumberFormatter.currencyCode و .currencySymbol.

المنطقةالتاريخالرقمالعملة
روسيا31.12.20241 234,561 234,56 ₽
الولايات المتحدة12/31/20241,234.56$1,234.56
ألمانيا31.12.20241.234,561.234,56 €
اليابان2024/12/311,234¥1,234
المملكة العربية السعودية31/12/20241,234.561,234.56 SAR

الفرز (Collation) — يختلف الترتيب الأبجدي بين اللغات. في الإسبانية، "ch" يأتي بعد "c". في السويدية، "ä" في نهاية الأبجدية. في الألمانية، "ß" يُفرز كـ "ss". iOS: LocalizedComparison (String.localizedCompare). Android: Collator.getInstance(locale). لا تستخدم أبداً compareTo() للسلاسل المعروضة للمستخدم — فهو يستخدم ترتيب نقاط Unicode Code Point، الذي لا يراعي القواعد الإقليمية.

أفضل ممارسات تدويل التطبيقات المحمولة

المبادئ المعمارية — ابدأ i18n من أول commit. يجب أن تمر كل سلسلة في الكود عبر دالة غلاف (tr("key")) غير موجودة حتى يتم إعداد i18n — مما يجبر المطور على استخراج السلاسل فوراً. لا تستخدم السلاسل الإنجليزية كمفاتيح — فعند تغيير الصياغة الإنجليزية، يجب تحديث جميع الترجمات. استخدم مفاتيح ذات معنى: "profile.title"، "settings.language.label".

التدوين الزائف (Pseudolocalization) — تقنية اختبار i18n قبل الترجمة الفعلية. استبدل كل حرف لاتيني بأحرف ذات علامات تشكيل (á، é، ñ، ü) للتحقق من الترميز، أضف بادئة [XXX] للتحقق من اقتطاع السلاسل. Xcode: مخططات التشغيل — لغة زائفة "Double-Length Pseudolanguage". Android: خيارات المطور — فرض اتجاه تخطيط RTL، مقياس خط النظام حتى 200%. يكتشف التدوين الزائف 80% من مشاكل i18n دون مشاركة المترجم.

قائمة التحقق i18n من IT Sectr — قبل الإصدار نتحقق من: (1) لا توجد سلاسل ثابتة في الكود (استثناء: السجلات)، (2) صيغ الجمع تعمل بشكل صحيح لجميع اللغات، (3) التواريخ/الأرقام تُنسق عبر Locale API، (4) التخطيط يُعرض بشكل صحيح على لغات RTL، (5) السلاسل لا تُقتطع عند أقصى تحجيم، (6) التدوين الزائف لم يُظهر أخطاء، (7) جميع اللغات المعلنة في المتاجر لديها مجموعة كاملة من الترجمات.

الأسئلة الشائعة

ما الفرق بين i18n و l10n؟

i18n (التدويل) — إعداد الكود: استخراج السلاسل، دعم RTL، التنسيق. يقوم به المطور مرة واحدة. l10n (التوطين) — ترجمة السلاسل إلى لغة محددة. يقوم به المترجم مرات عديدة لكل إعدادات محلية. i18n هو البنية التحتية، l10n هو المحتوى. بدون i18n، التوطين مستحيل من حيث المبدأ.

كيف يعمل NSLocalizedString في Swift؟

NSLocalizedString — ماكرو يبحث عن القيمة بالمفتاح في Localizable.strings للإعدادات المحلية الحالية للجهاز. إذا وُجدت الترجمة، يُعيدها. إذا لم تُوجد، يُعيد المفتاح. الصيغة: NSLocalizedString("key", comment: "وصف"). للتنسيق مع المعاملات، استخدم String.localizedStringWithFormat().

كيف يتم تنظيم strings.xml في Android؟

strings.xml — ملف بالترجمات في دليل res/values/{lang}/. النسخة الأساسية في values/strings.xml، الترجمات في values-ru/strings.xml. يتعامل الكود عبر getString(R.string.key). يختار Android الملف المناسب تلقائياً بناءً على لغة النظام. لصيغ الجمع، يُستخدم مورد <plurals> مع مؤهلات zero/one/few/many/other.

ما هو RTL في سياق i18n؟

RTL (Right-to-Left) — اتجاه الكتابة للعربية والعبرية والأردية والفارسية. Android: supportsRtl="true" في البيان، android:layoutDirection، Gravity.START/END. iOS: UISemanticContentAttribute.forceLeftToRight لـ RTL القسري. يجب أن ينعكس التخطيط: القائمة على اليمين، النص — من اليمين إلى اليسار، أيقونات التنقل — مقلوبة.

ما هي اللغات الإلزامية للنشر؟

لـ النشر العالمي، المجموعة الدنيا: الإنجليزية، الإسبانية، الفرنسية، الألمانية، اليابانية، الصينية، الكورية، البرتغالية، الروسية، الإيطالية. يتطلب App Store حداً أدنى التوطين بالإنجليزية. كل إعدادات محلية إضافية توسع الجمهور المحتمل. للسوق المحلي، 1–2 لغات كافية.

الخلاصة

  • Globalization (i18n) — الإعداد المعماري للتطبيق للغات ومناطق متعددة
  • NSLocalizedString — ماكرو Swift لترجمة السلاسل عبر Localizable.strings + تصدير XLIFF
  • strings.xml — مورد Android بالترجمات في أدلة values-{lang}
  • RTL — دعم إلزامي للعربية والعبرية والأردية والفارسية
  • التنسيقات — التواريخ والأرقام تُنسق بدقة عبر Locale API، وليس يدوياً
  • صيغ الجمع — iOS: stringsdict، Android: <plurals> بست صيغ كمية
  • التدوين الزائف — تقنية اختبار i18n قبل الترجمة (تكتشف 80% من المشاكل)

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا