بدء استخدام ميزة "الإعداد عن بُعد في Firebase"


يمكنك استخدام Firebase Remote Config لتحديد المَعلمات في تطبيقك وتعديل قيمها على السحابة الإلكترونية، ما يتيح لك تغيير مظهر تطبيقك وطريقة عمله بدون توزيع تحديث للتطبيق. يرشدك هذا الدليل إلى الخطوات اللازمة للبدء، كما يقدّم بعض نماذج الرموز البرمجية التي يمكنك استنساخها أو تنزيلها من مستودع firebase/quickstart-ios على GitHub.

الخطوة 1: إضافة Remote Config إلى تطبيقك

  1. أضِف Firebase إلى مشروع Apple إذا لم يسبق لك إجراء ذلك.

  2. بالنسبة إلى Remote Config، يجب استخدام Google Analytics من أجل استهداف نسخ التطبيق الافتراضية وفقًا للشروط لخصائص المستخدمين وشرائح الجمهور. تأكَّد من تفعيل Google Analytics في مشروعك.

  3. أنشئ عنصر Remote Config الفردي، كما هو موضّح في المثال التالي:

    SwiftObjective-C
    remoteConfig = RemoteConfig.remoteConfig()
    let settings = RemoteConfigSettings()
    settings.minimumFetchInterval = 0
    remoteConfig.configSettings = settings
    self.remoteConfig = [FIRRemoteConfig remoteConfig];
    FIRRemoteConfigSettings *remoteConfigSettings = [[FIRRemoteConfigSettings alloc] init];
    remoteConfigSettings.minimumFetchInterval = 0;
    self.remoteConfig.configSettings = remoteConfigSettings;

يُستخدَم هذا العنصر لتخزين قيم المَعلمات التلقائية داخل التطبيق، واسترداد قيم المَعلمات المعدَّلة من الخلفية Remote Config، والتحكّم في وقت إتاحة القيم المستردّة لتطبيقك.

أثناء التطوير، يُنصح بتحديد حدّ أدنى منخفض نسبيًا لفاصل الجلب. يمكنك الاطّلاع على التقييد للحصول على مزيد من المعلومات.

الخطوة 2: ضبط القيم التلقائية للمعلمات داخل التطبيق

يمكنك ضبط قيم المَعلمات التلقائية داخل التطبيق في العنصر Remote Config، حتى يتصرف تطبيقك على النحو المطلوب قبل الاتصال بخادم Remote Config الخلفي، وحتى تتوفّر القيم التلقائية في حال عدم ضبط أي قيم في الخادم الخلفي.

  1. حدِّد مجموعة من أسماء المَعلمات وقيم المَعلمات التلقائية باستخدام كائن NSDictionary أو ملف plist.

    إذا سبق لك ضبط قيم مَعلمات Remote Config في الخلفية، يمكنك تنزيل ملف plist تم إنشاؤه يتضمّن جميع القيم التلقائية وحفظه في مشروع Xcode.

    curl --compressed -D headers -H "Authorization: Bearer token -X GET https://firebaseremoteconfig.googleapis.com/v1/projects/my-project-id/remoteConfig:downloadDefaults?format=PLIST -o RemoteConfigDefaults.plist
    
    1. في علامة التبويب المَعلمات، افتح القائمة، ثم انقر على تنزيل القيم التلقائية.

    2. عندما يُطلب منك ذلك، فعِّل plist لنظام التشغيل iOS، ثم انقر على تنزيل الملف.

  2. أضِف هذه القيم إلى العنصر Remote Config باستخدام setDefaults:. يضبط المثال التالي القيم التلقائية داخل التطبيق من ملف plist:

    SwiftObjective-C
    remoteConfig.setDefaults(fromPlist: "RemoteConfigDefaults")
    [self.remoteConfig setDefaultsFromPlistFileName:@"RemoteConfigDefaults"];

الخطوة 3: الحصول على قيم المَعلمات لاستخدامها في تطبيقك

يمكنك الآن الحصول على قيم المَعلمات من العنصر Remote Config. إذا حدّدت قيمًا لاحقًا في الخلفية Remote Config، واسترجعتها، ثم فعّلتها، ستتوفّر هذه القيم لتطبيقك. وإلا، ستحصل على قيم المَعلمات داخل التطبيق التي تم ضبطها باستخدام setDefaults:. للحصول على هذه القيم، استدعِ طريقة configValueForKey: ، وقدِّم مفتاح المَعلمة كمعلَمة.

