@@ -32,6 +32,11 @@ @implementation RCNConfigContent {
3232 NSMutableDictionary *_fetchedConfig;
3333 // / Default config provided by user.
3434 NSMutableDictionary *_defaultConfig;
35+ // / Active Personalization metadata that is currently used.
36+ NSDictionary *_activePersonalization;
37+ // / Pending Personalization metadata that is latest data from server that might or might not be
38+ // / applied.
39+ NSDictionary *_fetchedPersonalization;
3540 // / DBManager
3641 RCNConfigDBManager *_DBManager;
3742 // / Current bundle identifier;
@@ -72,14 +77,17 @@ - (instancetype)initWithDBManager:(RCNConfigDBManager *)DBManager {
7277 _activeConfig = [[NSMutableDictionary alloc ] init ];
7378 _fetchedConfig = [[NSMutableDictionary alloc ] init ];
7479 _defaultConfig = [[NSMutableDictionary alloc ] init ];
80+ _activePersonalization = [[NSDictionary alloc ] init ];
81+ _fetchedPersonalization = [[NSDictionary alloc ] init ];
7582 _bundleIdentifier = [[NSBundle mainBundle ] bundleIdentifier ];
7683 if (!_bundleIdentifier) {
7784 FIRLogNotice (kFIRLoggerRemoteConfig , @" I-RCN000038" ,
7885 @" Main bundle identifier is missing. Remote Config might not work properly." );
7986 _bundleIdentifier = @" " ;
8087 }
8188 _DBManager = DBManager;
82- _configLoadFromDBSemaphore = dispatch_semaphore_create (0 );
89+ // Waits for both config and Personalization data to load.
90+ _configLoadFromDBSemaphore = dispatch_semaphore_create (1 );
8391 [self loadConfigFromMainTable ];
8492 }
8593 return self;
@@ -93,6 +101,44 @@ - (BOOL)initializationSuccessful {
93101 return isDatabaseLoadSuccessful;
94102}
95103
104+ #pragma mark - database
105+
106+ // / This method is only meant to be called at init time. The underlying logic will need to be
107+ // / revaluated if the assumption changes at a later time.
108+ - (void )loadConfigFromMainTable {
109+ if (!_DBManager) {
110+ return ;
111+ }
112+
113+ NSAssert (!_isDatabaseLoadAlreadyInitiated, @" Database load has already been initiated" );
114+ _isDatabaseLoadAlreadyInitiated = true ;
115+
116+ [_DBManager
117+ loadMainWithBundleIdentifier: _bundleIdentifier
118+ completionHandler: ^(BOOL success, NSDictionary *fetchedConfig,
119+ NSDictionary *activeConfig, NSDictionary *defaultConfig) {
120+ self->_fetchedConfig = [fetchedConfig mutableCopy ];
121+ self->_activeConfig = [activeConfig mutableCopy ];
122+ self->_defaultConfig = [defaultConfig mutableCopy ];
123+ dispatch_semaphore_signal (self->_configLoadFromDBSemaphore );
124+ }];
125+
126+ [_DBManager loadPersonalizationWithCompletionHandler: ^(
127+ BOOL success, NSDictionary *fetchedPersonalization,
128+ NSDictionary *activePersonalization, NSDictionary *defaultConfig) {
129+ self->_fetchedPersonalization = [fetchedPersonalization copy ];
130+ self->_activePersonalization = [activePersonalization copy ];
131+ dispatch_semaphore_signal (self->_configLoadFromDBSemaphore );
132+ }];
133+ }
134+
135+ // / Update the current config result to main table.
136+ // / @param values Values in a row to write to the table.
137+ // / @param source The source the config data is coming from. It determines which table to write to.
138+ - (void )updateMainTableWithValues : (NSArray *)values fromSource : (RCNDBSource)source {
139+ [_DBManager insertMainTableWithValues: values fromSource: source completionHandler: nil ];
140+ }
141+
96142#pragma mark - update
97143// / This function is for copying dictionary when user set up a default config or when user clicks
98144// / activate. For now the DBSource can only be Active or Default.
@@ -204,10 +250,17 @@ - (void)updateConfigContentWithResponse:(NSDictionary *)response
204250 if ([state isEqualToString: RCNFetchResponseKeyStateUpdate]) {
205251 [self handleUpdateStateForConfigNamespace: currentNamespace
206252 withEntries: response[RCNFetchResponseKeyEntries]];
253+ [self handleUpdatePersonalization: response[RCNFetchResponseKeyPersonalizationMetadata]];
207254 return ;
208255 }
209256}
210257
258+ - (void )activatePersonalization {
259+ _activePersonalization = _fetchedPersonalization;
260+ [_DBManager insertOrUpdatePersonalizationConfig: _activePersonalization
261+ fromSource: RCNDBSourceActive];
262+ }
263+
211264#pragma mark State handling
212265- (void )handleNoChangeStateForConfigNamespace : (NSString *)currentNamespace {
213266 if (!_fetchedConfig[currentNamespace]) {
@@ -263,35 +316,14 @@ - (void)handleUpdateStateForConfigNamespace:(NSString *)currentNamespace
263316 }
264317}
265318
266- #pragma mark - database
267-
268- // / This method is only meant to be called at init time. The underlying logic will need to be
269- // / revaluated if the assumption changes at a later time.
270- - (void )loadConfigFromMainTable {
271- if (!_DBManager) {
319+ - (void )handleUpdatePersonalization : (NSDictionary *)metadata {
320+ if (!metadata) {
272321 return ;
273322 }
274-
275- NSAssert (!_isDatabaseLoadAlreadyInitiated, @" Database load has already been initiated" );
276- _isDatabaseLoadAlreadyInitiated = true ;
277-
278- [_DBManager
279- loadMainWithBundleIdentifier: _bundleIdentifier
280- completionHandler: ^(BOOL success, NSDictionary *fetchedConfig,
281- NSDictionary *activeConfig, NSDictionary *defaultConfig) {
282- self->_fetchedConfig = [fetchedConfig mutableCopy ];
283- self->_activeConfig = [activeConfig mutableCopy ];
284- self->_defaultConfig = [defaultConfig mutableCopy ];
285- dispatch_semaphore_signal (self->_configLoadFromDBSemaphore );
286- }];
323+ _fetchedPersonalization = metadata;
324+ [_DBManager insertOrUpdatePersonalizationConfig: metadata fromSource: RCNDBSourceFetched];
287325}
288326
289- // / Update the current config result to main table.
290- // / @param values Values in a row to write to the table.
291- // / @param source The source the config data is coming from. It determines which table to write to.
292- - (void )updateMainTableWithValues : (NSArray *)values fromSource : (RCNDBSource)source {
293- [_DBManager insertMainTableWithValues: values fromSource: source completionHandler: nil ];
294- }
295327#pragma mark - getter/setter
296328- (NSDictionary *)fetchedConfig {
297329 // / If this is the first time reading the fetchedConfig, we might still be reading it from the
@@ -314,6 +346,16 @@ - (NSDictionary *)defaultConfig {
314346 return _defaultConfig;
315347}
316348
349+ - (NSDictionary *)getConfigAndMetadataForNamespace : (NSString *)FIRNamespace {
350+ // / If this is the first time reading the active metadata, we might still be reading it from the
351+ // / database.
352+ [self checkAndWaitForInitialDatabaseLoad ];
353+ return @{
354+ RCNFetchResponseKeyEntries : _activeConfig[FIRNamespace],
355+ RCNFetchResponseKeyPersonalizationMetadata : _activePersonalization
356+ };
357+ }
358+
317359// / We load the database async at init time. Block all further calls to active/fetched/default
318360// / configs until load is done.
319361// / @return Database load completion status.
0 commit comments