تخطي إلى المحتوى الرئيسي
جميع الأدلة
دليل

تحديث الترجمات عبر الهواء في Flutter

تُدمج أداة التوطين المضمّنة في Flutter النصوص داخل التطبيق، لذا يحتاج كل تغيير إلى إصدار جديد. يحمّل هذا الدليل ترجمات litei18n عند تشغيل التطبيق بدلًا من ذلك، مع النسخة المضمّنة كبديل احتياطي.

خطوات الإعداد

  1. أنشئ إصدارًا

    في litei18n، اعتمد ترجماتك وأنشئ إصدارًا من صفحة Releases (خطة Starter وما فوقها). انسخ معرّف مشروعك من رابط الإصدار الظاهر هناك. وصدّر ترجماتك أيضًا بصيغة JSON وأضفها إلى تطبيقك كنسخة مضمّنة.

  2. حمّل الإصدار عند تشغيل التطبيق

    أضف حزمة http إلى pubspec.yaml، وضع ملفات JSON المصدَّرة في assets/i18n/، وأدرج هذا المجلد تحت flutter: assets: في pubspec.yaml، وإلا فلن يتمكن التطبيق من قراءتها. تقرأ هذه الفئة الملف المضمّن أولًا، ثم تستبدل قيمه بقيم أحدث إصدار عند توفر الاتصال.

    lib/translations.dart
    import 'dart:convert';
    
    import 'package:flutter/services.dart' show rootBundle;
    import 'package:http/http.dart' as http;
    
    const projectId = 'YOUR_PROJECT_ID';
    const releases =
        'https://ttksowxkfdohtprtfarf.supabase.co/storage/v1/object/public/releases/locales';
    
    class Translations {
      Translations(this._values);
    
      final Map<String, String> _values;
    
      String t(String key) => _values[key] ?? key;
    
      static Future<Translations> load(String locale) async {
        // The copy bundled with the app: works offline and on first launch.
        final values = Map<String, String>.from(
          jsonDecode(await rootBundle.loadString('assets/i18n/$locale.json')),
        );
        try {
          final res = await http
              .get(Uri.parse('$releases/$projectId/latest/$locale.json'))
              .timeout(const Duration(seconds: 5));
          if (res.statusCode == 200) {
            values.addAll(Map<String, String>.from(jsonDecode(utf8.decode(res.bodyBytes))));
          }
        } catch (_) {
          // Offline or slow: keep the bundled copy.
        }
        return Translations(values);
      }
    }
  3. استخدم النصوص

    حمّل الترجمات قبل runApp ومرّرها إلى الواجهات، أو احفظها في أداة إدارة الحالة التي تستخدمها. يظهر المفتاح المفقود باسمه، فيسهل اكتشافه.

    lib/main.dart
    import 'package:flutter/material.dart';
    
    import 'translations.dart';
    
    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
      final tr = await Translations.load('es');
      runApp(MyApp(tr: tr));
    }
    
    // In a widget:
    Text(tr.t('home.title'))
  4. غيّر النصوص دون إصدار جديد

    عدّل ترجمة واعتمدها وأنشئ إصدارًا جديدًا. سيقدّم رابط latest النص الجديد، ويحصل عليه تطبيقك في المرة التالية التي يحمّل فيها الترجمات. لا حاجة إلى إصدار جديد ولا إلى مراجعة من متجر التطبيقات.

من المفيد معرفته

  • تُخزَّن ملفات الإصدارات مؤقتًا على شبكة CDN، لذا قد يستغرق ظهور الإصدار الجديد في كل مكان بضع دقائق.
  • لتثبيت إصدار من التطبيق على إصدار ترجمات محدد، استخدم الرابط ذا الرقم (…/v3/es.json) بدلًا من …/latest/es.json.
  • للاحتفاظ بالنص المحمَّل دون اتصال، احفظ الاستجابة باستخدام shared_preferences أو path_provider واقرأها قبل الملف المضمّن في المرة التالية.

ابدأ الإطلاق عالمياً في 5 دقائق

انضم إلى المطورين الذين يطلقون تطبيقاتهم بكل لغة مع litei18n.

خطة مجانية متاحة · لا حاجة لبطاقة ائتمان · إعداد في أقل من 5 دقائق