let remoteConfig = RemoteConfig.remoteConfig()

// Retrieve a parameter value using configValueForKey
let welcomeMessageValue = remoteConfig.configValue(forKey: "welcome_message")
let welcomeMessage = welcomeMessageValue.stringValue

let featureFlagValue = remoteConfig.configValue(forKey: "new_feature_flag")
let isFeatureEnabled = featureFlagValue.boolValue

تتوفّر طريقة أسهل وأكثر ملاءمة للوصول إلى هذه القيم في Swift من خلال ترميز الاشتراك في Swift:

let remoteConfig = RemoteConfig.remoteConfig()

// Retrieve a string parameter value
let welcomeMessage = remoteConfig["welcome_message"].stringValue

// Retrieve a boolean parameter value
let isFeatureEnabled = remoteConfig["new_feature_flag"].boolValue

// Retrieve a number parameter value
let maxItemCount = remoteConfig["max_items"].numberValue.intValue

استخدام Codable لإعدادات آمنة الأنواع

بالنسبة إلى الإعدادات الأكثر تعقيدًا، يمكنك استخدام بروتوكول Codable في Swift لفك ترميز البيانات المنظَّمة من Remote Config. يوفّر ذلك إدارة إعدادات آمنة من حيث النوع، كما يسهّل العمل مع العناصر المعقّدة.

// Define a Codable struct for your configuration
struct AppFeatureConfig: Codable {
  let isNewFeatureEnabled: Bool
  let maxUploadSize: Int
  let themeColors: [String: String]
}

// Fetch and decode the configuration
func configureAppFeatures() {
  let remoteConfig = RemoteConfig.remoteConfig()
  remoteConfig.fetchAndActivate { status, error in
    guard error == nil else { return }

    do {
      let featureConfig = try remoteConfig["app_feature_config"].decoded(asType: AppFeatureConfig.self)
      configureApp(with: featureConfig)
    } catch {
      // Handle decoding errors
      print("Failed to decode configuration: \(error)")
    }
  }
}

تتيح لك هذه الطريقة ما يلي:

  • تحديد بنى الإعدادات المعقّدة.
  • تحليل إعدادات JSON تلقائيًا
  • ضمان أمان النوع عند الوصول إلى قيم Remote Config
  • قدِّم رمزًا برمجيًا واضحًا وسهل القراءة للتعامل مع نماذج البيانات المنظَّمة Remote Config.

استخدام Property Wrappers لإعدادات تعريفية في SwiftUI

أغلفة السمات هي إحدى ميزات Swift الفعّالة التي تتيح لك إضافة سلوك مخصّص إلى تعريفات السمات. في SwiftUI، تُستخدَم أغلفة الخصائص لإدارة الحالة وعمليات الربط وسلوكيات الخصائص الأخرى. لمزيد من المعلومات، راجِع دليل لغة Swift.

struct ContentView: View {
  @RemoteConfigProperty(key: "cardColor", fallback: "#f05138")
  var cardColor

  var body: some View {
    VStack {
      Text("Dynamic Configuration")
        .background(Color(hex: cardColor))
    }
    .onAppear {
      RemoteConfig.remoteConfig().fetchAndActivate()
    }
  }
}

استخدِم أداة التغليف @RemoteConfigProperty عندما تريد طريقة تعريفية للوصول إلى قيم Remote Config في SwiftUI، مع توفير دعم مدمج للقيم التلقائية وإدارة مبسطة للإعدادات.

الخطوة 4: ضبط قيم المَعلمات

