תחילת העבודה עם הגדרת תצורה מרחוק ב-iOS

בחירת פלטפורמה: iOS+‎ Android Web Flutter Unity C++‎


אפשר להשתמש ב-Firebase Remote Config כדי להגדיר פרמטרים באפליקציה ולעדכן את הערכים שלהם בענן. כך אפשר לשנות את המראה וההתנהגות של האפליקציה בלי להפיץ עדכון לאפליקציה. במדריך הזה מפורטים השלבים שצריך לבצע כדי להתחיל, ויש בו קוד לדוגמה שאפשר לשכפל או להוריד ממאגר GitHub‏ firebase/quickstart-ios.

שלב 1: מוסיפים את Remote Config לאפליקציה

  1. אם עדיין לא הוספתם את Firebase לפרויקט Apple, אתם צריכים להוסיף אותו.

  2. כדי להשתמש ב-Remote Config, צריך להשתמש ב-Google Analytics כדי לטַרגט מופעים של האפליקציה על סמך תנאים לפי מאפייני משתמשים וקהלים. חשוב להפעיל את Google Analytics בפרויקט.

  3. יוצרים את אובייקט הסינגלטון Remote Config, כפי שמוצג בדוגמה הבאה:

    Swift

    let remoteConfig = RemoteConfig.remoteConfig()
    let settings = RemoteConfigSettings()
    settings.minimumFetchInterval = 0
    RemoteConfig.remoteConfig().configSettings = settings

    Objective-C

    FIRRemoteConfig *remoteConfig = [FIRRemoteConfig remoteConfig];
    FIRRemoteConfigSettings *remoteConfigSettings = [[FIRRemoteConfigSettings alloc] init];
    remoteConfigSettings.minimumFetchInterval = 0;
    remoteConfig.configSettings = remoteConfigSettings;

האובייקט הזה משמש לאחסון ערכי ברירת מחדל של פרמטרים בתוך האפליקציה, לאחזור ערכים מעודכנים של פרמטרים מהקצה העורפי של Remote Config ולשליטה במועד שבו הערכים שאוחזרו יהיו זמינים באפליקציה.

במהלך הפיתוח, מומלץ להגדיר מרווח זמן מינימלי קצר יחסית בין אחזורים. מידע נוסף זמין במאמר בנושא הגבלת קצב הבקשות.

שלב 2: הגדרת ערכי ברירת מחדל של פרמטרים באפליקציה

אפשר להגדיר ערכי ברירת מחדל של פרמטרים בתוך האפליקציה באובייקט Remote Config, כדי שהאפליקציה תפעל כמצופה לפני שהיא מתחברת לחלק האחורי של Remote Config, וכדי שערכי ברירת מחדל יהיו זמינים אם לא הוגדרו ערכים כאלה בחלק האחורי.

  1. מגדירים קבוצה של שמות פרמטרים וערכי ברירת מחדל של פרמטרים באמצעות אובייקט NSDictionary או קובץ plist.

    אם כבר הגדרתם ערכי פרמטרים של Remote Config backend, אתם יכולים להוריד קובץ plist שנוצר וכולל את כל ערכי ברירת המחדל ולשמור אותו בפרויקט Xcode.

    REST

    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
    

    אפשר ליצור אסימון מסוג Bearer באמצעות הפקודה הבאה ב-Google Cloud CLI או ב-Cloud Shell:

    gcloud auth print-access-token
    

    תוקף הטוקן הזה קצר, ולכן יכול להיות שתצטרכו ליצור אותו מחדש אם תקבלו שגיאת אימות.

    מסוף Firebase

    1. בכרטיסייה פרמטרים, פותחים את התפריט ובוחרים באפשרות הורדת ערכי ברירת מחדל.

    2. כשמופיעה בקשה, מפעילים את .plist ל-iOS ולוחצים על הורדת הקובץ.

  2. מוסיפים את הערכים האלה לאובייקט Remote Config באמצעות setDefaults:. בדוגמה הבאה מוגדרים ערכי ברירת מחדל בתוך האפליקציה מתוך קובץ plist:

    Swift

    RemoteConfig.remoteConfig().setDefaults(fromPlist: "RemoteConfigDefaults")

    Objective-C

    [remoteConfig setDefaultsFromPlistFileName:@"RemoteConfigDefaults"];

שלב 3: מקבלים ערכי פרמטר לשימוש באפליקציה

עכשיו אפשר לקבל ערכי פרמטרים מהאובייקט Remote Config. אם מאוחר יותר תגדירו ערכים ב-Remote Config backend, תאחזרו אותם ואז תפעילו אותם, הערכים האלה יהיו זמינים לאפליקציה. אחרת, תקבלו את ערכי הפרמטרים באפליקציה שהוגדרו באמצעות 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 backend API, אפשר ליצור ערכי ברירת מחדל חדשים ב-backend שמבטלים את הערכים בתוך האפליקציה בהתאם ללוגיקה המותנית או לטירגוט המשתמשים הרצויים. בקטע הזה מוסבר איך ליצור את הערכים האלה באמצעות השלבים בFirebaseמסוף.

  1. במסוף Firebase, פותחים את הפרויקט.
  2. בתפריט, בוחרים באפשרות Remote Config כדי להציג את לוח הבקרה Remote Config.
  3. מגדירים פרמטרים עם אותם שמות כמו הפרמטרים שהגדרתם באפליקציה. לכל פרמטר אפשר להגדיר ערך ברירת מחדל (שבסופו של דבר יבטל את ערך ברירת המחדל באפליקציה), ואפשר גם להגדיר ערכים מותנים. מידע נוסף זמין במאמר Remote Config פרמטרים ותנאים.
  4. אם משתמשים בתנאים מותאמים אישית לאותות, צריך להגדיר את המאפיינים ואת הערכים שלהם. בדוגמאות הבאות אפשר לראות איך מגדירים תנאי מותאם אישית לאות.

    Swift

        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)")
            }
      }

    Objective-C

        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: נקראת כדי להפוך אותם לזמינים לאפליקציה:

