-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add support for other Firebase products to integrate with Remote Config. #6692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
4a27403
550212d
b8fac84
fae0559
9a5c7f9
7bcef17
c4f83b2
d9996a4
a6574e4
2f396e3
9724b71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,6 +32,11 @@ @implementation RCNConfigContent { | |
| NSMutableDictionary *_fetchedConfig; | ||
| /// Default config provided by user. | ||
| NSMutableDictionary *_defaultConfig; | ||
| /// Active Personalization metadata that is currently used. | ||
| NSDictionary *_activePersonalization; | ||
| /// Pending Personalization metadata that is latest data from server that might or might not be | ||
| /// applied. | ||
| NSDictionary *_fetchedPersonalization; | ||
| /// DBManager | ||
| RCNConfigDBManager *_DBManager; | ||
| /// Current bundle identifier; | ||
|
|
@@ -72,14 +77,17 @@ - (instancetype)initWithDBManager:(RCNConfigDBManager *)DBManager { | |
| _activeConfig = [[NSMutableDictionary alloc] init]; | ||
| _fetchedConfig = [[NSMutableDictionary alloc] init]; | ||
| _defaultConfig = [[NSMutableDictionary alloc] init]; | ||
| _activePersonalization = [[NSDictionary alloc] init]; | ||
| _fetchedPersonalization = [[NSDictionary alloc] init]; | ||
| _bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; | ||
| if (!_bundleIdentifier) { | ||
| FIRLogNotice(kFIRLoggerRemoteConfig, @"I-RCN000038", | ||
| @"Main bundle identifier is missing. Remote Config might not work properly."); | ||
| _bundleIdentifier = @""; | ||
| } | ||
| _DBManager = DBManager; | ||
| _configLoadFromDBSemaphore = dispatch_semaphore_create(0); | ||
| // Waits for both config and Personalization data to load. | ||
| _configLoadFromDBSemaphore = dispatch_semaphore_create(1); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please add a comment why the particular semaphore value is set. Also, maybe it will be a bit more readable if we call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved the database methods closer. |
||
| [self loadConfigFromMainTable]; | ||
| } | ||
| return self; | ||
|
|
@@ -93,6 +101,44 @@ - (BOOL)initializationSuccessful { | |
| return isDatabaseLoadSuccessful; | ||
| } | ||
|
|
||
| #pragma mark - database | ||
|
|
||
| /// This method is only meant to be called at init time. The underlying logic will need to be | ||
| /// revaluated if the assumption changes at a later time. | ||
| - (void)loadConfigFromMainTable { | ||
| if (!_DBManager) { | ||
| return; | ||
| } | ||
|
|
||
| NSAssert(!_isDatabaseLoadAlreadyInitiated, @"Database load has already been initiated"); | ||
| _isDatabaseLoadAlreadyInitiated = true; | ||
|
|
||
| [_DBManager | ||
| loadMainWithBundleIdentifier:_bundleIdentifier | ||
| completionHandler:^(BOOL success, NSDictionary *fetchedConfig, | ||
| NSDictionary *activeConfig, NSDictionary *defaultConfig) { | ||
| self->_fetchedConfig = [fetchedConfig mutableCopy]; | ||
| self->_activeConfig = [activeConfig mutableCopy]; | ||
| self->_defaultConfig = [defaultConfig mutableCopy]; | ||
| dispatch_semaphore_signal(self->_configLoadFromDBSemaphore); | ||
| }]; | ||
|
|
||
| [_DBManager loadPersonalizationWithCompletionHandler:^( | ||
| BOOL success, NSDictionary *fetchedPersonalization, | ||
| NSDictionary *activePersonalization, NSDictionary *defaultConfig) { | ||
| self->_fetchedPersonalization = [fetchedPersonalization copy]; | ||
| self->_activePersonalization = [activePersonalization copy]; | ||
| dispatch_semaphore_signal(self->_configLoadFromDBSemaphore); | ||
| }]; | ||
| } | ||
|
|
||
| /// Update the current config result to main table. | ||
| /// @param values Values in a row to write to the table. | ||
| /// @param source The source the config data is coming from. It determines which table to write to. | ||
| - (void)updateMainTableWithValues:(NSArray *)values fromSource:(RCNDBSource)source { | ||
| [_DBManager insertMainTableWithValues:values fromSource:source completionHandler:nil]; | ||
| } | ||
|
|
||
| #pragma mark - update | ||
| /// This function is for copying dictionary when user set up a default config or when user clicks | ||
| /// activate. For now the DBSource can only be Active or Default. | ||
|
|
@@ -204,10 +250,17 @@ - (void)updateConfigContentWithResponse:(NSDictionary *)response | |
| if ([state isEqualToString:RCNFetchResponseKeyStateUpdate]) { | ||
| [self handleUpdateStateForConfigNamespace:currentNamespace | ||
| withEntries:response[RCNFetchResponseKeyEntries]]; | ||
| [self handleUpdatePersonalization:response[RCNFetchResponseKeyPersonalizationMetadata]]; | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| - (void)activatePersonalization { | ||
| _activePersonalization = _fetchedPersonalization; | ||
| [_DBManager insertOrUpdatePersonalizationConfig:_activePersonalization | ||
| fromSource:RCNDBSourceActive]; | ||
| } | ||
|
|
||
| #pragma mark State handling | ||
| - (void)handleNoChangeStateForConfigNamespace:(NSString *)currentNamespace { | ||
| if (!_fetchedConfig[currentNamespace]) { | ||
|
|
@@ -263,35 +316,14 @@ - (void)handleUpdateStateForConfigNamespace:(NSString *)currentNamespace | |
| } | ||
| } | ||
|
|
||
| #pragma mark - database | ||
|
|
||
| /// This method is only meant to be called at init time. The underlying logic will need to be | ||
| /// revaluated if the assumption changes at a later time. | ||
| - (void)loadConfigFromMainTable { | ||
| if (!_DBManager) { | ||
| - (void)handleUpdatePersonalization:(NSDictionary *)metadata { | ||
| if (!metadata) { | ||
| return; | ||
| } | ||
|
|
||
| NSAssert(!_isDatabaseLoadAlreadyInitiated, @"Database load has already been initiated"); | ||
| _isDatabaseLoadAlreadyInitiated = true; | ||
|
|
||
| [_DBManager | ||
| loadMainWithBundleIdentifier:_bundleIdentifier | ||
| completionHandler:^(BOOL success, NSDictionary *fetchedConfig, | ||
| NSDictionary *activeConfig, NSDictionary *defaultConfig) { | ||
| self->_fetchedConfig = [fetchedConfig mutableCopy]; | ||
| self->_activeConfig = [activeConfig mutableCopy]; | ||
| self->_defaultConfig = [defaultConfig mutableCopy]; | ||
| dispatch_semaphore_signal(self->_configLoadFromDBSemaphore); | ||
| }]; | ||
| _fetchedPersonalization = metadata; | ||
| [_DBManager insertOrUpdatePersonalizationConfig:metadata fromSource:RCNDBSourceFetched]; | ||
| } | ||
|
|
||
| /// Update the current config result to main table. | ||
| /// @param values Values in a row to write to the table. | ||
| /// @param source The source the config data is coming from. It determines which table to write to. | ||
| - (void)updateMainTableWithValues:(NSArray *)values fromSource:(RCNDBSource)source { | ||
| [_DBManager insertMainTableWithValues:values fromSource:source completionHandler:nil]; | ||
| } | ||
| #pragma mark - getter/setter | ||
| - (NSDictionary *)fetchedConfig { | ||
| /// If this is the first time reading the fetchedConfig, we might still be reading it from the | ||
|
|
@@ -314,6 +346,16 @@ - (NSDictionary *)defaultConfig { | |
| return _defaultConfig; | ||
| } | ||
|
|
||
| - (NSDictionary *)getConfigAndMetadataForNamespace:(NSString *)FIRNamespace { | ||
| /// If this is the first time reading the active metadata, we might still be reading it from the | ||
| /// database. | ||
| [self checkAndWaitForInitialDatabaseLoad]; | ||
| return @{ | ||
| RCNFetchResponseKeyEntries : _activeConfig[FIRNamespace], | ||
| RCNFetchResponseKeyPersonalizationMetadata : _activePersonalization | ||
| }; | ||
| } | ||
|
|
||
| /// We load the database async at init time. Block all further calls to active/fetched/default | ||
| /// configs until load is done. | ||
| /// @return Database load completion status. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should move to a 7.1.0 section. 7.0.0 is past code freeze.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.