45
45
// / Notification when config is successfully activated
46
46
const NSNotificationName FIRRemoteConfigActivateNotification =
47
47
@" FIRRemoteConfigActivateNotification" ;
48
+ static NSNotificationName FIRRolloutsStateDidChangeNotificationName =
49
+ @" FIRRolloutsStateDidChangeNotification" ;
48
50
49
51
// / Listener for the get methods.
50
52
typedef void (^FIRRemoteConfigListener)(NSString *_Nonnull, NSDictionary *_Nonnull);
@@ -79,8 +81,9 @@ @implementation FIRRemoteConfig {
79
81
*RCInstances;
80
82
81
83
+ (nonnull FIRRemoteConfig *)remoteConfigWithApp : (FIRApp *_Nonnull)firebaseApp {
82
- return [FIRRemoteConfig remoteConfigWithFIRNamespace: FIRNamespaceGoogleMobilePlatform
83
- app: firebaseApp];
84
+ return [FIRRemoteConfig
85
+ remoteConfigWithFIRNamespace: FIRRemoteConfigConstants.FIRNamespaceGoogleMobilePlatform
86
+ app: firebaseApp];
84
87
}
85
88
86
89
+ (nonnull FIRRemoteConfig *)remoteConfigWithFIRNamespace : (NSString *_Nonnull)firebaseNamespace {
@@ -116,8 +119,9 @@ + (FIRRemoteConfig *)remoteConfig {
116
119
@" initializer in SwiftUI." ];
117
120
}
118
121
119
- return [FIRRemoteConfig remoteConfigWithFIRNamespace: FIRNamespaceGoogleMobilePlatform
120
- app: [FIRApp defaultApp ]];
122
+ return [FIRRemoteConfig
123
+ remoteConfigWithFIRNamespace: FIRRemoteConfigConstants.FIRNamespaceGoogleMobilePlatform
124
+ app: [FIRApp defaultApp ]];
121
125
}
122
126
123
127
// / Singleton instance of serial queue for queuing all incoming RC calls.
@@ -329,16 +333,20 @@ - (void)activateWithCompletion:(FIRRemoteConfigActivateChangeCompletion)completi
329
333
// New config has been activated at this point
330
334
FIRLogDebug (kFIRLoggerRemoteConfig , @" I-RCN000069" , @" Config activated." );
331
335
[strongSelf->_configContent activatePersonalization ];
332
- // Update activeRolloutMetadata
333
- [strongSelf->_configContent activateRolloutMetadata ];
334
336
// Update last active template version number in setting and userDefaults.
335
- dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
336
- [strongSelf->_settings updateLastActiveTemplateVersion ];
337
- });
337
+ [strongSelf->_settings updateLastActiveTemplateVersion ];
338
+ // Update activeRolloutMetadata
339
+ [strongSelf->_configContent activateRolloutMetadata: ^(BOOL success) {
340
+ if (success) {
341
+ [self notifyRolloutsStateChange: strongSelf->_configContent.activeRolloutMetadata
342
+ versionNumber: strongSelf->_settings.lastActiveTemplateVersion];
343
+ }
344
+ }];
345
+
338
346
// Update experiments only for 3p namespace
339
347
NSString *namespace = [strongSelf->_FIRNamespace
340
348
substringToIndex: [strongSelf->_FIRNamespace rangeOfString: @" :" ].location];
341
- if ([namespace isEqualToString: FIRNamespaceGoogleMobilePlatform]) {
349
+ if ([namespace isEqualToString: FIRRemoteConfigConstants. FIRNamespaceGoogleMobilePlatform]) {
342
350
dispatch_async (dispatch_get_main_queue (), ^{
343
351
[self notifyConfigHasActivated ];
344
352
});
@@ -383,6 +391,17 @@ - (NSString *)fullyQualifiedNamespace:(NSString *)namespace {
383
391
return fullyQualifiedNamespace;
384
392
}
385
393
394
+ - (FIRRemoteConfigValue *)defaultValueForFullyQualifiedNamespace : (NSString *)namespace
395
+ key : (NSString *)key {
396
+ FIRRemoteConfigValue *value = self->_configContent .defaultConfig [namespace][key];
397
+ if (!value) {
398
+ value = [[FIRRemoteConfigValue alloc ]
399
+ initWithData: [NSData data ]
400
+ source: (FIRRemoteConfigSource)FIRRemoteConfigSourceStatic];
401
+ }
402
+ return value;
403
+ }
404
+
386
405
#pragma mark - Get Config Result
387
406
388
407
- (FIRRemoteConfigValue *)objectForKeyedSubscript : (NSString *)key {
@@ -408,13 +427,7 @@ - (FIRRemoteConfigValue *)configValueForKey:(NSString *)key {
408
427
config: [self ->_configContent getConfigAndMetadataForNamespace: FQNamespace]];
409
428
return ;
410
429
}
411
- value = self->_configContent .defaultConfig [FQNamespace][key];
412
- if (value) {
413
- return ;
414
- }
415
-
416
- value = [[FIRRemoteConfigValue alloc ] initWithData: [NSData data ]
417
- source: FIRRemoteConfigSourceStatic];
430
+ value = [self defaultValueForFullyQualifiedNamespace: FQNamespace key: key];
418
431
});
419
432
return value;
420
433
}
@@ -619,4 +632,67 @@ - (FIRConfigUpdateListenerRegistration *)addOnConfigUpdateListener:
619
632
return [self ->_configRealtime addConfigUpdateListener: listener];
620
633
}
621
634
635
+ #pragma mark - Rollout
636
+
637
+ - (void )addRemoteConfigInteropSubscriber : (id <FIRRolloutsStateSubscriber>)subscriber {
638
+ [[NSNotificationCenter defaultCenter ]
639
+ addObserverForName: FIRRolloutsStateDidChangeNotificationName
640
+ object: self
641
+ queue: nil
642
+ usingBlock: ^(NSNotification *_Nonnull notification) {
643
+ FIRRolloutsState *rolloutsState =
644
+ notification.userInfo [FIRRolloutsStateDidChangeNotificationName];
645
+ [subscriber rolloutsStateDidChange: rolloutsState];
646
+ }];
647
+ // Send active rollout metadata stored in persistence while app launched if there is activeConfig
648
+ NSString *fullyQualifiedNamespace = [self fullyQualifiedNamespace: _FIRNamespace];
649
+ NSDictionary <NSString *, NSDictionary *> *activeConfig = self->_configContent .activeConfig ;
650
+ if (activeConfig[fullyQualifiedNamespace] && activeConfig[fullyQualifiedNamespace].count > 0 ) {
651
+ [self notifyRolloutsStateChange: self ->_configContent.activeRolloutMetadata
652
+ versionNumber: self ->_settings.lastActiveTemplateVersion];
653
+ }
654
+ }
655
+
656
+ - (void )notifyRolloutsStateChange : (NSArray <NSDictionary *> *)rolloutMetadata
657
+ versionNumber : (NSString *)versionNumber {
658
+ NSArray <FIRRolloutAssignment *> *rolloutsAssignments =
659
+ [self rolloutsAssignmentsWith: rolloutMetadata versionNumber: versionNumber];
660
+ FIRRolloutsState *rolloutsState =
661
+ [[FIRRolloutsState alloc ] initWithAssignmentList: rolloutsAssignments];
662
+ FIRLogDebug (kFIRLoggerRemoteConfig , @" I-RCN000069" ,
663
+ @" Send rollouts state notification with name %@ to RemoteConfigInterop." ,
664
+ FIRRolloutsStateDidChangeNotificationName);
665
+ [[NSNotificationCenter defaultCenter ]
666
+ postNotificationName: FIRRolloutsStateDidChangeNotificationName
667
+ object: self
668
+ userInfo: @{FIRRolloutsStateDidChangeNotificationName : rolloutsState}];
669
+ }
670
+
671
+ - (NSArray <FIRRolloutAssignment *> *)rolloutsAssignmentsWith :
672
+ (NSArray <NSDictionary *> *)rolloutMetadata
673
+ versionNumber : (NSString *)versionNumber {
674
+ NSMutableArray <FIRRolloutAssignment *> *rolloutsAssignments = [[NSMutableArray alloc ] init ];
675
+ NSString *FQNamespace = [self fullyQualifiedNamespace: _FIRNamespace];
676
+ for (NSDictionary *metadata in rolloutMetadata) {
677
+ NSString *rolloutId = metadata[RCNFetchResponseKeyRolloutID];
678
+ NSString *variantID = metadata[RCNFetchResponseKeyVariantID];
679
+ NSArray <NSString *> *affectedParameterKeys = metadata[RCNFetchResponseKeyAffectedParameterKeys];
680
+ if (rolloutId && variantID && affectedParameterKeys) {
681
+ for (NSString *key in affectedParameterKeys) {
682
+ FIRRemoteConfigValue *value = self->_configContent .activeConfig [FQNamespace][key];
683
+ if (!value) {
684
+ value = [self defaultValueForFullyQualifiedNamespace: FQNamespace key: key];
685
+ }
686
+ FIRRolloutAssignment *assignment =
687
+ [[FIRRolloutAssignment alloc ] initWithRolloutId: rolloutId
688
+ variantId: variantID
689
+ templateVersion: [versionNumber longLongValue ]
690
+ parameterKey: key
691
+ parameterValue: value.stringValue];
692
+ [rolloutsAssignments addObject: assignment];
693
+ }
694
+ }
695
+ }
696
+ return rolloutsAssignments;
697
+ }
622
698
@end
0 commit comments