Skip to content

Commit

Permalink
Release Cordova SDK version 8.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
jerielng committed Feb 8, 2024
1 parent 1b2b36c commit 12fe950
Show file tree
Hide file tree
Showing 13 changed files with 237 additions and 82 deletions.
102 changes: 61 additions & 41 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "braze-cordova-sdk",
"version": "7.0.0",
"version": "8.0.0",
"main": "www/BrazePlugin.js"
}
8 changes: 4 additions & 4 deletions plugin.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
id="cordova-plugin-braze" version="7.0.0">
id="cordova-plugin-braze" version="8.0.0">
<name>Device</name>
<description>Braze Cordova SDK</description>
<license>MIT</license>
Expand Down Expand Up @@ -54,9 +54,9 @@
<source url="https://cdn.cocoapods.org/"/>
</config>
<pods use-frameworks="true">
<pod name="BrazeKit" spec="~> 6.6.0" />
<pod name="BrazeUI" spec="~> 6.6.0" />
<pod name="BrazeLocation" spec="~> 6.6.0" />
<pod name="BrazeKit" spec="~> 7.6.0" />
<pod name="BrazeUI" spec="~> 7.6.0" />
<pod name="BrazeLocation" spec="~> 7.6.0" />
</pods>
</podspec>
</platform>
Expand Down
23 changes: 18 additions & 5 deletions sample-project/config.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.braze.hellocordova"
version="1.0.0"
xmlns="http://www.w3.org/ns/widgets"
xmlns:cdv="http://cordova.apache.org/ns/1.0"
<widget id="com.braze.hellocordova"
version="1.0.0"
xmlns="http://www.w3.org/ns/widgets"
xmlns:cdv="http://cordova.apache.org/ns/1.0"
xmlns:android="schemas.android.com/apk/res/android">

<name>HelloCordova</name>
<description>
A sample Apache Cordova application for the Braze SDK.
Expand Down Expand Up @@ -40,6 +40,7 @@
<preference name="com.braze.enable_location_collection" value="false" />
<preference name="com.braze.geofences_enabled" value="false" />
<preference name="com.braze.sdk_authentication_enabled" value="true" />
<preference name="com.braze.trigger_action_minimum_time_interval_seconds" value="30" />

<edit-config
file="app/src/main/AndroidManifest.xml"
Expand All @@ -61,5 +62,17 @@
<preference name="com.braze.display_foreground_push_notifications" value="YES" />
<preference name="deployment-target" value="11.0" />
<preference name="com.braze.ios_disable_un_authorization_option_provisional" value="NO" />
<preference name="com.braze.trigger_action_minimum_time_interval_seconds" value="30" />
<preference name="com.braze.ios_push_app_group" value="group.com.braze.hellocordova.PushStories" />
<preference name="com.braze.ios_forward_universal_links" value="YES" />

<config-file parent="UIBackgroundModes" target="*-Info.plist">
<array>
<string>remote-notification</string>
</array>
</config-file>
<resource-file src="res/HelloCordova-Debug.entitlements" target="HelloCordova-Debug.entitlements" />
<resource-file src="res/HelloCordova-Release.entitlements" target="HelloCordova-Release.entitlements" />
<hook type="after_prepare" src="hooks/replace-entitlements.js" />
</platform>
</widget>
22 changes: 22 additions & 0 deletions sample-project/hooks/replace-entitlements.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var xcode = require('xcode'),
fs = require('fs'),
path = require('path');

