Начало работы с Remote Config в iOS

Выберите платформу: iOS+ Android Веб 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, то можете скачать сгенерированный файл 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
    

    Вы можете сгенерировать токен на предъявителя, выполнив следующую команду с помощью Google Cloud CLI или Cloud Shell:

    gcloud auth print-access-token
    

    Этот токен действует недолго, поэтому, если вы получите ошибку аутентификации, вам может потребоваться сгенерировать его заново.

    Консоль Firebase

    1. В консоли Firebase перейдите на страницу DevOps & Engagement (DevOps и вовлечение) > Remote Config (Удаленная конфигурация) > Parameters (Параметры).

    2. Откройте меню и выберите Скачать значения по умолчанию.

    3. В появившемся окне включите параметр .plist для iOS и нажмите Скачать файл.

  2. Добавьте эти значения в объект Remote Config с помощью setDefaults:. В примере ниже значения по умолчанию задаются из файла plist.

    Swift

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

    Objective-C

    [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 – использование нотации нижнего индекса:

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 или серверных API Remote Config можно создать новые значения по умолчанию, которые будут переопределять значения в приложении в соответствии с заданной условной логикой или таргетингом на пользователей. В этом разделе рассказывается, как создать эти значения в консоли Firebase.

  1. В консоли Firebase перейдите на страницу DevOps & Engagement (DevOps и вовлечение) > Remote Config (Удаленная конфигурация) > Parameters (Параметры).

  2. Задайте параметры с теми же названиями, что и в приложении. Для каждого параметра можно установить значение по умолчанию (которое в конечном итоге переопределит значение по умолчанию в приложении), а также условные значения. Подробнее о параметрах и условиях Remote Config…

  3. Если вы используете условия для специальных сигналов, задайте атрибуты и их значения. Ниже приведены примеры того, как задать условие для пользовательского сигнала.

    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.

Обновления в реальном времени поддерживаются в SDK Firebase для платформ 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 устройства, на которых запущено приложение и которые отслеживают изменения, вызовут обработчик завершения.

Ограничение пропускной способности

Если приложение выполняет слишком много запросов за короткий период времени, вызовы на получение ограничиваются и SDK возвращает FIRRemoteConfigFetchStatusThrottled. В версиях SDK до 6.3.0 ограничение составляло 5 запросов на получение в течение 60 минут (в более новых версиях ограничения менее строгие).

Во время разработки приложения вы можете получать данные чаще, чтобы обновлять кеш несколько раз в час. Это позволит вам быстро вносить изменения и тестировать приложение. Обновления Remote Config в реальном времени автоматически обходят кеш, когда конфигурация обновляется на сервере. Чтобы ускорить итерацию в проекте с большим количеством разработчиков, вы можете временно добавить в приложение свойство FIRRemoteConfigSettings с низким минимальным интервалом получения (MinimumFetchInterval).

Рекомендуемый интервал получения данных для рабочей версии Remote Config составляет 12 часов. Это означает, что конфигурации будут запрашиваться из серверной части не чаще одного раза в 12 часов, независимо от того, сколько вызовов получения данных было сделано. Минимальный интервал извлечения определяется в следующем порядке:

  1. Параметр в fetch(long)
  2. Параметр в FIRRemoteConfigSettings.MinimumFetchInterval
  3. Значение по умолчанию – 12 часов.