التدويل (i18n) في Swift: دليل شامل لنظامي iOS و macOS
\n\nالتدويل (i18n) هو عملية تصميم التطبيق بحيث يمكن تكييفه مع لغات ومناطق مختلفة دون إجراء تغييرات هندسية. في نظام Apple البيئي (iOS، macOS، watchOS، tvOS)، تكون أدوات الترجمة مدمجة مباشرة في Swift و Xcode. في هذه المقالة، سنشرح بالتفصيل كيفية استخدام NSLocalizedString و String Catalog الحديث لإنشاء تطبيقات متعددة اللغات.
\n\nالأساسيات: NSLocalizedString
\n\nالآلية الأساسية للتدويل في Swift هي الدالة NSLocalizedString. وهي تبحث عن ترجمة النص في ملفات .strings أو .xcstrings (String Catalog).
let greeting = NSLocalizedString("hello_world", comment: "تحية على الشاشة الرئيسية")\nprint(greeting) // سيعرض الترجمة حسب لغة الجهاز\n\nالمعامل comment يعمل كتلميح للمترجم. يجب أن يكون المفتاح "hello_world" فريدًا ضمن المشروع بأكمله.
إنشاء ملفات الترجمة
\n\nفي Xcode، يمكنك إضافة اللغات المدعومة عبر Project Info > Localizations. بعد ذلك، سيتم إنشاء ملفات فرعية للترجمة لكل ملف .strings أو Storyboard.
مثال على محتوى Localizable.strings (الإنجليزية):
"hello_world" = "Hello, World!";\n"welcome_message" = "Welcome to our app %@";\n\nالنسخة العربية (Localizable.strings (Arabic)):
"hello_world" = "مرحبًا بالعالم!";\n"welcome_message" = "مرحبًا بك في تطبيقنا %@";\n\nتنسيق النصوص مع المعاملات
\n\nبالنسبة للنصوص التي تحتوي على بيانات ديناميكية، استخدم محددات التنسيق. في Swift، يمكن القيام بذلك بطريقتين:
\n\nالطريقة 1: String(format:)
\nlet userName = "إيفان"\nlet points = 150\nlet message = String(format: NSLocalizedString("user_score", comment: "نقاط المستخدم"), userName, points)\nprint(message) // "إيفان حصل على 150 نقطة"\n\nفي ملف الترجمة:
\n"user_score" = "%@ حصل على %d نقطة";\n\nالطريقة 2: تداخل النصوص في Swift (iOS 15+)
\nlet message = "\\(userName) حصل على \\(points) نقطة"\nلكن هذه الطريقة غير مناسبة للترجمة، لأن ترتيب الكلمات قد يختلف بين اللغات. استخدم فقط String(format:) أو AttributedString مع التصريف.
صيغ الجمع (الأشكال المتعددة)
\n\nفي اللغة العربية، هناك قواعد معقدة للجمع: "ملف واحد"، "ملفان"، "5 ملفات". لهذا، توفر Apple stringsdict (XML) أو String Catalog مع قواعد الجمع.
\n\nمثال stringsdict
\n<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"\n "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0">\n<dict>\n <key>files_count</key>\n <dict>\n <key>NSStringLocalizedFormatKey</key>\n <string>%#@files@</string>\n <key>files</key>\n <dict>\n <key>NSStringFormatSpecTypeKey</key>\n <string>NSStringPluralRuleType</string>\n <key>NSStringFormatValueTypeKey</key>\n <string>d</string>\n <key>one</key>\n <string>%d ملف</string>\n <key>two</key>\n <string>%d ملفان</string>\n <key>few</key>\n <string>%d ملفات</string>\n <key>many</key>\n <string>%d ملفًا</string>\n <key>other</key>\n <string>%d ملف</string>\n </dict>