Skip to content
This repository was archived by the owner on Oct 29, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
67fb5ce
Removed the guides link
bwoskow-ld Feb 3, 2021
b6a113c
V4.0 (#68)
torchhound Apr 1, 2021
a193441
merge from public after release
LaunchDarklyCI Apr 1, 2021
510e581
Update iOS SDK dependency to fix Throttler behavior (#69)
torchhound Apr 7, 2021
0afc773
merge from public after release
LaunchDarklyCI Apr 7, 2021
9df202f
V4.1.0 (#72)
torchhound Apr 14, 2021
17e2d75
merge from public after release
LaunchDarklyCI Apr 14, 2021
35b61e1
Fixed jsonVariationDetail parsing on Android and fixed a typo in json…
torchhound Apr 16, 2021
fceade3
Merge branch 'master' of github.com:launchdarkly/react-native-client-sdk
bwoskow-ld Apr 23, 2021
82ba5fe
Releasing version 4.0.2
bwoskow-ld Apr 23, 2021
5489162
Merge branch 'v4.0.x-squashed' of github.com:launchdarkly/react-nativ…
bwoskow-ld Apr 23, 2021
ccc28c3
Merge branch 'master' of github.com:launchdarkly/react-native-client-sdk
bwoskow-ld Apr 24, 2021
c4a2891
Merge branch 'master' of github.com:launchdarkly/react-native-client-sdk
bwoskow-ld Apr 24, 2021
cae667b
Removes Typescript enums and replaces them with types that extend str…
torchhound Apr 28, 2021
f975de3
Releasing version 4.0.3
bwoskow-ld Apr 28, 2021
881c2fb
Merge branch 'v4.0.x-squashed'
bwoskow-ld Apr 28, 2021
b23e1c0
Merge branch 'master' of github.com:launchdarkly/react-native-client-…
bwoskow-ld Apr 28, 2021
c261c78
Merge branch 'master' of github.com:launchdarkly/react-native-client-sdk
bwoskow-ld Apr 28, 2021
5ad0499
Multi Environment (#65)
torchhound May 11, 2021
4ca1a1f
Add secondary user attribute (#76)
torchhound May 11, 2021
4a9530e
Merge branch 'master' of github.com:launchdarkly/react-native-client-sdk
bwoskow-ld May 11, 2021
81ae48d
Fix multi environment on restwrapper (#77)
torchhound May 19, 2021
0029ba5
merge from public after release
LaunchDarklyCI May 19, 2021
83640b7
[ch109800] Await Android client initialization. (#78)
gwhelanLD May 28, 2021
2668c2a
Update iOS method signature to match implementation (#79)
bwoskow-ld Jun 1, 2021
9703765
Merge remote-tracking branch 'public/master'
gwhelanLD Jun 1, 2021
b1a94ca
merge from public after release
LaunchDarklyCI Jun 1, 2021
8399a02
Releasing version 4.0.4
bwoskow-ld Jun 2, 2021
14c3993
Merge tag '4.0.4'
bwoskow-ld Jun 2, 2021
4d003c0
[ch110474] Fixes for undeclared variables and other callback issues. …
gwhelanLD Jun 15, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to the LaunchDarkly React Native SDK will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org).

## [4.0.4] - 2021-06-02
### Fixed:
- iOS: Fixed an issue where an exception was thrown when calling `LDClient.configure` with an optional `timeout` ([#80](https://github.com/launchdarkly/react-native-client-sdk/issues/80)).

## [4.2.1] - 2021-06-01
### Fixed:
- iOS: Fixed an issue where an exception was thrown when calling `LDClient.configure` with an optional `timeout` ([#80](https://github.com/launchdarkly/react-native-client-sdk/issues/80)).
Expand All @@ -10,15 +14,13 @@ All notable changes to the LaunchDarkly React Native SDK will be documented in t
- Android: Fixed an issue where the promise for `LDClient.configure` could be resolved before the client had finished initializing when not providing the optional `timeout` parameter.
- Android: Fixed an issue where `LDClient.allFlags` would reject the promise when the client was configured but not yet initialized, rather than resolving with any cached flags.


## [4.2.0] - 2021-05-19
### Added:
- `LDUser` now has an optional `secondary` attribute to match other LaunchDarkly SDKs. For more on the behavior of this attribute see [the documentation on targeting users](https://docs.launchdarkly.com/home/managing-flags/targeting-users).
- Support for multiple LaunchDarkly projects or environments. Each set of feature flags associated with a mobile key is called an environment. ([#10](https://github.com/launchdarkly/react-native-client-sdk/issues/10))
- `secondaryMobileKeys` is now a config option which allows a mapping of names to the SDK keys for each additional environment. `mobileKey` is still required, and represents the primary environment.
- Many methods including variations, track, and listeners now support an optional `environment` parameter to evaluate the method against the given `environment`.


## [4.1.2] - 2021-04-28
### Fixed:
- The `LDEvaluationReasonErrorKind`, `LDEvaluationReasonKind`, `LDConnectionMode`, and `LDFailureReason` enum TypeScript types were undefined when evaluated at runtime due to being defined in an ambient context. This was also fixed in SDK version 4.0.3 with React Native 0.63 compatibility.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -902,11 +902,13 @@ private String envConcat(String environment, String identifier) {

@ReactMethod
public void registerFeatureFlagListener(final String flagKey, final String environment) {
FeatureFlagChangeListener listener = new FeatureFlagChangeListener() {
final String multiListenerId = envConcat(environment, flagKey);
final FeatureFlagChangeListener listener = new FeatureFlagChangeListener() {
@Override
public void onFeatureFlagChange(String flagKey) {
WritableMap result = Arguments.createMap();
result.putString("flagKey", envConcat(environment, flagKey));
result.putString("flagKey", flagKey);
result.putString("listenerId", multiListenerId);

getReactApplicationContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
Expand All @@ -924,10 +926,11 @@ public void onFeatureFlagChange(String flagKey) {

@ReactMethod
public void unregisterFeatureFlagListener(String flagKey, String environment) {
String multiListenerId = envConcat(environment, flagKey);
try {
if (listeners.containsKey(flagKey)) {
LDClient.getForMobileKey(environment).unregisterFeatureFlagListener(flagKey, listeners.get(flagKey));
listeners.remove(flagKey);
if (listeners.containsKey(multiListenerId)) {
LDClient.getForMobileKey(environment).unregisterFeatureFlagListener(flagKey, listeners.get(multiListenerId));
listeners.remove(multiListenerId);
}
} catch (Exception e) {
Timber.w(e);
Expand All @@ -936,12 +939,13 @@ public void unregisterFeatureFlagListener(String flagKey, String environment) {

@ReactMethod
public void registerCurrentConnectionModeListener(final String listenerId, final String environment) {
final String multiListenerId = envConcat(environment, listenerId);
LDStatusListener listener = new LDStatusListener() {
@Override
public void onConnectionModeChanged(ConnectionInformation connectionInfo) {
WritableMap result = Arguments.createMap();
result.putString("connectionMode", gson.toJson(connectionInfo));
result.putString("listenerId", envConcat(environment, listenerId));
result.putString("listenerId", multiListenerId);

getReactApplicationContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
Expand All @@ -954,7 +958,7 @@ public void onInternalFailure(LDFailure ldFailure) {}

try {
LDClient.getForMobileKey(environment).registerStatusListener(listener);
connectionModeListeners.put(listenerId, listener);
connectionModeListeners.put(multiListenerId, listener);
} catch (Exception e) {
Timber.w(e);
}
Expand All @@ -963,9 +967,10 @@ public void onInternalFailure(LDFailure ldFailure) {}
@ReactMethod
public void unregisterCurrentConnectionModeListener(String listenerId, String environment) {
try {
if (connectionModeListeners.containsKey(listenerId)) {
LDClient.getForMobileKey(environment).unregisterStatusListener(connectionModeListeners.get(listenerId));
connectionModeListeners.remove(listenerId);
String multiListenerId = envConcat(environment, listenerId);
if (connectionModeListeners.containsKey(multiListenerId)) {
LDClient.getForMobileKey(environment).unregisterStatusListener(connectionModeListeners.get(multiListenerId));
connectionModeListeners.remove(multiListenerId);
}
} catch (Exception e) {
Timber.w(e);
Expand All @@ -974,12 +979,13 @@ public void unregisterCurrentConnectionModeListener(String listenerId, String en

@ReactMethod
public void registerAllFlagsListener(final String listenerId, final String environment) {
final String multiListenerId = envConcat(environment, listenerId);
LDAllFlagsListener listener = new LDAllFlagsListener() {
@Override
public void onChange(List<String> flagKeys) {
WritableMap result = Arguments.createMap();
result.putString("flagKeys", gson.toJson(flagKeys));
result.putString("listenerId", envConcat(environment, listenerId));
result.putString("listenerId", multiListenerId);

getReactApplicationContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
Expand All @@ -989,7 +995,7 @@ public void onChange(List<String> flagKeys) {

try {
LDClient.getForMobileKey(environment).registerAllFlagsListener(listener);
allFlagsListeners.put(listenerId, listener);
allFlagsListeners.put(multiListenerId, listener);
} catch (Exception e) {
Timber.w(e);
}
Expand All @@ -998,9 +1004,10 @@ public void onChange(List<String> flagKeys) {
@ReactMethod
public void unregisterAllFlagsListener(String listenerId, String environment) {
try {
if (allFlagsListeners.containsKey(listenerId)) {
LDClient.getForMobileKey(environment).unregisterAllFlagsListener(allFlagsListeners.get(listenerId));
allFlagsListeners.remove(listenerId);
String multiListenerId = envConcat(environment, listenerId);
if (allFlagsListeners.containsKey(multiListenerId)) {
LDClient.getForMobileKey(environment).unregisterAllFlagsListener(allFlagsListeners.get(multiListenerId));
allFlagsListeners.remove(multiListenerId);
}
} catch (Exception e) {
Timber.w(e);
Expand Down
25 changes: 11 additions & 14 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,9 @@ export default class LDClient {

_flagUpdateListener(changedFlag) {
const flagKey = changedFlag.flagKey;
if (this.flagListeners.hasOwnProperty(flagKey)) {
let listeners = this.flagListeners[flagKey];
const listenerId = changedFlag.listenerId;
if (this.flagListeners.hasOwnProperty(listenerId)) {
let listeners = this.flagListeners[listenerId];
for (const listener of listeners) {
listener(flagKey);
}
Expand All @@ -238,20 +239,16 @@ export default class LDClient {
_allFlagsUpdateListener(changedFlags) {
const flagKeys = changedFlags.flagKeys;
const listenerId = changedFlags.listenerId;
for (const [key, value] of Object.entries(this.allFlagsListeners)) {
if (key == listenerId) {
key(flagKeys);
}
if (this.allFlagsListeners.hasOwnProperty(listenerId)) {
this.allFlagsListeners[listenerId](flagKeys);
}
}

_connectionModeUpdateListener(connectionStatus) {
const connectionMode = connectionStatus.connectionMode;
const listenerId = connectionStatus.listenerId;
for (const [key, value] of Object.entries(this.connectionModeListeners)) {
if (key == listenerId) {
key(connectionMode);
}
if (this.connectionModeListeners.hasOwnProperty(listenerId)) {
this.connectionModeListeners[listenerId](connectionMode);
}
}

Expand Down Expand Up @@ -296,15 +293,15 @@ export default class LDClient {
return;
}
const env = environment !== undefined ? environment : "default";
const multiListenerId = this._envConcat(env, flagKey);
const multiListenerId = this._envConcat(env, listenerId);

this.connectionModeListeners[multiListenerId] = callback;
LaunchdarklyReactNativeClient.registerCurrentConnectionModeListener(listenerId, env);
}

unregisterCurrentConnectionModeListener(listenerId, environment) {
const env = environment !== undefined ? environment : "default";
const multiListenerId = this._envConcat(env, flagKey);
const multiListenerId = this._envConcat(env, listenerId);
if (!this.connectionModeListeners.hasOwnProperty(multiListenerId)) {
return;
}
Expand All @@ -318,15 +315,15 @@ export default class LDClient {
return;
}
const env = environment !== undefined ? environment : "default";
const multiListenerId = this._envConcat(env, flagKey);
const multiListenerId = this._envConcat(env, listenerId);

this.allFlagsListeners[multiListenerId] = callback;
LaunchdarklyReactNativeClient.registerAllFlagsListener(listenerId, env);
}

unregisterAllFlagsListener(listenerId, environment) {
const env = environment !== undefined ? environment : "default";
const multiListenerId = this._envConcat(env, flagKey);
const multiListenerId = this._envConcat(env, listenerId);
if (!this.allFlagsListeners.hasOwnProperty(multiListenerId)) {
return;
}
Expand Down
49 changes: 18 additions & 31 deletions ios/LaunchdarklyReactNativeClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -541,43 +541,34 @@ class LaunchdarklyReactNativeClient: RCTEventEmitter {
}

@objc func registerFeatureFlagListener(_ flagKey: String, environment: String) -> Void {
let flagChangeOwner = flagKey as LDObserverOwner
if listenerKeys[flagKey] == nil {
listenerKeys[flagKey] = flagChangeOwner
} else {
return
}
LDClient.get(environment: environment)!.observe(keys: [flagKey], owner: flagChangeOwner, handler: { (changedFlags) in
if changedFlags[flagKey] != nil && self.bridge != nil {
self.sendEvent(withName: self.FLAG_PREFIX, body: ["flagKey": self.envConcat(environment: environment, identifier: flagKey)])
let multiListenerId = envConcat(environment: environment, identifier: flagKey)
let flagChangeOwner = multiListenerId as LDObserverOwner
listenerKeys[multiListenerId] = flagChangeOwner
LDClient.get(environment: environment)!.observe(key: flagKey, owner: flagChangeOwner, handler: { changedFlag in
if self.bridge != nil {
self.sendEvent(withName: self.FLAG_PREFIX, body: ["flagKey": changedFlag.key, "listenerId": multiListenerId])
}
})
}

private func unregisterListener(_ key: String, _ environment: String) -> Void {
let owner = key as LDObserverOwner
if listenerKeys[key] != nil {
listenerKeys.removeValue(forKey: key)
} else {
return
let multiListenerId = envConcat(environment: environment, identifier: key)
let owner = multiListenerId as LDObserverOwner
if listenerKeys.removeValue(forKey: multiListenerId) != nil {
LDClient.get(environment: environment)!.stopObserving(owner: owner)
}
LDClient.get(environment: environment)!.stopObserving(owner: owner)
}

@objc func unregisterFeatureFlagListener(_ flagKey: String, environment: String) -> Void {
unregisterListener(flagKey, environment)
}

@objc func registerCurrentConnectionModeListener(_ listenerId: String, environment: String) -> Void {
let currentConnectionModeOwner = listenerId as LDObserverOwner
if listenerKeys[listenerId] == nil {
listenerKeys.removeValue(forKey: listenerId)
} else {
return
}
LDClient.get(environment: environment)!.observeCurrentConnectionMode(owner: currentConnectionModeOwner, handler: { (connectionMode) in
let multiListenerId = envConcat(environment: environment, identifier: listenerId)
let currentConnectionModeOwner = multiListenerId as LDObserverOwner
LDClient.get(environment: environment)!.observeCurrentConnectionMode(owner: currentConnectionModeOwner, handler: { connectionMode in
if self.bridge != nil {
self.sendEvent(withName: self.CONNECTION_MODE_PREFIX, body: ["connectionMode": connectionMode, "listenerId": self.envConcat(environment: environment, identifier: listenerId)])
self.sendEvent(withName: self.CONNECTION_MODE_PREFIX, body: ["connectionMode": connectionMode, "listenerId": multiListenerId])
}
})
}
Expand All @@ -587,15 +578,11 @@ class LaunchdarklyReactNativeClient: RCTEventEmitter {
}

@objc func registerAllFlagsListener(_ listenerId: String, environment: String) -> Void {
let flagChangeOwner = listenerId as LDObserverOwner
if listenerKeys[listenerId] == nil {
listenerKeys[listenerId] = flagChangeOwner
} else {
return
}
LDClient.get(environment: environment)!.observeAll(owner: flagChangeOwner, handler: { (changedFlags) in
let multiListenerId = envConcat(environment: environment, identifier: listenerId)
let flagChangeOwner = multiListenerId as LDObserverOwner
LDClient.get(environment: environment)!.observeAll(owner: flagChangeOwner, handler: { changedFlags in
if self.bridge != nil {
self.sendEvent(withName: self.ALL_FLAGS_PREFIX, body: ["flagKeys": changedFlags.keys.description, "listenerId": self.envConcat(environment: environment, identifier: listenerId)])
self.sendEvent(withName: self.ALL_FLAGS_PREFIX, body: ["flagKeys": Array(changedFlags.keys), "listenerId": multiListenerId])
}
})
}
Expand Down