Skip to content

Commit

Permalink
Merge pull request #526 from urbanairship/release-16.1.0
Browse files Browse the repository at this point in the history
WIP release 16.1.0
  • Loading branch information
Ulrico972 authored Sep 11, 2023
2 parents a6a580c + e81a9bf commit cd6f0d1
Show file tree
Hide file tree
Showing 14 changed files with 139 additions and 29 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
# React Native Module Changelog

## Version 16.1.0 - September 11, 2023
Minor release that updates the iOS SDK to 17.3.0 and Android SDK to 17.2.1. Also adds support for Airship Feature Flag feature and for Channel Tag Editor.

### Changes
- Updated iOS SDK to 17.3.0
- Updated Android SDK to 17.2.1
- Added support for Airship Feature Flag feature
- Added a new method `Airship.channel.editTags()`

## Version 16.0.1 - July 21, 2023
Patch release that updates the iOS and Android Airship SDK to 17.0.3.
Expand Down
4 changes: 2 additions & 2 deletions android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Airship_targetSdkVersion=31
Airship_compileSdkVersion=31
Airship_ndkversion=21.4.7075529

Airship_airshipProxyVersion=4.1.0
Airship_airshipProxyVersion=4.2.0

# workaround for now, used for HMS
Airship_airshipVersion=17.2.0
Airship_airshipVersion=17.2.1

Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ import com.urbanairship.android.framework.proxy.proxies.SuspendingPredicate
import com.urbanairship.json.JsonMap
import com.urbanairship.json.JsonSerializable
import com.urbanairship.json.JsonValue
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch
import java.util.UUID

class AirshipModule internal constructor(val context: ReactApplicationContext) : AirshipSpec(context) {
Expand All @@ -27,6 +25,8 @@ class AirshipModule internal constructor(val context: ReactApplicationContext) :
private var isOverrideForegroundDisplayEnabled: Boolean = false
private val foregroundDisplayRequestMap = mutableMapOf<String, CompletableDeferred<Boolean>>()

private val scope: CoroutineScope = CoroutineScope(Dispatchers.Main) + SupervisorJob()

private val foregroundDisplayPredicate = object : SuspendingPredicate<Map<String, Any>> {
override suspend fun apply(value: Map<String, Any>): Boolean {
val deferred = CompletableDeferred<Boolean>()
Expand All @@ -53,7 +53,7 @@ class AirshipModule internal constructor(val context: ReactApplicationContext) :
override fun initialize() {
super.initialize()

MainScope().launch {
scope.launch {
// Background events will create a headless JS task in ReactAutopilot since
// initialized wont be called until we have a JS task.
EventEmitter.shared().pendingEventListener
Expand All @@ -79,6 +79,11 @@ class AirshipModule internal constructor(val context: ReactApplicationContext) :
ProxyLogger.debug("AirshipModule initialized")
}

override fun invalidate() {
super.invalidate()
scope.cancel()
}

@ReactMethod
override fun takeOff(config: ReadableMap?, promise: Promise) {
promise.resolveResult {
Expand Down Expand Up @@ -628,6 +633,20 @@ class AirshipModule internal constructor(val context: ReactApplicationContext) :
}
}

override fun featureFlagManagerFlag(flagName: String?, promise: Promise) {
promise.resolveDeferred { callback ->
scope.launch {
try {
requireNotNull(flagName)
val flag = proxy.featureFlagManager.flag(flagName)
callback(flag, null)
} catch (e: Exception) {
callback(null, e)
}
}
}
}

private fun notifyPending() {
if (context.hasActiveReactInstance()) {
val appEventEmitter = context.getJSModule(RCTNativeAppEventEmitter::class.java)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,10 @@ abstract class AirshipSpec internal constructor(context: ReactApplicationContext
@ReactMethod
@com.facebook.proguard.annotations.DoNotStrip
abstract fun pushIosGetAuthorizedNotificationStatus(promise: Promise)

@ReactMethod
@com.facebook.proguard.annotations.DoNotStrip
abstract fun featureFlagManagerFlag(flagName: String?, promise: Promise)
}


40 changes: 20 additions & 20 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
PODS:
- Airship (17.2.2):
- Airship/Automation (= 17.2.2)
- Airship/Basement (= 17.2.2)
- Airship/Core (= 17.2.2)
- Airship/FeatureFlags (= 17.2.2)
- Airship/MessageCenter (= 17.2.2)
- Airship/PreferenceCenter (= 17.2.2)
- Airship/Automation (17.2.2):
- Airship (17.3.0):
- Airship/Automation (= 17.3.0)
- Airship/Basement (= 17.3.0)
- Airship/Core (= 17.3.0)
- Airship/FeatureFlags (= 17.3.0)
- Airship/MessageCenter (= 17.3.0)
- Airship/PreferenceCenter (= 17.3.0)
- Airship/Automation (17.3.0):
- Airship/Core
- Airship/Basement (17.2.2)
- Airship/Core (17.2.2):
- Airship/Basement (17.3.0)
- Airship/Core (17.3.0):
- Airship/Basement
- Airship/FeatureFlags (17.2.2):
- Airship/FeatureFlags (17.3.0):
- Airship/Core
- Airship/MessageCenter (17.2.2):
- Airship/MessageCenter (17.3.0):
- Airship/Core
- Airship/PreferenceCenter (17.2.2):
- Airship/PreferenceCenter (17.3.0):
- Airship/Core
- AirshipFrameworkProxy (4.1.0):
- Airship (= 17.2.2)
- AirshipFrameworkProxy (4.2.0):
- Airship (= 17.3.0)
- boost (1.76.0)
- CocoaAsyncSocket (7.6.5)
- DoubleConversion (1.1.6)
Expand Down Expand Up @@ -317,8 +317,8 @@ PODS:
- React-jsinspector (0.71.1)
- React-logger (0.71.1):
- glog
- react-native-airship (16.0.1):
- AirshipFrameworkProxy (= 4.1.0)
- react-native-airship (16.1.0):
- AirshipFrameworkProxy (= 4.2.0)
- React-Core
- react-native-safe-area-context (4.5.0):
- RCT-Folly
Expand Down Expand Up @@ -581,8 +581,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"

SPEC CHECKSUMS:
Airship: f5a106a6daa01ba46ae2f519b1b3d4595e7e0972
AirshipFrameworkProxy: b9822473fef17241cf54508770fdf198f1af9405
Airship: 73ee3648eb6864be959246427e084b60536ae0dc
AirshipFrameworkProxy: a6e3e4357e6d65dd33c5bec39219a859762709c1
boost: 57d2868c099736d80fcd648bf211b4431e51a558
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
Expand Down Expand Up @@ -616,7 +616,7 @@ SPEC CHECKSUMS:
React-jsiexecutor: 60cf272aababc5212410e4249d17cea14fc36caa
React-jsinspector: ff56004b0c974b688a6548c156d5830ad751ae07
React-logger: 60a0b5f8bed667ecf9e24fecca1f30d125de6d75
react-native-airship: cb708f7d12b3fcea474119f2eb694d686aac54f6
react-native-airship: a254a0fb81c4ebe6dccc95c7644b5b84c90adc65
react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc
React-perflogger: ec8eef2a8f03ecfa6361c2c5fb9197ef4a29cc85
React-RCTActionSheet: a0c023b86cf4c862fa9c4eb0f6f91fbe878fb2de
Expand Down
13 changes: 12 additions & 1 deletion ios/AirshipReactNative.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class AirshipReactNative: NSObject {
AirshipProxy.shared
}

public static let version: String = "16.0.1"
public static let version: String = "16.1.0"

private let eventNotifier = EventNotifier()

Expand Down Expand Up @@ -545,6 +545,17 @@ public extension AirshipReactNative {
}



// Feature Flag Manager
@objc
public extension AirshipReactNative {
@objc
func featureFlagManagerFlag(flagName: String) async throws -> Any {
let result = try await AirshipProxy.shared.featureFlagManager.flag(name: flagName)
return try AirshipJSON.wrap(result).unWrap() as Any
}
}

extension AirshipReactNative: AirshipProxyDelegate {
public func migrateData(store: ProxyStore) {
ProxyDataMigrator().migrateData(store: store)
Expand Down
11 changes: 11 additions & 0 deletions ios/RTNAirship.mm
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,17 @@ + (BOOL)requiresMainQueueSetup {
// Android only
}

RCT_REMAP_METHOD(featureFlagManagerFlag,
featureFlagManagerFlag:(NSString *)flagName
featureFlagManagerFlag:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject) {

[AirshipReactNative.shared featureFlagManagerFlagWithFlagName:flagName
completionHandler:^(id result, NSError * _Nullable error) {
[self handleResult:result error:error resolve:resolve reject:reject];
}];
}


-(void)handleResult:(id)result
error:(NSError *)error
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ua/react-native-airship",
"version": "16.0.1",
"version": "16.1.0",
"description": "Airship plugin for React Native apps.",
"main": "lib/commonjs/index",
"module": "lib/module/index",
Expand Down
2 changes: 1 addition & 1 deletion react-native-airship.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ Pod::Spec.new do |s|



s.dependency "AirshipFrameworkProxy", "4.1.0"
s.dependency "AirshipFrameworkProxy", "4.2.0"

end
21 changes: 21 additions & 0 deletions src/AirshipFeatureFlagManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { FeatureFlag } from './types';

/**
* Airship feature flag manager.
*/
export class AirshipFeatureFlagManager {
constructor(private readonly module: any) {}

/**
* Retrieve a given flag's status and associated data by its name.
* @param {string} flagName the flag name
* @return {Promise<FeatureFlag>} A promise resolving to the feature flag
* requested.
* @throws {Error} when failed to fetch
*/
public flag(
flagName: string
): Promise<FeatureFlag> {
return this.module.featureFlagManagerFlag(flagName);
}
}
4 changes: 4 additions & 0 deletions src/AirshipRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { AirshipMessageCenter } from './AirshipMessageCenter';
import { AirshipPreferenceCenter } from './AirshipPreferenceCenter';
import { AirshipPrivacyManager } from './AirshipPrivacyManager';
import { AirshipPush } from './AirshipPush';
import { AirshipFeatureFlagManager } from './AirshipFeatureFlagManager';

import { AirshipConfig, EventTypeMap, EventType } from './types';
import { Subscription, UAEventEmitter } from './UAEventEmitter';

Expand All @@ -25,6 +27,7 @@ export class AirshipRoot {
public readonly preferenceCenter: AirshipPreferenceCenter;
public readonly privacyManager: AirshipPrivacyManager;
public readonly push: AirshipPush;
public readonly featureFlagManager: AirshipFeatureFlagManager;

private readonly eventEmitter: UAEventEmitter;

Expand All @@ -39,6 +42,7 @@ export class AirshipRoot {
this.preferenceCenter = new AirshipPreferenceCenter(module);
this.privacyManager = new AirshipPrivacyManager(module);
this.push = new AirshipPush(module);
this.featureFlagManager = new AirshipFeatureFlagManager(module);
this.eventEmitter = new UAEventEmitter(module);
}

Expand Down
3 changes: 3 additions & 0 deletions src/NativeRTNAirship.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ export interface Spec extends TurboModule {
localeSetLocaleOverride(localeIdentifier: string): Promise<void>;
localeGetLocale(): Promise<string>;
localeClearLocaleOverride(): Promise<void>;

// Feature Flag Manager
featureFlagManagerFlag(flagName: string):Promise<Object>;
}

export default TurboModuleRegistry.getEnforcing<Spec>('RTNAirship');
2 changes: 2 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export { AirshipLocale } from './AirshipLocale';
export { AirshipMessageCenter } from './AirshipMessageCenter';
export { AirshipPreferenceCenter } from './AirshipPreferenceCenter';
export { AirshipPrivacyManager } from './AirshipPrivacyManager';
export { AirshipFeatureFlagManager } from './AirshipFeatureFlagManager';

export { AirshipPush, AirshipPushAndroid, AirshipPushIOS } from './AirshipPush';
export { CustomEvent } from './CustomEvent';
export { SubscriptionListEditor } from './SubscriptionListEditor';
Expand Down
26 changes: 26 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -710,3 +710,29 @@ export type Item =
| AlertItem;

export type Section = CommonSection | LabeledSectionBreak;


/**
* An interface representing the eligibility status of a flag, and optional
* variables associated with the flag.
*/
export interface FeatureFlag {
/**
* A boolean representing flag eligibility; will be `true` if the current
* contact is eligible for the flag.
*/
readonly isEligible: boolean
/**
* A variables associated with the flag, if any. Will be `null` if no data
* is associated with the flag, or if the flag does not exist.
*/
readonly variables: unknown | null
/**
* A boolean representing if the flag exists or not. For ease of use and
* deployment, asking for a flag by any name will return a `FeatureFlag`
* interface, even if the flag was not found to exist. However this property
* may be checked to determine if the flag was actually resolved to a known
* flag name.
*/
readonly exists: boolean
}

0 comments on commit cd6f0d1

Please sign in to comment.