باستخدام وحدة تحكّم Firebase أو واجهات برمجة التطبيقات الخلفية، يمكنك إنشاء قيم تلقائية جديدة في الخلفية تلغي القيم داخل التطبيق وفقًا للمنطق الشرطي أو استهداف المستخدمين المطلوب.Remote Config يرشدك هذا القسم إلى خطوات Firebase في وحدة التحكّم لإنشاء هذه القيم.

  1. في وحدة تحكّم Firebase، افتح مشروعك.
  2. انقر على Remote Config من القائمة لعرض لوحة بيانات Remote Config.
  3. حدِّد المَعلمات بالأسماء نفسها التي حدّدتها في تطبيقك. ويمكنك ضبط قيمة تلقائية لكل مَعلمة (ستلغي القيمة التلقائية داخل التطبيق في النهاية)، ويمكنك أيضًا ضبط قيم شرطية. لمزيد من المعلومات، اطّلِع على مَعلمات وشروط Remote Config.
  4. في حال استخدام شروط الإشارات المخصّصة، حدِّد السمات وقيمها. توضّح الأمثلة التالية كيفية تحديد شرط إشارة مخصّصة.

    SwiftObjective-C
      Task {
          let customSignals: [String: CustomSignalValue?] = [
          "city": .string("Tokyo"),
          "preferred_event_category": .string("sports")
        ]
    
        do {
          try await remoteConfig.setCustomSignals(customSignals)
          print("Custom signals set successfully!")
          } catch {
              print("Error setting custom signals: \(error)")
          }
    }
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSDictionary *customSignals = @{
          @"city": @"Tokyo",
          @"preferred_event_category": @"sports"
        };
    
        [self.remoteConfig setCustomSignals:customSignals withCompletion:^(NSError * _Nullable error) {
            if (error) {
                NSLog(@"Error setting custom signals: %@", error);
            } else {
                NSLog(@"Custom signals set successfully!");
            }
      }];
    });

الخطوة 5: استرجاع القيم وتنشيطها

لجلب قيم المَعلمات من Remote Config، استخدِم الطريقتَين fetchWithCompletionHandler: أو fetchWithExpirationDuration:completionHandler:. يتم جلب أي قيم تحدّدها في الخلفية وتخزينها مؤقتًا في الكائن Remote Config.

في الحالات التي تريد فيها استرجاع القيم وتفعيلها في طلب واحد، استخدِم fetchAndActivateWithCompletionHandler:.

يجلب هذا المثال القيم من الخلفية Remote Config (القيم غير المخزّنة مؤقتًا) ويطلب activateWithCompletionHandler: لإتاحتها للتطبيق:

SwiftObjective-C
remoteConfig.fetch { (status, error) -> Void in
  if status == .success {
    print("Config fetched!")
    self.remoteConfig.activate { changed, error in
      // ...
    }
  } else {
    print("Config not fetched")
    print("Error: \(error?.localizedDescription ?? "No error available.")")
  }
  self.displayWelcome()
}
[self.remoteConfig fetchWithCompletionHandler:^(FIRRemoteConfigFetchStatus status, NSError *error) {
    if (status == FIRRemoteConfigFetchStatusSuccess) {
        NSLog(@"Config fetched!");
      [self.remoteConfig activateWithCompletion:^(BOOL changed, NSError * _Nullable error) {
        if (error != nil) {
          NSLog(@"Activate error: %@", error.localizedDescription);
        } else {
          dispatch_async(dispatch_get_main_queue(), ^{
            [self displayWelcome];
          });
        }
      }];
    } else {
        NSLog(@"Config not fetched");
        NSLog(@"Error %@", error.localizedDescription);
    }
}];

بما أنّ قيم المَعلمات المعدَّلة هذه تؤثّر في سلوك تطبيقك ومظهره، عليك تفعيل القيم التي تم جلبها في وقت يضمن تقديم تجربة سلسة للمستخدم، مثل المرة التالية التي يفتح فيها المستخدم تطبيقك. راجِع استراتيجيات تحميل Remote Config للحصول على مزيد من المعلومات والأمثلة.

الخطوة 6: الاستماع إلى التعديلات في الوقت الفعلي

بعد استرجاع قيم المَعلمات، يمكنك استخدام Remote Config في الوقت الفعلي للاستماع إلى التعديلات من الخلفية Remote Config. إشارات Remote Config في الوقت الفعلي إلى الأجهزة المتصلة عند توفّر تحديثات، واسترداد التغييرات تلقائيًا بعد نشر إصدار جديد من Remote Config

