Description
Which Platforms?
iOS
Which React Native Version?
0.71.14
Which @braze/react-native-sdk SDK version?
8.0.0
Repro Rate
100% of the time
Steps To Reproduce
- Open the iOS app.
- Send an In-App Message to the user.
- IAM is shown as expected, close the message.
- Attempt to open an action sheet, the app crashes.
If the IAM is not sent, the action sheet works as expected. Or, if I close the app and open it again, the action sheet works again.
Expected Behavior
As for iOS 14 and above, the user should be able to keep using the action sheet after receiving the IAM.
Actual Incorrect Behavior
After receiving IAM, the app crashes when attempting to open an action sheet.
Verbose Logs
Fatal Exception: NSInvalidArgumentException
*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]
Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0x12b80c __exceptionPreprocess
1 libobjc.A.dylib 0x5fa4 objc_exception_throw
2 CoreFoundation 0x181350 -[__NSCFString characterAtIndex:].cold.1
3 CoreFoundation 0x18a6b4 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:].cold.5
4 CoreFoundation 0x1850c -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]
5 CoreFoundation 0xa3a0 +[NSDictionary dictionaryWithObjects:forKeys:count:]
6 InvoiceSimple 0x803a3c -[RCTActionSheetManager showActionSheetWithOptions:callback:] + 110 (RCTActionSheetManager.mm:110)
7 CoreFoundation 0x131c10 __invoking___
8 CoreFoundation 0x1b00 -[NSInvocation invoke]
9 CoreFoundation 0x26d8 -[NSInvocation invokeWithTarget:]
10 InvoiceSimple 0xa55240 -[RCTModuleMethod invokeWithBridge:module:arguments:] + 587 (RCTModuleMethod.mm:587)
11 InvoiceSimple 0xa573c8 facebook::react::invokeInner(RCTBridge*, RCTModuleData*, unsigned int, folly::dynamic const&, int, (anonymous namespace)::SchedulingContext) + 183 (RCTNativeModule.mm:183)
12 InvoiceSimple 0xa57050 invocation function for block in facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int) + 419 (Optional.h:419)
13 libdispatch.dylib 0x5b610 _dispatch_call_block_and_release
14 libdispatch.dylib 0x5c184 _dispatch_client_callout
15 libdispatch.dylib 0xe190 _dispatch_main_queue_callback_4CF$VARIANT$mp
16 CoreFoundation 0xa93a8 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
17 CoreFoundation 0xa439c __CFRunLoopRun
18 CoreFoundation 0xa38a0 CFRunLoopRunSpecific
19 GraphicsServices 0x3328 GSEventRunModal
20 UIKitCore 0xa01740 UIApplicationMain
21 InvoiceSimple 0x6aa4 main + 15 (main.m:15)
22 libdyld.dylib 0x1360 start
I've already checked that we are not passing any null values as the log indicates.
Additional Information
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTLinkingManager.h>
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>
#import <IntercomModule.h>
#import "Firebase.h"
#import "Orientation.h"
#import "AppsFlyerLib/AppsFlyerLib.h"
#import <BrazeKit/BrazeKit-Swift.h>
#import "BrazeReactBridge.h"
@implementation AppDelegate
static NSString *const brazeApiKey = @"...";
static NSString *const brazeEndpoint = @"...";
-
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];self.moduleName = @"...";
self.initialProps = @{};
BRZConfiguration *configuration = [[BRZConfiguration alloc] initWithApiKey:brazeApiKey endpoint:brazeEndpoint];
configuration.logger.level = BRZLoggerLevelInfo;
Braze *braze = [BrazeReactBridge initBraze:configuration];
AppDelegate.braze = braze;[IntercomModule initialize:@"..." withAppId:@"..."];
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;if (@available(iOS 14, *)) {
UIDatePicker *picker = [UIDatePicker appearance];
picker.preferredDatePickerStyle = UIDatePickerStyleWheels;
}return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
#pragma mark - AppDelegate.braze
static Braze *_braze = nil;
-
(Braze *)braze {
return _braze;
} -
(void)setBraze:(Braze *)braze {
_braze = braze;
}
// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
[RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[IntercomModule setDeviceToken:deviceToken];
[AppDelegate.braze.notifications registerDeviceToken:deviceToken];
// notify AppsFlyerLib
[[AppsFlyerLib shared] registerUninstall:deviceToken];
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
(void)[AppDelegate.braze.notifications handleBackgroundNotificationWithUserInfo:userInfo
fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// IOS 10+ Required for localNotification event
-
(void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
{
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
(void)[AppDelegate.braze.notifications handleUserNotificationWithResponse:response
withCompletionHandler:completionHandler];
completionHandler();
}
// IOS 4-10 Required for the localNotification event. -
(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[RNCPushNotificationIOS didReceiveLocalNotification:notification];
} -
(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return [Orientation getOrientation];
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
#if RCT_DEV
-
(BOOL)bridge:(RCTBridge *)bridge didNotFindModule:(NSString *)moduleName {
return YES;
}
#endif -
(BOOL)application:(UIApplication *)app openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:app openURL:url options:options];
} -
(BOOL)concurrentRootEnabled
{
return true;
}
@EnD