This post demonstrates how developers can dynamically update app behavior, UI elements, and features without requiring an App Store update. This capability is especially valuable for A/B testing, feature flagging, and personalized user experiences, making apps more adaptable and data-driven. Despite its benefits, many developers underutilize Remote Config. A step-by-step guide covering Firebase setup, SDK integration, fetching configurations, and best practices would offer significant value.
In this post, we’ll walk through creating a sample iOS app that reads a feature flag and, based on its value, displays a different UI message.
Setup Firebase and XCode
In a previous post, Unlocking Firebase iOS Push Notifications, we explained how to set up a Firebase project for iOS from scratch. During this process, you obtained a file called GoogleService-Info.plist.

You have to include it on your project, next step is include SPM Firebase Library.

Add FirebaseCore and FirebaseRemoteConfig to your target.
Create a Firebase Configuration Flag
From your Firebase project side bar:

Select ‘Remote Config’. And add a new parameter:

In our implementation, ‘NewTentativeFeatureFlag’ will be a boolean (false) parameter. Once set, ensure that it is properly published.
The iOS Remote Configuration App
The Main ContentView retrieves the newTentativeFeatureFlag
@Published attribute from the RemoteConfigManager component in Firebase:
struct ContentView: View {
@State private var showNewFeature = false
@StateObject var remoteConfigManager = appSingletons.remoteConfigManager
var body: some View {
VStack {
if remoteConfigManager.newTentativeFeatureFlag {
Text("New Feature is Enabled!")
.font(.largeTitle)
.foregroundColor(.green)
} else {
Text("New Feature is Disabled.")
.font(.largeTitle)
.foregroundColor(.red)
}
}
}
}
Depending on the value obtained, a different text is printed with a different color. This is a very simplistic example, but it could represent an A/B test, a new feature, or any functionality you want to run live.
An alternative valid implementation could be to call getBoolValue
inside the .onAppear
modifier instead of using the @published
attribute from RemoteConfigManager
.
RemoteConfigManager
is the component that wraps Firebase Remote Config functionality.
import Foundation
import Firebase
@globalActor
actor GlobalManager {
static var shared = GlobalManager()
}
@GlobalManager
class RemoteConfigManager: ObservableObject {
@MainActor
@Published var newTentativeFeatureFlag: Bool = false
private var internalNewTentativeFeatureFlag = false {
didSet {
Task { @MainActor [internalNewTentativeFeatureFlag] in
newTentativeFeatureFlag = internalNewTentativeFeatureFlag
}
}
}
private var remoteConfig: RemoteConfig = RemoteConfig.remoteConfig()
private var configured = false
@MainActor
init() {
Task { @GlobalManager in
await self.setupRemoteConfig()
}
}
private func setupRemoteConfig() async {
guard !configured else { return }
let settings = RemoteConfigSettings()
settings.minimumFetchInterval = 0
remoteConfig.configSettings = settings
fetchConfig { [weak self] result in
guard let self else { return }
Task { @GlobalManager [result] in
configured = result
self.internalNewTentativeFeatureFlag = self.getBoolValue(forKey: "NewTentativeFeatureFlag")
}
}
}
private func fetchConfig(completion: @escaping @Sendable (Bool) -> Void) {
remoteConfig.fetch { status, error in
if status == .success {
Task { @GlobalManager in
self.remoteConfig.activate { changed, error in
completion(true)
}
}
} else {
completion(false)
}
}
}
func getBoolValue(forKey key: String) -> Bool {
return remoteConfig[key].boolValue
}
func getStringValue(forKey key: String) -> String {
return remoteConfig[key].stringValue
}
}
The code is already compatible with Swift 6 and defines a RemoteConfigManager
class responsible for fetching and managing Firebase Remote Config values in a SwiftUI application. To ensure thread safety, all operations related to Remote Config are handled within a global actor (GlobalManager
).
The RemoteConfigManager
class conforms to ObservableObject
, allowing SwiftUI views to react to changes in its properties. The newTentativeFeatureFlag
property is marked with @Published
and updated safely on the main actor to maintain UI responsiveness.
The class initializes Remote Config settings, fetches values asynchronously, and updates internalNewTentativeFeatureFlag
accordingly. This design ensures efficient Remote Config value retrieval while maintaining proper concurrency handling in a Swift application.
Build and run
As title suggests, build and run:

In Firebase Remote Config, ‘NewTentativeFeatureFlag’ is set to true, and the view is displaying the correct message. Now, let’s switch the value to false and restart the application. Yes, I said restart, because when the value is changed in the console, Firebase Remote Config has no mechanism to notify the app. The app must periodically fetch the value to detect any changes in its state.

Now turn ‘NewTentativeFeatureFlag’ to false and re-start the app.
Conclusions
Firebase Remote Config is essential for implementing A/B tests and serves as a great mechanism for disabling immature functionalities that might fail in production (e.g., a new payment method).
You can find source code used for writing this post in following repository.
References
- Firebase Remote Config
Apple Developer Documentation