Swift

remoteConfig.fetch { (status, error) -> Void in
  if status == .success {
    print("Config fetched!")
    remoteConfig.activate { changed, error in
      // ...
    }
  } else {
    print("Config not fetched")
    print("Error: \(error?.localizedDescription ?? "No error available.")")
  }
}

Objective-C

[remoteConfig fetchWithCompletionHandler:^(FIRRemoteConfigFetchStatus status, NSError *error) {
  if (status == FIRRemoteConfigFetchStatusSuccess) {
    NSLog(@"Config fetched!");
    [remoteConfig activateWithCompletion:^(BOOL changed, NSError * _Nullable error) {
      if (error != nil) {
        NSLog(@"Activate error: %@", error.localizedDescription);
      } else {
        dispatch_async(dispatch_get_main_queue(), ^{
          // update UI
        });
      }
    }];
  } else {
    NSLog(@"Config not fetched");
    NSLog(@"Error %@", error.localizedDescription);
  }
}];

מכיוון שערכי הפרמטרים המעודכנים האלה משפיעים על ההתנהגות והמראה של האפליקציה, כדאי להפעיל את הערכים שאוחזרו בזמן שיבטיח חוויה חלקה למשתמש, למשל בפעם הבאה שהמשתמש יפתח את האפליקציה. מידע נוסף ודוגמאות זמינים במאמר בנושא אסטרטגיות לטעינת Remote Config.

שלב 6: שומעים את העדכונים בזמן אמת

אחרי שמביאים את ערכי הפרמטרים, אפשר להשתמש ב-Remote Config בזמן אמת כדי להאזין לעדכונים מהקצה העורפי של Remote Config. אותות בזמן אמת Remote Config למכשירים מחוברים כשיש עדכונים זמינים, והשינויים נשלפים אוטומטית אחרי שמפרסמים גרסה חדשה של Remote Config האפליקציה.

עדכונים בזמן אמת נתמכים על ידי Firebase SDK לפלטפורמות Apple גרסה 10.7.0 ומעלה.

  1. באפליקציה, קוראים ל-addOnConfigUpdateListener כדי להתחיל להאזין לעדכונים ולאחזר באופן אוטומטי ערכים חדשים או מעודכנים של פרמטרים. בדוגמה הבאה, המערכת מאזינה לעדכונים, וכשמתבצעת קריאה ל-activateWithCompletionHandler, היא משתמשת בערכים שאוחזרו כדי להציג הודעת ברוכים הבאים מעודכנת.

    Swift

    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()
          }
        }
      }
      

    Objective-C

    __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, מכשירים שבהם האפליקציה פועלת ומאזינים לשינויים יפעילו את handler ההשלמה.

ויסות נתונים (throttle)

אם אפליקציה מבצעת יותר מדי אחזורים בפרק זמן קצר, קריאות האחזור מוגבלות על ידי מערכת בקרת העומס (throttling) וה-SDK מחזיר FIRRemoteConfigFetchStatusThrottled. לפני גרסה 6.3.0 של SDK, המגבלה הייתה 5 בקשות אחזור בחלון של 60 דקות (בגרסאות חדשות יותר יש מגבלות מקלות יותר).

במהלך פיתוח האפליקציה, יכול להיות שתרצו לאחזר נתונים לעיתים קרובות יותר כדי לרענן את המטמון בתדירות גבוהה מאוד (הרבה פעמים בשעה), וכך לבצע איטרציות במהירות בזמן הפיתוח והבדיקה של האפליקציה. עדכונים בזמן אמת של Remote Config עוקפים אוטומטית את המטמון כשההגדרה מתעדכנת בשרת. כדי לאפשר איטרציה מהירה בפרויקט עם מספר רב של מפתחים, אתם יכולים להוסיף זמנית מאפיין FIRRemoteConfigSettings עם מרווח מינימלי נמוך לאחזור (MinimumFetchInterval) באפליקציה.

מרווח האחזור שמוגדר כברירת מחדל ומומלץ לשימוש ב-Remote Config הוא 12 שעות. המשמעות היא שההגדרות לא יאוחזרו מהקצה העורפי יותר מפעם אחת בחלון של 12 שעות, לא משנה כמה קריאות אחזור מתבצעות בפועל. ספציפית, מרווח האחזור המינימלי נקבע לפי הסדר הבא:

  1. הפרמטר ב-fetch(long)
  2. הפרמטר ב-FIRRemoteConfigSettings.MinimumFetchInterval
  3. ערך ברירת המחדל הוא 12 שעות.