تتوافق التحديثات في الوقت الفعلي مع الإصدار 10.7.0 والإصدارات الأحدث من حزمة تطوير البرامج (SDK) لمنصات Apple.Firebase

  1. في تطبيقك، استدعِ الدالة addOnConfigUpdateListener لبدء الاستماع إلى التعديلات واسترجاع أي قيم جديدة أو معدَّلة للمَعلمات تلقائيًا. يستمع المثال التالي إلى التعديلات، وعندما يتم استدعاء activateWithCompletionHandler، يستخدم القيم التي تم جلبها حديثًا لعرض رسالة ترحيب معدَّلة.

    SwiftObjective-C
    remoteConfig.addOnConfigUpdateListener { configUpdate, error in
      guard let configUpdate, error == nil else {
        print("Error listening for config updates: \(error)")
      }
    
      print("Updated keys: \(configUpdate.updatedKeys)")
    
      self.remoteConfig.activate { changed, error in
        guard error == nil else { return self.displayError(error) }
        DispatchQueue.main.async {
          self.displayWelcome()
        }
      }
    }
    __weak __typeof__(self) weakSelf = self;
    [self.remoteConfig addOnConfigUpdateListener:^(FIRRemoteConfigUpdate * _Nonnull configUpdate, NSError * _Nullable error) {
      if (error != nil) {
        NSLog(@"Error listening for config updates %@", error.localizedDescription);
      } else {
        NSLog(@"Updated keys: %@", configUpdate.updatedKeys);
    
        __typeof__(self) strongSelf = weakSelf;
        [strongSelf.remoteConfig activateWithCompletion:^(BOOL changed, NSError * _Nullable error) {
          if (error != nil) {
            NSLog(@"Activate error %@", error.localizedDescription);
          }
    
          dispatch_async(dispatch_get_main_queue(), ^{
            [strongSelf displayWelcome];
          });
        }];
      }
    }];
  2. في المرة القادمة التي تنشر فيها إصدارًا جديدًا من Remote Config، ستطلب الأجهزة التي تشغّل تطبيقك وتستمع إلى التغييرات من معالج الإكمال.

التقييد

إذا كان أحد التطبيقات يجلب البيانات عدة مرات خلال فترة زمنية قصيرة، يتم تقييد عدد مرات جلب البيانات، وتعرض حزمة SDK الرمز FIRRemoteConfigFetchStatusThrottled. قبل الإصدار 6.3.0 من حزمة تطوير البرامج (SDK)، كان الحد الأقصى المسموح به هو 5 طلبات جلب خلال فترة 60 دقيقة (تتضمّن الإصدارات الأحدث حدودًا أكثر تساهلاً).

أثناء تطوير التطبيق، قد تحتاج إلى إجراء عمليات جلب بشكل متكرر لتحديث ذاكرة التخزين المؤقت بشكل متكرر جدًا (عدة مرات في الساعة) من أجل السماح لك بالتكرار السريع أثناء تطوير تطبيقك واختباره. تتجاوز تحديثات Remote Config في الوقت الفعلي ذاكرة التخزين المؤقت تلقائيًا عند تعديل الإعداد على الخادم. لاستيعاب التكرار السريع في مشروع يضم العديد من المطوّرين، يمكنك إضافة موقع FIRRemoteConfigSettings مؤقتًا مع حد أدنى منخفض لفاصل الجلب (MinimumFetchInterval) في تطبيقك.

إنّ الفترة التلقائية والمقترَحة لجلب البيانات في مرحلة الإنتاج Remote Config هي 12 ساعة، ما يعني أنّه لن يتم جلب عمليات الضبط من الخلفية أكثر من مرة خلال فترة 12 ساعة، بغض النظر عن عدد عمليات الجلب التي يتم إجراؤها فعليًا. وعلى وجه التحديد، يتم تحديد الحد الأدنى لفاصل الجلب بالترتيب التالي:

  1. المَعلمة في fetch(long)
  2. المَعلمة في FIRRemoteConfigSettings.MinimumFetchInterval
  3. القيمة التلقائية هي 12 ساعة

الخطوات التالية

إذا لم يسبق لك ذلك، يمكنك الاطّلاع على Remote Config حالات الاستخدام، وإلقاء نظرة على بعض المستندات الخاصة بالمفاهيم الأساسية والاستراتيجيات المتقدّمة، بما في ذلك: