Skip to content

Commit 61bd0a7

Browse files
authored
Release 20.2.0 (#616)
* Types updates for FF enhancements * iOS update * Android update * Bump version * Update proxy
1 parent 17eaa0e commit 61bd0a7

File tree

11 files changed

+187
-44
lines changed

11 files changed

+187
-44
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# React Native Module Changelog
22

3+
## Version 20.2.0 - December 20, 2024
4+
Minor release that updates to the latest Airship SDKs and adds new Feature Flag APIs.
5+
6+
### Changes
7+
- Updated Android SDK to [18.6.0](https://github.com/urbanairship/android-library/releases/tag/18.6.0).
8+
- Updated iOS SDK to [18.14.1](https://github.com/urbanairship/ios-library/releases/tag/18.14.1).
9+
- Adds `Airship.featureFlagManager.resultCache` to cache a result that can be used when `Airship.featureFlagManager.flag` fails to resolve a result.
10+
311
## Version 20.1.0 - December 5, 2024
412
Minor release that updates the Android Airship SDK to 18.5.0 and iOS Airship SDK to 18.13.0
513

android/gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ Airship_minSdkVersion=21
33
Airship_targetSdkVersion=34
44
Airship_compileSdkVersion=34
55
Airship_ndkversion=26.1.10909125
6-
Airship_airshipProxyVersion=11.1.0
6+
Airship_airshipProxyVersion=11.2.1

android/src/main/java/com/urbanairship/reactnative/AirshipModule.kt

+27-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import com.urbanairship.android.framework.proxy.proxies.SuspendingPredicate
1919
import com.urbanairship.json.JsonMap
2020
import com.urbanairship.json.JsonSerializable
2121
import com.urbanairship.json.JsonValue
22+
import kotlin.time.Duration.Companion.milliseconds
2223
import kotlinx.coroutines.*
2324
import kotlinx.coroutines.flow.filter
2425
import java.util.UUID
@@ -698,21 +699,42 @@ class AirshipModule internal constructor(val context: ReactApplicationContext) :
698699
}
699700

700701
@ReactMethod
701-
override fun featureFlagManagerFlag(flagName: String?, promise: Promise) {
702+
override fun featureFlagManagerFlag(flagName: String, useResultCache: Boolean, promise: Promise) {
702703
promise.resolveSuspending(scope) {
703-
requireNotNull(flagName)
704-
proxy.featureFlagManager.flag(flagName)
704+
proxy.featureFlagManager.flag(flagName, useResultCache)
705705
}
706706
}
707707

708708
@ReactMethod
709-
override fun featureFlagManagerTrackInteraction(flag: ReadableMap?, promise: Promise) {
709+
override fun featureFlagManagerTrackInteraction(flag: ReadableMap, promise: Promise) {
710710
promise.resolveResult {
711-
val parsedFlag = FeatureFlagProxy(Utils.convertMap(requireNotNull(flag)).toJsonValue())
711+
val parsedFlag = FeatureFlagProxy(Utils.convertMap(flag).toJsonValue())
712712
proxy.featureFlagManager.trackInteraction(parsedFlag)
713713
}
714714
}
715715

716+
@ReactMethod
717+
override fun featureFlagManagerResultCacheGetFlag(flagName: String, promise: Promise) {
718+
promise.resolveSuspending(scope) {
719+
proxy.featureFlagManager.resultCache.flag(flagName)
720+
}
721+
}
722+
723+
@ReactMethod
724+
override fun featureFlagManagerResultCacheSetFlag(flag: ReadableMap, ttl: Double, promise: Promise) {
725+
promise.resolveSuspending(scope) {
726+
val parsedFlag = FeatureFlagProxy(Utils.convertMap(flag).toJsonValue())
727+
proxy.featureFlagManager.resultCache.cache(parsedFlag, ttl.milliseconds)
728+
}
729+
}
730+
731+
@ReactMethod
732+
override fun featureFlagManagerResultCacheRemoveFlag(flagName: String, promise: Promise) {
733+
promise.resolveSuspending(scope) {
734+
proxy.featureFlagManager.resultCache.removeCachedFlag(flagName)
735+
}
736+
}
737+
716738
@ReactMethod
717739
override fun liveActivityListAll(promise: Promise) {
718740
promise.resolveResult {

android/src/oldarch/java/com/urbanairship/reactnative/AirshipSpec.kt

+14-2
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,23 @@ abstract class AirshipSpec internal constructor(context: ReactApplicationContext
407407

408408
@ReactMethod
409409
@com.facebook.proguard.annotations.DoNotStrip
410-
abstract fun featureFlagManagerFlag(flagName: String?, promise: Promise)
410+
abstract fun featureFlagManagerFlag(flagName: String, useResultCache: Boolean, promise: Promise)
411411

412412
@ReactMethod
413413
@com.facebook.proguard.annotations.DoNotStrip
414-
abstract fun featureFlagManagerTrackInteraction(flag: ReadableMap?, promise: Promise)
414+
abstract fun featureFlagManagerTrackInteraction(flag: ReadableMap, promise: Promise)
415+
416+
@ReactMethod
417+
@com.facebook.proguard.annotations.DoNotStrip
418+
abstract fun featureFlagManagerResultCacheGetFlag(flagName: String, promise: Promise)
419+
420+
@ReactMethod
421+
@com.facebook.proguard.annotations.DoNotStrip
422+
abstract fun featureFlagManagerResultCacheSetFlag(flag: ReadableMap, ttl: Double, promise: Promise)
423+
424+
@ReactMethod
425+
@com.facebook.proguard.annotations.DoNotStrip
426+
abstract fun featureFlagManagerResultCacheRemoveFlag(flagName: String, promise: Promise)
415427

416428
@ReactMethod
417429
@com.facebook.proguard.annotations.DoNotStrip

example/ios/Podfile.lock

+23-23
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
PODS:
2-
- Airship (18.13.0):
3-
- Airship/Automation (= 18.13.0)
4-
- Airship/Basement (= 18.13.0)
5-
- Airship/Core (= 18.13.0)
6-
- Airship/FeatureFlags (= 18.13.0)
7-
- Airship/MessageCenter (= 18.13.0)
8-
- Airship/PreferenceCenter (= 18.13.0)
9-
- Airship/Automation (18.13.0):
2+
- Airship (18.14.1):
3+
- Airship/Automation (= 18.14.1)
4+
- Airship/Basement (= 18.14.1)
5+
- Airship/Core (= 18.14.1)
6+
- Airship/FeatureFlags (= 18.14.1)
7+
- Airship/MessageCenter (= 18.14.1)
8+
- Airship/PreferenceCenter (= 18.14.1)
9+
- Airship/Automation (18.14.1):
1010
- Airship/Core
11-
- Airship/Basement (18.13.0)
12-
- Airship/Core (18.13.0):
11+
- Airship/Basement (18.14.1)
12+
- Airship/Core (18.14.1):
1313
- Airship/Basement
14-
- Airship/FeatureFlags (18.13.0):
14+
- Airship/FeatureFlags (18.14.1):
1515
- Airship/Core
16-
- Airship/MessageCenter (18.13.0):
16+
- Airship/MessageCenter (18.14.1):
1717
- Airship/Core
18-
- Airship/PreferenceCenter (18.13.0):
18+
- Airship/PreferenceCenter (18.14.1):
1919
- Airship/Core
20-
- AirshipFrameworkProxy (11.1.0):
21-
- Airship (= 18.13.0)
22-
- AirshipServiceExtension (18.13.0)
20+
- AirshipFrameworkProxy (11.2.1):
21+
- Airship (= 18.14.1)
22+
- AirshipServiceExtension (18.14.0)
2323
- boost (1.83.0)
2424
- DoubleConversion (1.1.6)
2525
- FBLazyVector (0.73.4)
@@ -907,8 +907,8 @@ PODS:
907907
- React-Mapbuffer (0.73.4):
908908
- glog
909909
- React-debug
910-
- react-native-airship (20.1.0):
911-
- AirshipFrameworkProxy (= 11.1.0)
910+
- react-native-airship (20.2.0):
911+
- AirshipFrameworkProxy (= 11.2.1)
912912
- glog
913913
- RCT-Folly (= 2022.05.16.00)
914914
- React-Core
@@ -1279,9 +1279,9 @@ EXTERNAL SOURCES:
12791279
:path: "../node_modules/react-native/ReactCommon/yoga"
12801280

12811281
SPEC CHECKSUMS:
1282-
Airship: bfe90d95c2b2bd0ea9ed5248a1337f124fe8abfe
1283-
AirshipFrameworkProxy: 15e4589484430c292aadc7e9f9878d83b7c0fd25
1284-
AirshipServiceExtension: aefb21acb70a7476279793d6e38be2bd612817d0
1282+
Airship: f293470bde4a4cbd23ac73dbda986629d9ad9fdb
1283+
AirshipFrameworkProxy: 9332b3f7871f054375653e72428fbcf4a3a9f849
1284+
AirshipServiceExtension: 1d6c2443724f6ea541eecb76ddbaab307809d561
12851285
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
12861286
DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953
12871287
FBLazyVector: 84f6edbe225f38aebd9deaf1540a4160b1f087d7
@@ -1311,7 +1311,7 @@ SPEC CHECKSUMS:
13111311
React-jsinspector: 9ac353eccf6ab54d1e0a33862ba91221d1e88460
13121312
React-logger: 0a57b68dd2aec7ff738195f081f0520724b35dab
13131313
React-Mapbuffer: 63913773ed7f96b814a2521e13e6d010282096ad
1314-
react-native-airship: adf4c86f2971ffe1f5f30b7c150d73e60725e009
1314+
react-native-airship: a4111a9d2ecb4b12bc021698917be8eeded34793
13151315
react-native-safe-area-context: b97eb6f9e3b7f437806c2ce5983f479f8eb5de4b
13161316
React-nativeconfig: d7af5bae6da70fa15ce44f045621cf99ed24087c
13171317
React-NativeModulesApple: 0123905d5699853ac68519607555a9a4f5c7b3ac
@@ -1342,4 +1342,4 @@ SPEC CHECKSUMS:
13421342

13431343
PODFILE CHECKSUM: 71939b1c0f451ff75f31df2f5e51d1c63f04150d
13441344

1345-
COCOAPODS: 1.16.2
1345+
COCOAPODS: 1.15.2

ios/AirshipReactNative.swift

+23-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public class AirshipReactNative: NSObject {
3939
AirshipProxy.shared
4040
}
4141

42-
public static let version: String = "20.1.0"
42+
public static let version: String = "20.2.0"
4343

4444
private let eventNotifier = EventNotifier()
4545

@@ -599,8 +599,8 @@ public extension AirshipReactNative {
599599
@objc
600600
public extension AirshipReactNative {
601601
@objc
602-
func featureFlagManagerFlag(flagName: String) async throws -> Any {
603-
let result = try await AirshipProxy.shared.featureFlagManager.flag(name: flagName)
602+
func featureFlagManagerFlag(flagName: String, useResultCache: Bool) async throws -> Any {
603+
let result = try await AirshipProxy.shared.featureFlagManager.flag(name: flagName, useResultCache: useResultCache)
604604
return try AirshipJSON.wrap(result).unWrap() as Any
605605
}
606606

@@ -609,6 +609,26 @@ public extension AirshipReactNative {
609609
let flag: FeatureFlagProxy = try AirshipJSON.wrap(flag).decode()
610610
try AirshipProxy.shared.featureFlagManager.trackInteraction(flag: flag)
611611
}
612+
613+
@objc
614+
func featureFlagManagerResultCacheGetFlag(name: String) async throws -> Any {
615+
let result = try await AirshipProxy.shared.featureFlagManager.resultCache.flag(name: name)
616+
return try AirshipJSON.wrap(result).unWrap() as Any
617+
}
618+
619+
@objc
620+
func featureFlagManagerResultCacheSetFlag(flag: Any, ttl: NSNumber) async throws {
621+
let flag: FeatureFlagProxy = try AirshipJSON.wrap(flag).decode()
622+
try await AirshipProxy.shared.featureFlagManager.resultCache.cache(
623+
flag: flag,
624+
ttl: TimeInterval(ttl.uint64Value/1000)
625+
)
626+
}
627+
628+
@objc
629+
func featureFlagManagerResultCacheRemoveFlag(name: String) async throws {
630+
try await AirshipProxy.shared.featureFlagManager.resultCache.removeCachedFlag(name: name)
631+
}
612632
}
613633

614634

ios/RTNAirship.mm

+38
Original file line numberDiff line numberDiff line change
@@ -783,15 +783,53 @@ + (BOOL)requiresMainQueueSetup {
783783

784784
RCT_REMAP_METHOD(featureFlagManagerFlag,
785785
featureFlagManagerFlag:(NSString *)flagName
786+
useResultCache:(BOOL)useResultCache
786787
featureFlagManagerFlag:(RCTPromiseResolveBlock)resolve
787788
reject:(RCTPromiseRejectBlock)reject) {
788789

789790
[AirshipReactNative.shared featureFlagManagerFlagWithFlagName:flagName
791+
useResultCache:useResultCache
790792
completionHandler:^(id result, NSError * _Nullable error) {
791793
[self handleResult:result error:error resolve:resolve reject:reject];
792794
}];
793795
}
794796

797+
RCT_REMAP_METHOD(featureFlagManagerResultCacheGetFlag,
798+
featureFlagManagerResultCacheGetFlag:(NSString *)flagName
799+
featureFlagManagerResultCacheGetFlag:(RCTPromiseResolveBlock)resolve
800+
reject:(RCTPromiseRejectBlock)reject) {
801+
802+
[AirshipReactNative.shared featureFlagManagerResultCacheGetFlagWithName:flagName
803+
completionHandler:^(id result, NSError * _Nullable error) {
804+
[self handleResult:result error:error resolve:resolve reject:reject];
805+
}];
806+
}
807+
808+
RCT_REMAP_METHOD(featureFlagManagerResultCacheSetFlag,
809+
featureFlagManagerResultCacheSetFlag:(NSDictionary *)flag
810+
ttl:(nonnull NSNumber *)ttl
811+
featureFlagManagerResultCacheGetFlag:(RCTPromiseResolveBlock)resolve
812+
reject:(RCTPromiseRejectBlock)reject) {
813+
814+
[AirshipReactNative.shared featureFlagManagerResultCacheSetFlagWithFlag:flag
815+
ttl:ttl
816+
completionHandler:^(NSError * _Nullable error) {
817+
[self handleResult:nil error:error resolve:resolve reject:reject];
818+
}];
819+
}
820+
821+
RCT_REMAP_METHOD(featureFlagManagerResultCacheRemoveFlag,
822+
featureFlagManagerResultCacheRemoveFlag:(NSString *)flagName
823+
featureFlagManagerResultCacheRemoveFlag:(RCTPromiseResolveBlock)resolve
824+
reject:(RCTPromiseRejectBlock)reject) {
825+
826+
[AirshipReactNative.shared featureFlagManagerResultCacheRemoveFlagWithName:flagName
827+
completionHandler:^(NSError * _Nullable error) {
828+
[self handleResult:nil error:error resolve:resolve reject:reject];
829+
}];
830+
}
831+
832+
795833
RCT_REMAP_METHOD(liveActivityListAll,
796834
liveActivityListAll:(RCTPromiseResolveBlock)resolve
797835
reject:(RCTPromiseRejectBlock)reject) {

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ua/react-native-airship",
3-
"version": "20.1.0",
3+
"version": "20.2.0",
44
"description": "Airship plugin for React Native apps.",
55
"main": "lib/commonjs/index",
66
"module": "lib/module/index",

react-native-airship.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ Pod::Spec.new do |s|
2222
s.dependency "React-Core"
2323
end
2424

25-
s.dependency "AirshipFrameworkProxy", "11.1.0"
25+
s.dependency "AirshipFrameworkProxy", "11.2.1"
2626

2727
end

src/AirshipFeatureFlagManager.ts

+47-7
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,30 @@ import { FeatureFlag } from './types';
44
* Airship feature flag manager.
55
*/
66
export class AirshipFeatureFlagManager {
7-
constructor(private readonly module: any) {}
7+
/**
8+
* Feature flag cache.
9+
*/
10+
public readonly resultCache: AirshipFeatureFlagResultCache;
811

9-
/**
12+
constructor(private readonly module: any) {
13+
this.resultCache = new AirshipFeatureFlagResultCache(module);
14+
}
15+
16+
/**
1017
* Retrieve a given flag's status and associated data by its name.
1118
* @param {string} flagName The flag name
12-
* @return {Promise<FeatureFlag>} A promise resolving to the feature flag
13-
* requested.
19+
* @param {boolean} useResultCache If the response should use result cache or not.
20+
* @return {Promise<FeatureFlag>} A promise resolving to the feature flag requested.
1421
* @throws {Error} when failed to fetch
1522
*/
1623
public flag(
17-
flagName: string
24+
flagName: string,
25+
useResultCache: boolean = true
1826
): Promise<FeatureFlag> {
19-
return this.module.featureFlagManagerFlag(flagName);
27+
return this.module.featureFlagManagerFlag(flagName, useResultCache);
2028
}
2129

22-
/**
30+
/**
2331
* Tracks a feature flag interaction event.
2432
* @param {FeatureFlag} flag The flag
2533
* @return {Promise<Void>} A promise with an empty result.
@@ -29,3 +37,35 @@ export class AirshipFeatureFlagManager {
2937
return this.module.featureFlagManagerTrackInteraction(flag);
3038
}
3139
}
40+
41+
export class AirshipFeatureFlagResultCache {
42+
constructor(private readonly module: any) {}
43+
44+
/**
45+
* Retrieve a flag from the cache.
46+
* @param {string} flagName The flag name
47+
* @return {Promise<FeatureFlag>} A promise resolving to the feature flag.
48+
*/
49+
public flag(flagName: string): Promise<FeatureFlag> {
50+
return this.module.featureFlagManagerResultCacheGetFlag(flagName);
51+
}
52+
53+
/**
54+
* Caches a feature flag.
55+
* @param {FeatureFlag} flag The flag
56+
* @param {FeatureFlag} ttl Cache TTL in milliseconds.
57+
* @return {Promise<Void>} A promise with an empty result.
58+
*/
59+
public cache(flag: FeatureFlag, ttl: number): Promise<void> {
60+
return this.module.featureFlagManagerResultCacheSetFlag(flag, ttl);
61+
}
62+
63+
/**
64+
* Clears the cache for a given flag.
65+
* @param {FeatureFlag} flagName The flag name
66+
* @return {Promise<Void>} A promise with an empty result.
67+
*/
68+
public removeCachedFlag(flagName: string): Promise<void> {
69+
return this.module.featureFlagManagerResultCacheRemoveFlag(flagName);
70+
}
71+
}

src/NativeRTNAirship.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,11 @@ export interface Spec extends TurboModule {
113113
localeClearLocaleOverride(): Promise<void>;
114114

115115
// Feature Flag Manager
116-
featureFlagManagerFlag(flagName: string):Promise<Object>;
116+
featureFlagManagerFlag(flagName: string, userResultCache: boolean):Promise<Object>;
117117
featureFlagManagerTrackInteraction(flag: Object): Promise<void>;
118+
featureFlagManagerResultCacheGetFlag(flagName: string): Promise<Object>;
119+
featureFlagManagerResultCacheSetFlag(flag: Object, ttl: number): Promise<void>;
120+
featureFlagManagerResultCacheRemoveFlag(flagName: string): Promise<void>;
118121

119122
// Live Activity
120123
liveActivityListAll(): Promise<Object>;

0 commit comments

Comments
 (0)