diff --git a/AppboyProject/AppboyProject.js b/AppboyProject/AppboyProject.js
index 0ea20dc..e6b657e 100644
--- a/AppboyProject/AppboyProject.js
+++ b/AppboyProject/AppboyProject.js
@@ -21,6 +21,7 @@ class AppboyProject extends Component {
super(props);
this.state = {
userIdText : '',
+ signatureText: '',
customEventText : '',
subscriptionState : 's',
gender : 'm',
@@ -30,6 +31,7 @@ class AppboyProject extends Component {
this._getInstallTrackingId = this._getInstallTrackingId.bind(this);
this._updateCardCount = this._updateCardCount.bind(this);
this._changeUserPress = this._changeUserPress.bind(this);
+ this._setSignaturePress = this._setSignaturePress.bind(this);
this._logCustomEventPress = this._logCustomEventPress.bind(this);
this._setSubscriptionStatePress = this._setSubscriptionStatePress.bind(this);
this._logPurchasePress = this._logPurchasePress.bind(this);
@@ -88,7 +90,11 @@ class AppboyProject extends Component {
ReactAppboy.addListener(ReactAppboy.Events.CONTENT_CARDS_UPDATED, function() {
console.log('Content Cards Updated.');
- })
+ });
+
+ ReactAppboy.addListener(ReactAppboy.Events.SDK_AUTHENTICATION_ERROR, function(data) {
+ console.log(`SDK Authentication for ${data.user_id} failed with error code ${data.error_code}.`);
+ });
this._listener = DeviceEventEmitter.addListener("inAppMessageReceived", function(event) {
let inAppMessage = new ReactAppboy.BrazeInAppMessage(event.inAppMessage);
@@ -156,6 +162,17 @@ class AppboyProject extends Component {
Set User ID
+
+ this.setState({signatureText})}
+ value={this.state.signatureText}
+ />
+
+ Set Signature
+
+
CFBundleDisplayName
- Appboy
+ Braze
LogLevel
0
diff --git a/AppboyProject/ios/Podfile b/AppboyProject/ios/Podfile
index 6a73378..d71d51b 100644
--- a/AppboyProject/ios/Podfile
+++ b/AppboyProject/ios/Podfile
@@ -42,4 +42,25 @@ target 'AppboyProject' do
end
use_native_modules!
+
+ # Fix for XCode 12.5 (see: https://github.com/facebook/react-native/issues/31480)
+ post_install do |installer|
+ find_and_replace("../node_modules/react-native/React/CxxBridge/RCTCxxBridge.mm",
+ "_initializeModules:(NSArray> *)modules", "_initializeModules:(NSArray *)modules")
+ find_and_replace("../node_modules/react-native/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm",
+ "RCTBridgeModuleNameForClass(module))", "RCTBridgeModuleNameForClass(Class(module)))")
+ end
+
+ def find_and_replace(dir, findstr, replacestr)
+ Dir[dir].each do |name|
+ text = File.read(name)
+ replace = text.gsub(findstr,replacestr)
+ if text != replace
+ puts "Fix: " + name
+ File.open(name, "w") { |file| file.puts replace }
+ STDOUT.flush
+ end
+ end
+ Dir[dir + '*/'].each(&method(:find_and_replace))
+ end
end
diff --git a/AppboyProject/ios/Podfile.lock b/AppboyProject/ios/Podfile.lock
index 337e0ec..21ca405 100644
--- a/AppboyProject/ios/Podfile.lock
+++ b/AppboyProject/ios/Podfile.lock
@@ -1,17 +1,17 @@
PODS:
- - Appboy-iOS-SDK (4.3.0):
- - Appboy-iOS-SDK/UI (= 4.3.0)
- - Appboy-iOS-SDK/ContentCards (4.3.0):
+ - Appboy-iOS-SDK (4.3.1):
+ - Appboy-iOS-SDK/UI (= 4.3.1)
+ - Appboy-iOS-SDK/ContentCards (4.3.1):
- Appboy-iOS-SDK/Core
- SDWebImage (< 6, >= 5.8.2)
- - Appboy-iOS-SDK/Core (4.3.0)
- - Appboy-iOS-SDK/InAppMessage (4.3.0):
+ - Appboy-iOS-SDK/Core (4.3.1)
+ - Appboy-iOS-SDK/InAppMessage (4.3.1):
- Appboy-iOS-SDK/Core
- SDWebImage (< 6, >= 5.8.2)
- - Appboy-iOS-SDK/NewsFeed (4.3.0):
+ - Appboy-iOS-SDK/NewsFeed (4.3.1):
- Appboy-iOS-SDK/Core
- SDWebImage (< 6, >= 5.8.2)
- - Appboy-iOS-SDK/UI (4.3.0):
+ - Appboy-iOS-SDK/UI (4.3.1):
- Appboy-iOS-SDK/ContentCards
- Appboy-iOS-SDK/Core
- Appboy-iOS-SDK/InAppMessage
@@ -199,8 +199,8 @@ PODS:
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsinspector (0.61.5)
- - react-native-appboy-sdk (1.30.0):
- - Appboy-iOS-SDK (~> 4.3.0)
+ - react-native-appboy-sdk (1.31.0):
+ - Appboy-iOS-SDK (~> 4.3.1)
- React
- React-RCTActionSheet (0.61.5):
- React-Core/RCTActionSheetHeaders (= 0.61.5)
@@ -334,7 +334,7 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"
SPEC CHECKSUMS:
- Appboy-iOS-SDK: dade18b2f6dc5c058669367c558ed87f389e4eea
+ Appboy-iOS-SDK: 33b31d5ade91a7d0718534798f4ab1146e7b0681
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
FBLazyVector: aaeaf388755e4f29cd74acbc9e3b8da6d807c37f
@@ -350,7 +350,7 @@ SPEC CHECKSUMS:
React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7
React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386
React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0
- react-native-appboy-sdk: dd0f7fb390666c6cfea7e177dcf22c3391e9cc39
+ react-native-appboy-sdk: 211e9e77ad5e523191c3cddd0252056668b45a13
React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76
React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360
React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72
@@ -364,6 +364,6 @@ SPEC CHECKSUMS:
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b
-PODFILE CHECKSUM: 5e38fbb08cd1a275383326ec8003103e6721fdc2
+PODFILE CHECKSUM: 12f4fef8b6ce7354bd8698dc795dfb0568db600d
COCOAPODS: 1.10.1
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e51ddd4..77c5732 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 1.31.0
+
+##### ⚠ Breaking
+- Updated the native iOS bridge to [Braze iOS SDK 4.3.1](https://github.com/Appboy/appboy-ios-sdk/blob/master/CHANGELOG.md#431).
+
+##### Added
+- Added support for new SDK Authentication feature to the Javascript layer. See `setSdkAuthenticationSignature` on the `Appboy` interface, as well as the optional `signature` parameter on `ReactAppboy.changeUser`.
+
## 1.30.0
##### ⚠ Breaking
diff --git a/__tests__/index.test.js b/__tests__/index.test.js
index c4e2d6b..c47118a 100644
--- a/__tests__/index.test.js
+++ b/__tests__/index.test.js
@@ -25,6 +25,7 @@ jest.mock('NativeModules', () => {
setEmail: jest.fn(),
setPhoneNumber: jest.fn(),
changeUser: jest.fn(),
+ setSdkAuthenticationSignature: jest.fn(),
setSDKFlavor: jest.fn(),
logCustomEvent: jest.fn(),
logPurchase: jest.fn(),
@@ -246,7 +247,13 @@ test('it calls AppboyReactBridge.changeUser', () => {
const user_id = "some_id";
ReactAppboy.changeUser(user_id);
expect(NativeModules.AppboyReactBridge.setSDKFlavor).toBeCalled();
- expect(NativeModules.AppboyReactBridge.changeUser).toBeCalledWith(user_id);
+ expect(NativeModules.AppboyReactBridge.changeUser).toBeCalledWith(user_id, null);
+});
+
+test('it calls AppboyReactBridge.setSdkAuthenticationSignature', () => {
+ const signature = "signature";
+ ReactAppboy.setSdkAuthenticationSignature(signature);
+ expect(NativeModules.AppboyReactBridge.setSdkAuthenticationSignature).toBeCalledWith(signature);
});
test('it calls AppboyReactBridge.logCustomEvent', () => {
@@ -595,4 +602,4 @@ it('instantiates a BrazeButton object with the desired defaults', () => {
expect(inAppMessage.text).toBe(defaultText);
expect(inAppMessage.clickAction).toBe(defaultClickAction.toLowerCase());
expect(inAppMessage.id).toBe(defaultId);
-});
\ No newline at end of file
+});
diff --git a/android/build.gradle b/android/build.gradle
index 2b83489..dec8524 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -14,6 +14,11 @@ android {
versionCode 1
versionName '1.0'
}
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
}
dependencies {
diff --git a/iOS/AppboyReactBridge/AppboyReactBridge/AppboyReactBridge.m b/iOS/AppboyReactBridge/AppboyReactBridge/AppboyReactBridge.m
index 4e8288e..afdc330 100644
--- a/iOS/AppboyReactBridge/AppboyReactBridge/AppboyReactBridge.m
+++ b/iOS/AppboyReactBridge/AppboyReactBridge/AppboyReactBridge.m
@@ -8,6 +8,7 @@
#import "ABKContentCardsViewController.h"
static NSString *const kContentCardsUpdatedEvent = @"contentCardsUpdated";
+static NSString *const kSdkAuthenticationErrorEvent = @"sdkAuthenticationError";
@implementation RCTConvert (AppboySubscriptionType)
RCT_ENUM_CONVERTER(ABKNotificationSubscriptionType,
@@ -16,6 +17,10 @@ @implementation RCTConvert (AppboySubscriptionType)
integerValue);
@end
+@interface AppboyReactBridge ()
+
+@end
+
@implementation AppboyReactBridge {
bool hasListeners;
}
@@ -35,17 +40,20 @@ - (void)startObserving {
selector:@selector(handleContentCardsUpdated:)
name:ABKContentCardsProcessedNotification
object:nil];
+ [Appboy sharedInstance].sdkAuthenticationDelegate = self;
}
- (void)stopObserving {
hasListeners = NO;
[[NSNotificationCenter defaultCenter] removeObserver:self];
+ [Appboy sharedInstance].sdkAuthenticationDelegate = nil;
}
- (NSArray *)supportedEvents {
return @[
- kContentCardsUpdatedEvent
- ];
+ kContentCardsUpdatedEvent,
+ kSdkAuthenticationErrorEvent
+ ];
}
- (NSDictionary *)constantsToExport
@@ -493,7 +501,7 @@ - (ABKCardCategory)getCardCategoryForString:(NSString *)category {
RCT_EXPORT_METHOD(requestImmediateDataFlush) {
RCTLogInfo(@"requestImmediateDataFlush called");
- [[Appboy sharedInstance] flushDataAndProcessRequestQueue];
+ [[Appboy sharedInstance] requestImmediateDataFlush];
}
RCT_EXPORT_METHOD(setLocationCustomAttribute:(NSString *)key latitude:(double)latitude longitude:(double)longitude callback:(RCTResponseSenderBlock)callback) {
@@ -533,4 +541,26 @@ - (ABKCardCategory)getCardCategoryForString:(NSString *)category {
}
RCT_EXPORT_MODULE();
+
+#pragma mark - SDK Authentication
+
+RCT_EXPORT_METHOD(setSdkAuthenticationSignature:(NSString *)signature)
+{
+ RCTLogInfo(@"[Appboy sharedInstance] setSdkAuthenticationSignature with value %@", signature);
+ [[Appboy sharedInstance] setSdkAuthenticationSignature:signature];
+}
+
+- (void)handleSdkAuthenticationError:(ABKSdkAuthenticationError *)authError {
+ if (!hasListeners) {
+ return;
+ }
+
+ NSMutableDictionary *error = [NSMutableDictionary dictionary];
+ error[@"error_code"] = @(authError.code);
+ error[@"user_id"] = authError.userId;
+ error[@"original_signature"] = authError.signature;
+ error[@"reason"] = authError.reason;
+ [self sendEventWithName:kSdkAuthenticationErrorEvent body:error];
+}
+
@end
diff --git a/index.d.ts b/index.d.ts
index 2fe64bb..7463e17 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -52,8 +52,18 @@ export function getInstallTrackingId(callback: Callback): void;
* to target while logged out and switching back to that user ID as part of your app's logout process.
*
* @param {string} userId - A unique identifier for this user.
+ * @param {string} signature - An encrypted signature to add to network requests to authenticate the current user. You can update the signature
+ * using the `setSdkAuthenticationSignature` method. This signature will only have an effect if SDK Authentication is enabled.
*/
-export function changeUser(userId: string): void;
+export function changeUser(userId: string, signature?: string): void;
+
+/**
+ * Sets the signature to be used to authenticate the current user. You can also set the signature when calling `changeUser`.
+ * This signature will only have an effect if SDK Authentication is enabled.
+ *
+ * @param signature - The signature to add to network requests to authenticate the current user.
+ */
+export function setSdkAuthenticationSignature(signature: string): void;
/**
* An alias serves as an alternative unique user identifier. Use aliases to identify users along different
@@ -631,6 +641,7 @@ export const NotificationSubscriptionTypes : NotificationSubscriptionType;
interface AppboyEvent {
CONTENT_CARDS_UPDATED: 'contentCardsUpdated',
+ SDK_AUTHENTICATION_ERROR: 'sdkAuthenticationError',
}
export const Events : AppboyEvent;
diff --git a/index.js b/index.js
index 4f68366..26964ae 100644
--- a/index.js
+++ b/index.js
@@ -105,10 +105,21 @@ var ReactAppboy = {
* to target while logged out and switching back to that user ID as part of your app's logout process.
*
* @param {string} userId - A unique identifier for this user.
+ * @param {string} signature - An optional authentication signature to be used with the SDK Authentication feature.
*/
- changeUser: function(userId) {
+ changeUser: function(userId, signature) {
AppboyReactBridge.setSDKFlavor();
- AppboyReactBridge.changeUser(userId, null);
+ AppboyReactBridge.changeUser(userId, signature != null ? signature : null);
+ },
+
+ /**
+ * Sets the signature to be used to authenticate the current user. You can also set the signature when calling `changeUser`.
+ * This signature will only have an effect if SDK Authentication is enabled.
+ *
+ * @param signature - The signature to add to network requests to authenticate the current user.
+ */
+ setSdkAuthenticationSignature: function(signature) {
+ AppboyReactBridge.setSdkAuthenticationSignature(signature);
},
/**
diff --git a/package.json b/package.json
index 393a219..4a61638 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-native-appboy-sdk",
- "version": "1.30.0",
+ "version": "1.31.0",
"description": "Braze SDK for React Native.",
"main": "index.js",
"types": "index.d.ts",
diff --git a/react-native-appboy-sdk.podspec b/react-native-appboy-sdk.podspec
index 3e282c2..87d6e16 100644
--- a/react-native-appboy-sdk.podspec
+++ b/react-native-appboy-sdk.podspec
@@ -18,6 +18,6 @@ Pod::Spec.new do |s|
s.preserve_paths = 'LICENSE.md', 'README.md', 'package.json', 'index.js'
s.source_files = 'iOS/**/*.{h,m}'
- s.dependency 'Appboy-iOS-SDK', '~> 4.3.0'
+ s.dependency 'Appboy-iOS-SDK', '~> 4.3.1'
s.dependency 'React'
end