Skip to content

Commit

Permalink
tests
Browse files Browse the repository at this point in the history
  • Loading branch information
themiswang committed Nov 22, 2023
1 parent a0fcb67 commit d40694f
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 9 deletions.
14 changes: 11 additions & 3 deletions Crashlytics/Crashlytics/FIRCrashlytics.m
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#import <GoogleDataTransport/GoogleDataTransport.h>

@import FirebaseSessions;
@import FirebaseRemoteConfigInterop;

#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
Expand Down Expand Up @@ -104,7 +105,8 @@ - (instancetype)initWithApp:(FIRApp *)app
appInfo:(NSDictionary *)appInfo
installations:(FIRInstallations *)installations
analytics:(id<FIRAnalyticsInterop>)analytics
sessions:(id<FIRSessionsProvider>)sessions {
sessions:(id<FIRSessionsProvider>)sessions
remoteConfig:(id<FIRRemoteConfigInterop>)remoteConfig {
self = [super init];

if (self) {
Expand Down Expand Up @@ -206,6 +208,10 @@ + (void)load {
FIRDependency *sessionsDep =
[FIRDependency dependencyWithProtocol:@protocol(FIRSessionsProvider)];

FIRDependency *remoteConfigDep =
[FIRDependency dependencyWithProtocol:@protocol(FIRRemoteConfigInterop)];

// break point on this also with rc creatioBlock and check the order
FIRComponentCreationBlock creationBlock =
^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) {
if (!container.app.isDefaultApp) {
Expand All @@ -215,6 +221,7 @@ + (void)load {

id<FIRAnalyticsInterop> analytics = FIR_COMPONENT(FIRAnalyticsInterop, container);
id<FIRSessionsProvider> sessions = FIR_COMPONENT(FIRSessionsProvider, container);
id<FIRRemoteConfigInterop> remoteConfig = FIR_COMPONENT(FIRRemoteConfigInterop, container);

FIRInstallations *installations = [FIRInstallations installationsWithApp:container.app];

Expand All @@ -224,13 +231,14 @@ + (void)load {
appInfo:NSBundle.mainBundle.infoDictionary
installations:installations
analytics:analytics
sessions:sessions];
sessions:sessions
remoteConfig:remoteConfig];
};

FIRComponent *component =
[FIRComponent componentWithProtocol:@protocol(FIRCrashlyticsInstanceProvider)
instantiationTiming:FIRInstantiationTimingEagerInDefaultApp
dependencies:@[ analyticsDep, sessionsDep ]
dependencies:@[ analyticsDep, sessionsDep, remoteConfigDep ]
creationBlock:creationBlock];
return @[ component ];
}
Expand Down
14 changes: 14 additions & 0 deletions FirebaseRemoteConfig/Interop/RemoteConfigInterop.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// File.swift
//
//
// Created by Themis Wang on 2023-11-16.
//

import Foundation

@objc(FIRRemoteConfigInterop)
public protocol RemoteConfigInterop {
func registerRolloutsStateSubscriber(_ namespace: String,
subscriber: RolloutsStateSubscriber?)
}
39 changes: 39 additions & 0 deletions FirebaseRemoteConfig/Interop/RolloutAssignment.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// File.swift
//
//
// Created by Themis Wang on 2023-11-16.
//

import Foundation

@objc(FIRRolloutAssignment)
public class RolloutAssignment: NSObject {
@objc public var rolloutId: String
@objc public var variantId: String
@objc public var templateVersion: String
@objc public var parameterKey: String
@objc public var parameterValue: String

public init(rolloutId: String, variantId: String, templateVersion: String, parameterKey: String,
parameterValue: String) {
self.rolloutId = rolloutId
self.variantId = variantId
self.templateVersion = templateVersion
self.parameterKey = parameterKey
self.parameterValue = parameterValue
super.init()
}
}

@objc(FIRRolloutsState)
public class RolloutsState: NSObject {
@objc public var assignments: Set<RolloutAssignment> = Set()

public init(assignmentList: [RolloutAssignment]) {
for assignment in assignmentList {
assignments.insert(assignment)
}
super.init()
}
}
13 changes: 13 additions & 0 deletions FirebaseRemoteConfig/Interop/RolloutsStateSubscriber.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// File.swift
//
//
// Created by Themis Wang on 2023-11-16.
//

import Foundation

@objc(FIRRolloutsStateSubscriber)
public protocol RolloutsStateSubscriber {
func onRolloutsStateChanged(_ rolloutsState: RolloutsState)
}
9 changes: 9 additions & 0 deletions FirebaseRemoteConfig/Sources/FIRRemoteConfig.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#import "FirebaseRemoteConfig/Sources/RCNDevice.h"
#import "FirebaseRemoteConfig/Sources/RCNPersonalization.h"

@import FirebaseRemoteConfigInterop;

/// Remote Config Error Domain.
/// TODO: Rename according to obj-c style for constants.
NSString *const FIRRemoteConfigErrorDomain = @"com.google.remoteconfig.ErrorDomain";
Expand Down Expand Up @@ -73,6 +75,7 @@ @implementation FIRRemoteConfig {
dispatch_queue_t _queue;
NSString *_appName;
NSMutableArray *_listeners;
NSMutableArray *_subscribers;
}

static NSMutableDictionary<NSString *, NSMutableDictionary<NSString *, FIRRemoteConfig *> *>
Expand Down Expand Up @@ -176,6 +179,8 @@ - (instancetype)initWithAppName:(NSString *)appName

[_settings loadConfigFromMetadataTable];

_subscribers = [[NSMutableArray alloc] init];

if (analytics) {
_listeners = [[NSMutableArray alloc] init];
RCNPersonalization *personalization =
Expand Down Expand Up @@ -613,4 +618,8 @@ - (FIRConfigUpdateListenerRegistration *)addOnConfigUpdateListener:
return [self->_configRealtime addConfigUpdateListener:listener];
}

- (void)addRemoteConfigInteropSubscriber:(id<FIRRolloutsStateSubscriber>)subscriber {
[self->_subscribers addObject:subscriber];
}

@end
3 changes: 2 additions & 1 deletion FirebaseRemoteConfig/Sources/FIRRemoteConfigComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import <Foundation/Foundation.h>

#import "FirebaseCore/Extension/FirebaseCoreInternal.h"
@import FirebaseRemoteConfigInterop;

@class FIRApp;
@class FIRRemoteConfig;
Expand All @@ -25,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN

/// Provides and creates instances of Remote Config based on the namespace provided. Used in the
/// interop registration process to keep track of RC instances for each `FIRApp` instance.
@protocol FIRRemoteConfigProvider
@protocol FIRRemoteConfigProvider <FIRRemoteConfigInterop>

/// Cached instances of Remote Config objects.
@property(nonatomic, strong) NSMutableDictionary<NSString *, FIRRemoteConfig *> *instances;
Expand Down
8 changes: 8 additions & 0 deletions FirebaseRemoteConfig/Sources/FIRRemoteConfigComponent.m
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ - (FIRRemoteConfig *)remoteConfigForNamespace:(NSString *)remoteConfigNamespace
FIRApp *app = self.app;
id<FIRAnalyticsInterop> analytics =
app.isDefaultApp ? FIR_COMPONENT(FIRAnalyticsInterop, app.container) : nil;

instance = [[FIRRemoteConfig alloc] initWithAppName:app.name
FIROptions:app.options
namespace:remoteConfigNamespace
Expand Down Expand Up @@ -95,6 +96,7 @@ + (void)load {
+ (NSArray<FIRComponent *> *)componentsToRegister {
FIRDependency *analyticsDep = [FIRDependency dependencyWithProtocol:@protocol(FIRAnalyticsInterop)
isRequired:NO];

FIRComponent *rcProvider = [FIRComponent
componentWithProtocol:@protocol(FIRRemoteConfigProvider)
instantiationTiming:FIRInstantiationTimingAlwaysEager
Expand All @@ -107,4 +109,10 @@ + (void)load {
return @[ rcProvider ];
}

- (void)registerRolloutsStateSubscriber:(nonnull NSString *)nameSpace
subscriber:(nullable id<FIRRolloutsStateSubscriber>)subscriber {
// adding the registered subscriber reference to the namespace instance
[self.instances[nameSpace] addRemoteConfigInteropSubscriber:subscriber];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
@class RCNConfigDBManager;
@class RCNConfigFetch;
@class RCNConfigRealtime;

@protocol FIRRemoteConfigComponentDelegate;
@protocol FIRAnalyticsInterop;

NS_ASSUME_NONNULL_BEGIN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import <Foundation/Foundation.h>

@class FIRApp;
@protocol FIRRolloutsStateSubscriber;

/// The Firebase Remote Config service default namespace, to be used if the API method does not
/// specify a different namespace. Use the default namespace if configuring from the Google Firebase
Expand Down Expand Up @@ -150,6 +151,8 @@ NS_SWIFT_NAME(RemoteConfigValue)
@property(nonatomic, readonly, nullable) id JSONValue NS_SWIFT_NAME(jsonValue);
/// Identifies the source of the fetched value.
@property(nonatomic, readonly) FIRRemoteConfigSource source;

@property(nonatomic, readonly, nonnull) NSMutableArray<id<FIRRolloutsStateSubscriber>> *subscribers;
@end

#pragma mark - FIRRemoteConfigSettings
Expand Down Expand Up @@ -357,4 +360,5 @@ typedef void (^FIRRemoteConfigUpdateCompletion)(FIRRemoteConfigUpdate *_Nullable
(FIRRemoteConfigUpdateCompletion _Nonnull)listener
NS_SWIFT_NAME(addOnConfigUpdateListener(remoteConfigUpdateCompletion:));

- (void)addRemoteConfigInteropSubscriber:(nonnull id<FIRRolloutsStateSubscriber>)subscriber;
@end
25 changes: 20 additions & 5 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -491,11 +491,16 @@ let package = Package(
),
.target(
name: "FirebaseCrashlytics",
dependencies: ["FirebaseCore", "FirebaseInstallations", "FirebaseSessions",
.product(name: "GoogleDataTransport", package: "GoogleDataTransport"),
.product(name: "GULEnvironment", package: "GoogleUtilities"),
.product(name: "FBLPromises", package: "Promises"),
.product(name: "nanopb", package: "nanopb")],
dependencies: [
"FirebaseCore",
"FirebaseInstallations",
"FirebaseSessions",
"FirebaseRemoteConfigInterop",
.product(name: "GoogleDataTransport", package: "GoogleDataTransport"),
.product(name: "GULEnvironment", package: "GoogleUtilities"),
.product(name: "FBLPromises", package: "Promises"),
.product(name: "nanopb", package: "nanopb"),
],
path: "Crashlytics",
exclude: [
"run",
Expand Down Expand Up @@ -957,6 +962,7 @@ let package = Package(
"FirebaseCore",
"FirebaseABTesting",
"FirebaseInstallations",
"FirebaseRemoteConfigInterop",
.product(name: "GULNSData", package: "GoogleUtilities"),
],
path: "FirebaseRemoteConfig/Sources",
Expand Down Expand Up @@ -1028,6 +1034,15 @@ let package = Package(
.headerSearchPath("../../../"),
]
),
// Internal headers only for consuming from other SDK.
.target(
name: "FirebaseRemoteConfigInterop",
path: "FirebaseRemoteConfig/Interop",
publicHeadersPath: ".",
cSettings: [
.headerSearchPath("../../"),
]
),

// MARK: - Firebase Sessions

Expand Down

0 comments on commit d40694f

Please sign in to comment.