module.exports = function(context) {
var projectRoot = context.opts.projectRoot;
var xcconfigPath = path.join(projectRoot, 'platforms', 'ios', 'cordova', 'build.xcconfig');
var xcconfigContents = fs.readFileSync(xcconfigPath, 'utf-8');

var entitlementsLine = 'CODE_SIGN_ENTITLEMENTS = $(PROJECT_DIR)/$(PROJECT_NAME)/Resources/HelloCordova-$(CONFIGURATION).entitlements';
var regex = /^CODE_SIGN_ENTITLEMENTS = .*/m;

if (xcconfigContents.match(regex)) {
// If the line exists, replace it.
xcconfigContents = xcconfigContents.replace(regex, entitlementsLine);
} else {
// If the line doesn't exist, add it.
xcconfigContents += '\n' + entitlementsLine;
}

fs.writeFileSync(xcconfigPath, xcconfigContents, 'utf-8');
};
17 changes: 17 additions & 0 deletions sample-project/res/HelloCordova-Debug.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.braze.hellocordova.PushStories</string>
</array>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:cdv.universal.braze.com</string>
<string>applinks:cdv.universal.example.com</string>
</array>
</dict>
</plist>
17 changes: 17 additions & 0 deletions sample-project/res/HelloCordova-Release.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>production</string>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.braze.hellocordova.PushStories</string>
</array>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:universal.braze.com</string>
<string>applinks:universal.example.com</string>
</array>
</dict>
</plist>
11 changes: 10 additions & 1 deletion sample-project/www/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,16 @@ function setSdkAuthenticationSignature() {

async function getFeatureFlag() {
try {
const featureFlag = await BrazePlugin.getFeatureFlag(document.getElementById("featureFlagInputId").value);
const featureFlagId = document.getElementById("featureFlagInputId").value;
if (!featureFlagId) {
showTextBubble('Feature Flag ID not entered.');
return;
}
const featureFlag = await BrazePlugin.getFeatureFlag(featureFlagId);
if (!featureFlag) {
showTextBubble(`No Feature Flag found for ID: ${featureFlagId}`);
return;
}
showTextBubble(`Feature Flag: ${JSON.stringify(featureFlag)}`);
} catch (error) {
// This method can error out if the Feature Flag fails to serialize at the native layer.
Expand Down
21 changes: 16 additions & 5 deletions src/android/BrazePlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ open class BrazePlugin : CordovaPlugin() {
disableAutoStartSessions = false
return true
}
"registerAppboyPushMessages", "setRegisteredPushToken" -> {
"setRegisteredPushToken" -> {
runOnBraze { it.registeredPushToken = args.getString(0) }
return true
}
Expand Down Expand Up @@ -293,7 +293,14 @@ open class BrazePlugin : CordovaPlugin() {
return true
}
"getFeatureFlag" -> {
callbackContext.success(Braze.getInstance(applicationContext).getFeatureFlag(args.getString(0)).forJsonPut())
runOnBraze {
val result = it.getFeatureFlag(args.getString(0))
if (result == null) {
callbackContext.sendCordovaSuccessPluginResultAsNull()
} else {
callbackContext.sendPluginResult(PluginResult(PluginResult.Status.OK, result.forJsonPut()))
}
}
return true
}
"getAllFeatureFlags" -> {
Expand Down Expand Up @@ -322,7 +329,7 @@ open class BrazePlugin : CordovaPlugin() {
runOnBraze {
val flagId = args.getString(0)
val propKey = args.getString(1)
val result = it.getFeatureFlag(flagId).getBooleanProperty(propKey)
val result = it.getFeatureFlag(flagId)?.getBooleanProperty(propKey)
if (result == null) {
callbackContext.sendCordovaSuccessPluginResultAsNull()
} else {
Expand All @@ -335,7 +342,7 @@ open class BrazePlugin : CordovaPlugin() {
runOnBraze {
val flagId = args.getString(0)
val propKey = args.getString(1)
val result = it.getFeatureFlag(flagId).getStringProperty(propKey)
val result = it.getFeatureFlag(flagId)?.getStringProperty(propKey)
if (result == null) {
callbackContext.sendCordovaSuccessPluginResultAsNull()
} else {
Expand All @@ -348,7 +355,7 @@ open class BrazePlugin : CordovaPlugin() {
runOnBraze {
val flagId = args.getString(0)
val propKey = args.getString(1)
val result = it.getFeatureFlag(flagId).getNumberProperty(propKey)
val result = it.getFeatureFlag(flagId)?.getNumberProperty(propKey)
if (result == null) {
callbackContext.sendCordovaSuccessPluginResultAsNull()
} else {
Expand Down Expand Up @@ -504,6 +511,9 @@ open class BrazePlugin : CordovaPlugin() {
if (cordovaPreferences.contains(SDK_AUTH_ENABLED_PREFERENCE)) {
configBuilder.setIsSdkAuthenticationEnabled(cordovaPreferences.getBoolean(SDK_AUTH_ENABLED_PREFERENCE, false))
}
if (cordovaPreferences.contains(TRIGGER_ACTION_MINIMUM_TIME_INTERVAL_SECONDS_PREFERENCE)) {
configBuilder.setTriggerActionMinimumTimeIntervalSeconds(parseNumericPreferenceAsInteger(cordovaPreferences.getString(TRIGGER_ACTION_MINIMUM_TIME_INTERVAL_SECONDS_PREFERENCE, "30")))
}
Braze.configure(applicationContext, configBuilder.build())
}

Expand Down Expand Up @@ -650,6 +660,7 @@ open class BrazePlugin : CordovaPlugin() {
private const val ENABLE_GEOFENCES_PREFERENCE = "com.braze.geofences_enabled"
private const val DISABLE_AUTO_START_SESSIONS_PREFERENCE = "com.braze.android_disable_auto_session_tracking"
private const val SDK_AUTH_ENABLED_PREFERENCE = "com.braze.sdk_authentication_enabled"
private const val TRIGGER_ACTION_MINIMUM_TIME_INTERVAL_SECONDS_PREFERENCE = "com.braze.trigger_action_minimum_time_interval_seconds"

/**
* When applied, restricts the SDK from taking
Expand Down
6 changes: 3 additions & 3 deletions src/android/ContentCardUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ object ContentCardUtils {
put("extras", JSONObject(card.extras))
}
when (card.cardType) {
BANNER -> mapBannerImageCardFields(mappedCardJson, card as BannerImageCard)
IMAGE -> mapImageOnlyCardFields(mappedCardJson, card as ImageOnlyCard)
CAPTIONED_IMAGE -> mapCaptionedImageCardFields(mappedCardJson, card as CaptionedImageCard)
SHORT_NEWS -> mapShortNewsCardFields(mappedCardJson, card as ShortNewsCard)
TEXT_ANNOUNCEMENT -> mapTextAnnouncementCardFields(mappedCardJson, card as TextAnnouncementCard)
Expand Down Expand Up @@ -82,12 +82,12 @@ object ContentCardUtils {
}
}

private fun mapBannerImageCardFields(mappedCard: JSONObject, card: BannerImageCard) {
private fun mapImageOnlyCardFields(mappedCard: JSONObject, card: ImageOnlyCard) {
mappedCard.apply {
put("image", card.imageUrl)
put("imageAspectRatio", card.aspectRatio.toDouble())
put("domain", card.domain)
put("type", "Banner")
put("type", "ImageOnly")
}
}
}
2 changes: 1 addition & 1 deletion src/android/build-extras.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repositories {
}

dependencies {
implementation 'com.braze:android-sdk-ui:27.0.1'
implementation 'com.braze:android-sdk-ui:30.0.0'
implementation 'com.google.firebase:firebase-messaging:23.0.0'
}

Expand Down
65 changes: 62 additions & 3 deletions src/ios/BrazePlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ @interface BrazePlugin() <BrazeSDKAuthDelegate>
@property NSString *sessionTimeout;
@property NSString *enableSDKAuth;
@property NSString *sdkAuthCallbackID;
@property NSString *triggerActionMinimumTimeInterval;
@property NSString *pushAppGroup;
@property NSString *forwardUniversalLinks;
@end

static Braze *_braze;
Expand All @@ -44,6 +47,9 @@ - (void)pluginInitialize {
self.disableUNAuthorizationOptionProvisional = settings[@"com.braze.ios_disable_un_authorization_option_provisional"];
self.sessionTimeout = settings[@"com.braze.ios_session_timeout"];
self.enableSDKAuth = settings[@"com.braze.sdk_authentication_enabled"];
self.triggerActionMinimumTimeInterval = settings[@"com.braze.trigger_action_minimum_time_interval_seconds"];
self.pushAppGroup = settings[@"com.braze.ios_push_app_group"];
self.forwardUniversalLinks = settings[@"com.braze.ios_forward_universal_links"];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didFinishLaunchingListener:) name:UIApplicationDidFinishLaunchingNotification object:nil];

Expand All @@ -61,10 +67,29 @@ - (void)didFinishLaunchingListener:(NSNotification *)notification {
[configuration.location setGeofencesEnabled:self.enableGeofences];
[configuration.location setAutomaticLocationCollection:self.enableLocationCollection];

// Set the minimum time interval between triggers (in seconds)
if ([self isStringPositiveNumeric:self.triggerActionMinimumTimeInterval]) {
NSTimeInterval intervalCast = [self.triggerActionMinimumTimeInterval doubleValue];
configuration.triggerMinimumTimeInterval = intervalCast;
NSLog(@"Setting \"trigger_action_minimum_time_interval_seconds\" to: %g", intervalCast);
} else {
NSLog(@"\"trigger_action_minimum_time_interval_seconds\" value not valid. Setting value to 30.");
}

// Set if the SDK should automatically recognize and forward universal links to the system methods
if ([self.forwardUniversalLinks isEqualToString:@"YES"]) {
configuration.forwardUniversalLinks = @YES;
NSLog(@"iOS universal link forwarding is enabled.");
}

// Set the time interval for session time out (in seconds)
NSNumber *timeout = [[[NSNumberFormatter alloc] init] numberFromString:self.sessionTimeout];
[configuration setSessionTimeout:[timeout doubleValue]];
[configuration.api addSDKMetadata:@[[BRZSDKMetadata cordova]]];

// Set the app group identifier for push stories.
[configuration.push setAppGroup:self.pushAppGroup];

self.braze = [[Braze alloc] initWithConfiguration:configuration];
self.braze.inAppMessagePresenter = [[BrazeInAppMessageUI alloc] init];
self.subscriptions = [NSMutableArray array];
Expand Down Expand Up @@ -633,10 +658,10 @@ + (NSDictionary *)formattedContentCard:(BRZContentCardRaw *)card {
formattedContentCardData[@"domain"] = card.domain ?: [NSNull null];
formattedContentCardData[@"type"] = @"Classic";
break;
case BRZContentCardRawTypeBanner:
case BRZContentCardRawTypeImageOnly:
formattedContentCardData[@"image"] = [card.image absoluteString];
formattedContentCardData[@"imageAspectRatio"] = @(card.imageAspectRatio);
formattedContentCardData[@"type"] = @"Banner";
formattedContentCardData[@"type"] = @"ImageOnly";
break;
case BRZContentCardRawTypeCaptionedImage:
formattedContentCardData[@"image"] = [card.image absoluteString];
Expand Down Expand Up @@ -671,7 +696,10 @@ + (NSString *)getJsonFromExtras:(NSDictionary *)extras {
- (void)getFeatureFlag:(CDVInvokedUrlCommand *)command {
NSString *featureFlagId = [command argumentAtIndex:0 withDefault:nil];
BRZFeatureFlag *featureFlag = [self.braze.featureFlags featureFlagWithId:featureFlagId];

if (featureFlag == nil) {
[self sendCordovaSuccessPluginResultAsNull:command];
return;
}
NSError* error = nil;
id flagJSON = [NSJSONSerialization JSONObjectWithData:[featureFlag json]
options:NSJSONReadingMutableContainers
Expand Down Expand Up @@ -706,6 +734,11 @@ - (void)getFeatureFlagBooleanProperty:(CDVInvokedUrlCommand *)command {
NSString *propertyKey = [command argumentAtIndex:1 withDefault:nil];

BRZFeatureFlag *featureFlag = [self.braze.featureFlags featureFlagWithId:featureFlagId];
if (!featureFlag) {
[self sendCordovaSuccessPluginResultAsNull:command];
return;
}

NSNumber *boolProperty = [featureFlag boolPropertyForKey:propertyKey];
if (boolProperty) {
[self sendCordovaSuccessPluginResultWithBool:boolProperty andCommand:command];
Expand All @@ -719,6 +752,11 @@ - (void)getFeatureFlagStringProperty:(CDVInvokedUrlCommand *)command {
NSString *propertyKey = [command argumentAtIndex:1 withDefault:nil];

BRZFeatureFlag *featureFlag = [self.braze.featureFlags featureFlagWithId:featureFlagId];
if (!featureFlag) {
[self sendCordovaSuccessPluginResultAsNull:command];
return;
}

NSString *stringProperty = [featureFlag stringPropertyForKey:propertyKey];
if (stringProperty) {
[self sendCordovaSuccessPluginResultWithString:stringProperty andCommand:command];
Expand All @@ -732,6 +770,11 @@ - (void)getFeatureFlagNumberProperty:(CDVInvokedUrlCommand *)command {
NSString *propertyKey = [command argumentAtIndex:1 withDefault:nil];

BRZFeatureFlag *featureFlag = [self.braze.featureFlags featureFlagWithId:featureFlagId];
if (!featureFlag) {
[self sendCordovaSuccessPluginResultAsNull:command];
return;
}

NSNumber *numberProperty = [featureFlag numberPropertyForKey:propertyKey];
if (numberProperty) {
[self sendCordovaSuccessPluginResultWithDouble:[numberProperty doubleValue] andCommand:command];
Expand Down Expand Up @@ -831,4 +874,20 @@ - (void)sendCordovaSuccessPluginResultAsNull:(CDVInvokedUrlCommand *)command {
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

// MARK: - Helper Methods
/**
* Takes an input NSString and returns true if it is a valid positive number.
* If the string is not a valid number or is negative, returns false.
**/
- (BOOL)isStringPositiveNumeric:(NSString *)inputString {
if ([inputString length] > 0) {
// Check if the string is a valid number (only contains digits 0 through 9)
NSCharacterSet* notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
if (([inputString rangeOfCharacterFromSet:notDigits].location == NSNotFound) && [inputString doubleValue] >= 0) {
return true;
}
}
return false;
}

@end
Loading

0 comments on commit 12fe950

Please sign in to comment.