iterable / react-native-sdk Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
Hello
When I create a Push campaign, I want to send a JSON Payload and handle it on the app. How do I retrieve the JSON payload on the JS part of the app?
Note I have already set up In-App Message deep links, Push Notification URL deep links and Push Notification with Custom actions and they all work.
@iterable/react-native-sdk - 1.0.21
react-native - 0.64.0
I am getting an error when trying to build my app for iOS on the latest react native SDK version the React Native SDK has an iOS deployment target of 9.0 but the Iterable iOS SDK has an iOS deployment target of 10.0.
If I update the deployment target manually it works but it gets reset anytime I deepclean the project.
Since this is blocking us, we're going to open a CSM ticket in parallel to reporting here.
Use of undeclared identifier 'IterableAPI'
.@import IterableSDK;
at the top of AppDelegate.m
Library Search Paths
per this commentAlways Embed Swift Standard Libraries
to no
v12.4
0.64
1.10.1
I'm getting an error when trying to add Iterable SDK to my project.
npm install @iterable/react-native-sdk
Found: [email protected]
npm ERR! node_modules/react-native
npm ERR! react-native@"0.63.4" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react-native@"^0.62.2" from @iterable/[email protected]
npm ERR! node_modules/@iterable/react-native-sdk
npm ERR! @iterable/react-native-sdk@"*" from the root project
Does this SDK support react-native v0.63.4 ?
iOS build success but crash when Iterable.initialize
is called
const Config = new IterableConfig();
Config.urlHandler = (url: string, _context: IterableActionContext) => {
pageNavigation(url);
return true;
};
Iterable.initialize(config.ITERABLE_APP_ID, Config);
// package.json
"@iterable/react-native-sdk": "1.0.18",
"react-native": "0.60.6",
// Podfile
platform :ios, '11.0'
We're seeing an issue where opening our app via a push notification after user hard-quits (cancels) the app causes subsequent push notifications to not be received by the device. If the app was previously running (i.e. the user didn't hard quit the app), push notifications are received and can open the app just fine.
In our app, we use react-native-splash-screens. What's more relevant is that in order to get splash screens to show up when the app is launched, we have need to have two Activities - MainActivity (functions as you'd expect) and SplashActivity (handles showing splash screens immediately then launches MainActivity). It appears like the issue happens only when SplashActivity is started by pressing a push notification.
Repro steps:
Observed result:
Step 4 fails because "user does not have required device fields" - looking into the user profile, their device has notificationsEnabled: true
but endpointEnabled: false
set.
Expected Result
Sending the 2nd push notification in step will properly deliver a notification.
adb logcat shows that iterable attempts to make the following 4 API requests in this order whenever the app is opened after a hard-quit (i.e. when the splash screen is shown):
/users/disableDevice (200 resp)
/users/registerDeviceToken (200 resp)
/users/disableDevice (200 resp)
/users/registerDeviceToken (200 resp)
What's interesting is that those 4 API request are made regardless of what's causing the app to open after hard-quit, whether it's "launch via opening app on home screen" or "launch via press push notification." The only difference I see is that the iterable SDK will make an additional API call before those 4 I listed
/events/trackPushOpen (200 resp)
/users/disableDevice (200 resp)
/users/registerDeviceToken (200 resp)
/users/disableDevice (200 resp)
/users/registerDeviceToken (200 resp)
relevent portion of AndroidManifest.xml
<activity
android:name=".SplashActivity"
android:theme="@style/SplashTheme"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustPan"
android:exported="true">
<intent-filter>
<!-- needed because iterable, to open the app, calls getLaunchIntentForPackage() which looks for this -->
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.INFO" />
</intent-filter>
</activity>
When trying to archive a RN iOS build with the Iterable RN SDK as a dependency in XCode 12, the archive process fails:
Undefined symbols for architecture arm64:
"Swift._ArrayBuffer._copyContents(initializing: Swift.UnsafeMutableBufferPointer<A>) -> (Swift.IndexingIterator<Swift._ArrayBuffer<A>>, Swift.Int)", referenced from:
generic specialization <Swift._ArrayBuffer<IterableSDK.InboxMessageViewModel>> of Swift._copyCollectionToContiguousArray<A where A: Swift.Collection>(A) -> Swift.ContiguousArray<A.Element> in libIterable-iOS-SDK.a(InboxViewControllerViewModel.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Note, we are able to run the app in Debug mode.
Environment:
xcode - 12.0.1
build target - iOS 11
The JS/TS has console.log statements in every method call.
Not only does it litter development logs, but it also affects app performance.
Can you please remove the log statements?
urlHandler
which processes the url
and returns true
home
button to place app in background (but still running)Push open action
of Open URL
@iterable/react-native-sdk
1.0.12
react-native
0.63.1
Android OS
10
Looking at this code, it seems the Android SDK is designed to not focus the app if the event is handled. This may be fine for an Android SDK, but this RN SDK doesn't have a way to bring the app into focus if it reports the url is handled.
For Android only, we return false
in our urlHandler
, basically disabling our custom url handler, and we make sure to use urls
to double as valid deep links. This works for now, but is a somewhat limited solution.
customActionHandler
to this lib.Open app
option selected.@iterable/react-native-sdk
1.0.12
(forked by #79)react-native
0.63.3
Android OS
10
The iterable-android-sdk
fires a push action call on onReceive
, but I couldn't find anywhere it was doing this check on app startup. Based on previous work we did with Android vs iOS push notifications, we needed to explicitly check for a notification once on app startup. Not sure if that is case here, just an idea.
Another possible idea is how the iterable-android-sdk
work together. Since this lib receives notification action events via a 1 way listener that is registered here, there may be a race condition where the event gets fired before the listener designed to catch it is actually ready. Again I didn't dive in to confirm this.
On app load we fire off doAndroidAppLoadCheck() exactly once to make sure we've processed any notification actions that were pressed while the app is closed. It's a pretty hacky workaround, but seems to be working based on our early testing.
Hi, I'm running into issues while trying to configure the Iterable react-native SDK to open push notifications that handle "Open URL" action to a specific screen using universal links. It works as expected on Android - i'm only having this problem with iOS.
We use the react-navigation
library to handle universal links, which works perfectly find for other links (e.g. a webpage has the link in an <a>
tag). However it's not working for push notifications sent by iterable.
Is there some step I'm missing here?? Please let me know if any additional info is required to diagnose the issue.
Thanks in advance!
Expected Behavior:
Sending push payload with "Open URL" action and a valid universal link URL (e.g. https://MY_DEEP_LINK_HOST/support_tab
) opens up the app to the correct screen specified in the react-navigation deep link config
Observed behavior:
https://MY_DEEP_LINK_HOST/support_tab
). This is typical universal link behavior when the app is not installed on the deviceVersions:
"react-native": "0.65.2",
"@iterable/react-native-sdk": "^1.0.28",
"@react-navigation/native": "^5.7.3",
We have our app set up to open appname://foo/bar
links. We do not use Universal Linking because we don't have a web app, so there's nowhere to send those links.
When opening appname://
links, the app opens properly, but the urlHandler
function never gets called.
In AppDelegate.m
:
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
return [IterableAPI handleUniversalLink:userActivity.webpageURL];
}
In app.js:
config.urlHandler = (url, context) => {
console.log("-----------------------------------")
console.log(url)
console.log(context)
}
config.customActionHandler = (action, context) => {
console.log("===================================")
console.log(action)
console.log(context)
}
Iterable.initialize(iterableAPIKey, config)
Push notifications, in-app messaging, and registering user data are all working fine, but links into the app don't seem to be getting delegated to the handler. What are we missing?
A few quick notes... The Obj-C code above was copied from the documentation, but missing a :
between continueUserActivity
and (NSUserActivity)
and causing the app to not build. After fixing that, we get a warning: Conflicting parameter types in implementation of 'application:continueUserActivity:restorationHandler:': 'void (^ _Nonnull __strong)(NSArray<id<UIUserActivityRestoring>> * _Nullable __strong)' vs 'void (^__strong _Nonnull)(NSArray *__strong)'
I was following Iterable Documentation for adding Iterable SDK for IOS and it's very confusing and unclear.
For example, this step: In you app register device token with Iterable.
I'm adding this code to AppDelegate.m
And then I see this error immediately:
From where this IterableAPI should be imported? How to fix this error?
Hello!
I configured the deep links as explained on the docs and the deep links are working fine when the app is opened, in background, and you tap over a deep link.
But when the app is closed, the urlHandler is not fired, so the links are not opened.
I've only tested in IOS so far.
This is my AppDelegate.me:
#import "AppDelegate.h"
#import "BraintreeCore.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <GoogleMaps/GoogleMaps.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <CommonUISDK/CommonUISDK.h>
#import <UserNotifications/UserNotifications.h>
#import <React/RCTLinkingManager.h>
#import <Firebase.h>
@import IterableSDK;
#if DEBUG
#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
static void InitializeFlipper(UIApplication *application) {
FlipperClient *client = [FlipperClient sharedClient];
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
[client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
[client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
[client addPlugin:[FlipperKitReactPlugin new]];
[client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
[client start];
}
#endif
#endif
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[GMSServices provideAPIKey:@"string/GOOGLE_MAPS_KEY"];
if ([FIRApp defaultApp] == nil) {
[FIRApp configure];
}
#if DEBUG
#ifdef FB_SONARKIT_ENABLED
InitializeFlipper(application);
#endif
#endif
[self setupNotifications];
[ZDKCommonTheme currentTheme].primaryColor = [UIColor colorWithRed: 0.25 green: 0.15 blue: 0.23 alpha: 1.00];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"Test"
initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
[BTAppSwitch setReturnURLScheme:self.paymentsURLScheme];
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
- (NSString *)paymentsURLScheme {
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
return [NSString stringWithFormat:@"%@.%@", bundleIdentifier, @"payments"];
}
#pragma mark - UNUserNotificationCenterDelegate
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
completionHandler(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
[IterableAppIntegration userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[IterableAPI registerToken:deviceToken];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[IterableAppIntegration application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
#pragma mark — Handling URLs
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([url.scheme localizedCaseInsensitiveCompare:self.paymentsURLScheme] == NSOrderedSame) {
return [BTAppSwitch handleOpenURL:url options:options];
}
if ([[url.scheme substringToIndex: 2] isEqualToString:@"fb"]) {
return [[FBSDKApplicationDelegate sharedInstance]application:application
openURL:url
options:options];
}
BOOL handled = [RCTLinkingManager application:application openURL:url options:options] || [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
];
return handled;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [IterableAPI handleUniversalLink:userActivity.webpageURL] || [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
#pragma mark - private
- (void) setupNotifications {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
}
@end
This is my configuration on the JS side. It is executed on the App.js:
const config = new IterableConfig();
config.checkForDeferredDeepLink = true;
config.inAppHandler = () => {
return IterableInAppShowResponse.show;
};
config.urlHandler = url => {
if (isUrlHandledByApp(url)) {
Linking.openURL(changeUrlToCustomScheme(url));
return true;
}
return false;
};
Iterable.initialize(Config.ITERABLE_API_KEY, config);
Please help.
Thanks in advance!
I have this as part of our iterable initialization:
Iterable.setEmail(email)
Iterable.setUserId(userId)
Iterable.trackEvent(Events.auth.signedInSessionBegan, {})
When I have the setUserId
in there and look in the logs the events are mapped to a temporary email address, but if I remove that call it associates it with the email correctly. I'm not sure if this is a race condition or something. There is no feedback with setEmail
so I can't know when it is done an "safe" to continue. Perhaps if that returned a promise I could work around this?
Today, I tried the new version to see if some of the previous bugs have been completely fixed, and then I encountered some problems.
On iOS, the build failed, this is the log:
The solution is to use the old version of Iterable-iOS-AppExtensions. (Note: My Xcode version is 12.5)
target 'XXXXXX' do
pod 'Iterable-iOS-AppExtensions', '6.3.3'
end
On iOS:
The content of rich push is not displayed, which is probably the reason for using the old version of Iterable-iOS-AppExtensions.
Both platforms:
1. Inapp messages cannot be received on both platforms (the old version also has the same problem, it seems to be a server problem).
2. The action to open the notification is set to Open URL: https://www.iterable.com. But only started the app.
There is one on both platforms. That is, the SDK can accurately jump to the corresponding page when processing deep links. However, there may be a delay when the navigator processes the default path. Therefore, the deep link page is displayed first, and then the home page is displayed.
Process: Receive push message
--> Click on the message
--> Open the app and jump to the deep link page
--> Jump to the homepage
The solution I thought of is: change the urlHandler
method to an asynchronous call, so that the user can figure out when to return the result.
For example:
Iterable.js
on line 370
to be asynchronously called. After the change, the implementation of 1 second delay for Android at line 337
is unnecessary.async function callUrlHandler(url, context) {
if ((await Iterable.savedConfig.urlHandler(url, context)) == false) {
Linking.canOpenURL(url)
.then(canOpen => {
if (canOpen) {
Linking.openURL(url);
}
})
.catch(reason => { console.log("could not open url: " + reason); });
}
}
config.urlHandler = async(url, context) => {
const complete = this.appStartupComplete || await this.checkAppStartupComplete();
//do somethings
if (complete && url.match(/product\/([^\/]+)/i)) {
this.navigate(match[1]);
return true; // handled
}
return false;
};
The urlHandler
is not being called in my setup when an iOS app is open but backgrounded. It works fine if the app is closed and in app messaging also works if the app is foregrounded. I have confirmed that the native event, handleUrlCalled
is not being sent by logging inside the handler in Iterable.js
.
My AppDelegate
for iterable looks like the following:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[IterableAPI registerToken:deviceToken];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[IterableAppIntegration application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
#pragma mark - UNUserNotificationCenterDelegate
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionBanner | UNNotificationPresentationOptionList | UNNotificationPresentationOptionSound);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
[IterableAppIntegration userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
#pragma mark - private
- (void) setupNotifications {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
// ...
}
Output logs from setting log level to debug
on opening the app from the push notification:
2021-10-06 14:36:09.292220-0400 MyApp[1316:364730] 💛 14:36:09.2920:0x283bc0580:IterableTaskRunner:onAppWillEnterForeground(notification:):68
2021-10-06 14:36:09.292688-0400 MyApp[1316:364730] 💛 14:36:09.2920:0x283bc0580:IterableTaskRunner:start():44
2021-10-06 14:36:09.293126-0400 MyApp[1316:364730] 💛 14:36:09.2930:0x283bc0580:IterableTaskRunner:run():101
2021-10-06 14:36:09.294046-0400 MyApp[1316:366884] 💛 14:36:09.2930:0x28350c540:IterableTaskRunner:processTasks():144
2021-10-06 14:36:09.306800-0400 MyApp[1316:364730] 💛 14:36:09.3060:0x283bc0580:IterableAppIntegrationInternal:application(_:didReceiveRemoteNotification:fetchCompletionHandler:):162
2021-10-06 14:36:09.308403-0400 MyApp[1316:366884] 💛 14:36:09.3080:0x28350c540:IterableTaskRunner:processTasks():173: No tasks to execute
2021-10-06 14:36:09.308906-0400 MyApp[1316:366884] 💛 14:36:09.3090:0x28350c540:IterableTaskRunner:run():113: Done processing tasks
2021-10-06 14:36:09.309380-0400 MyApp[1316:366884] 💛 14:36:09.3090:0x28350c540:IterableTaskRunner:scheduleNext():121
2021-10-06 14:36:09.309929-0400 MyApp[1316:367136] 💛 14:36:09.3100:0x283550140:IterableTaskRunner:scheduleNext():128: Scheduling timer
2021-10-06 14:36:28.406650-0400 MyApp[1316:364730] 💛 14:36:28.4060:0x283bc0580:IterableTaskRunner:onAppDidEnterBackground(notification:):74
2021-10-06 14:36:28.407280-0400 MyApp[1316:364730] 💛 14:36:28.4070:0x283bc0580:IterableTaskRunner:stop():51
2021-10-06 14:36:50.801925-0400 MyApp[1316:364730] 💛 14:36:50.8010:0x283bc0580:IterableTaskRunner:onAppWillEnterForeground(notification:):68
2021-10-06 14:36:50.802457-0400 MyApp[1316:364730] 💛 14:36:50.8020:0x283bc0580:IterableTaskRunner:start():44
2021-10-06 14:36:50.803131-0400 MyApp[1316:364730] 💛 14:36:50.8030:0x283bc0580:IterableTaskRunner:run():101
2021-10-06 14:36:50.804910-0400 MyApp[1316:366884] 💛 14:36:50.8030:0x28350c540:IterableTaskRunner:processTasks():144
2021-10-06 14:36:50.806580-0400 MyApp[1316:364730] 💛 14:36:50.8060:0x283bc0580:IterableAppIntegration:application(_:didReceiveRemoteNotification:fetchCompletionHandler:):24
2021-10-06 14:36:50.808897-0400 MyApp[1316:364730] 💛 14:36:50.8080:0x283bc0580:IterableAppIntegrationInternal:application(_:didReceiveRemoteNotification:fetchCompletionHandler:):162
2021-10-06 14:36:50.809942-0400 MyApp[1316:366884] 💛 14:36:50.8090:0x28350c540:IterableTaskRunner:processTasks():173: No tasks to execute
2021-10-06 14:36:50.814180-0400 MyApp[1316:366884] 💛 14:36:50.8140:0x28350c540:IterableTaskRunner:run():113: Done processing tasks
2021-10-06 14:36:50.814698-0400 MyApp[1316:366884] 💛 14:36:50.8140:0x28350c540:IterableTaskRunner:scheduleNext():121
2021-10-06 14:36:50.815631-0400 MyApp[1316:367522] 💛 14:36:50.8150:0x283571640:IterableTaskRunner:scheduleNext():128: Scheduling timer
2021-10-06 14:36:52.005721-0400 MyApp[1316:367517] 💛 14:36:52.0050:0x28356f700:ReactIterableAPI:initialize(apiKey:config:version:resolver:rejecter:):59
2021-10-06 14:36:52.005943-0400 MyApp[1316:367517] 💛 14:36:52.0060:0x28356f700:ReactIterableAPI:initialize(withApiKey:config:version:apiEndPointOverride:resolver:rejecter:):433
2021-10-06 14:36:52.006268-0400 MyApp[1316:364730] 💛 14:36:52.0060:0x283bc0580:InternalIterableAPI:init(apiKey:launchOptions:config:apiEndPointOverride:dependencyContainer:):518
2021-10-06 14:36:52.006480-0400 MyApp[1316:364730] 💛 14:36:52.0060:0x283bc0580:InternalIterableAPI:deinit:642
2021-10-06 14:36:52.006678-0400 MyApp[1316:367517] 💛 14:36:52.0060:0x28356f700:ReactIterableAPI:getEmail(resolver:rejecter:):94
2021-10-06 14:36:52.007981-0400 MyApp[1316:364730] 💛 14:36:52.0080:0x283bc0580:IterableTaskRunner:deinit:244
2021-10-06 14:36:52.008123-0400 MyApp[1316:364730] 💛 14:36:52.0080:0x283bc0580:IterableTaskRunner:stop():51
2021-10-06 14:36:52.009864-0400 MyApp[1316:364730] 💛 14:36:52.0100:0x283bc0580:InternalIterableAPI:start():534
2021-10-06 14:36:52.011034-0400 MyApp[1316:364730] 💛 14:36:52.0110:0x283bc0580:IterableTaskRunner:init(networkSession:persistenceContextProvider:healthMonitor:notificationCenter:timeInterval:connectivityManager:dateProvider:):17
2021-10-06 14:36:52.012807-0400 MyApp[1316:364730] 💛 14:36:52.0130:0x283bc0580:InternalIterableAPI:checkRemoteConfiguration():629
2021-10-06 14:36:52.227527-0400 MyApp[1316:366875] 💛 14:36:52.2270:0x28355c6c0:ReactIterableAPI:set(email:):87
2021-10-06 14:36:52.227723-0400 MyApp[1316:366875] 💛 14:36:52.2280:0x28355c6c0:InternalIterableAPI:setEmail(_:):94
2021-10-06 14:36:52.552025-0400 MyApp[1316:366884] 💛 14:36:52.5510:0x28350c540:InternalIterableAPI:checkRemoteConfiguration():634: setting offlineMode: false
Seems like maybe it's treating this as an in-app message as I think it calling didReceiveRemoteNotification
is related to that, but setting the inAppHandler
in the config does not get called either.
Hi,
We're getting ready to release an update using Iterable in app messages. We're parsing the data returned by:
const list = await Iterable.inAppManager.getMessages();
And we're noticing that the IterableInAppMessage
on Android is missing the createdAt
date. It's showing as a null date. iOS appears to be working just fine.
referenced here:
https://github.com/Iterable/react-native-sdk/blob/master/ts/IterableInAppClasses.ts#L137
Here's our current version info:
"@iterable/react-native-sdk": "1.0.21"
Data we see:
I'm following the setup with the "Installing Iterable's React Native SDK" step and I'm testing with android devices.
But I can't receive any push notification through the Iterable campaign and test push.
Also, by using the "getLastPushPayload" function there's no returning JSON back.
Testing push notifications with @react-native-firebase/messaging works fine.
I'm wondering the push notification is broken on Iterable react-native SDK, does anyone also facing this problem?
We are currently in the process of migrating our react native application to use this lib for all push notifications. We previously used the more general libs react-native-push-notification v4.0.0
, @react-native-community/push-notification-ios v1.3.0
, and react-native-firebase v5.6.0
. We used Iterable to actually send push notifications, but just processed the raw payload ourselves to get the routing & tracking we needed.
So far the integration of this lib has been smooth, but we found one rather custom thing we had set up exposed a gap in the functionality of this (and the underlying iOS/Android) SDK.
We previously used the Push Payload
field to add our custom JSON which told our app how to handle the push once the user pressed on it.
We realized early on that we basically had custom-built a lot of the functionality this SDK provides. We did so a year ago, before this SDK was around. After this lib was released we noticed it would be better to use the OpenURL action, and just insert deep-links that we can use in our app, rather then continuing to use our custom approach.
However we were forced to do so by the fact what we see as two omissions in this SDK:
Here is an example of the kind of callback you'd expect, if you just want to have non-sdk code to have access to the entire push object.
I thought this was an omission in this react-native
version, but I dug around the root ios-sdk and saw this wasn't the case. The notification object is processed, tracked, and passed to an action handler, but there's no option to pass the raw object down the client.
Your docs really only mention the ability to read this payload using IterableApi.lastPushPayload
in client code to poll for the last payload received, but this leaves out the important cases of if an app is backgrounded/foregrounded when a push is pressed. The client has no way to know a push came through, except perhaps by polling the above to see if there is a change (not an approach we tried or recommend).
We saw that we could get the 'callback' functionality we desired by using the Open URL
action and hooking in there. But it did seem odd to use that there is apparently know way to know if a push
is pressed by the user unless it happens to have a openURL
or other action attached to it.
We were able to quickly work around this, and end up with a cleaner implementation that met our needs. However, I expect most react-native
developers will expect an option to hook into the raw push object arrival to enable additional customization/processing if desired.
Iterable.trackEvent
does not require dataFields
in the typescript code. The android SDK marks it as @Nullable as well, but the serialization code doesn't check for it to be null so it crashes when it tries to access its member field.
You should probably update the annotations in the android code of this SDK and properly handle the null case. I'm getting around it by just passing in an empty object instead but it isn't a good first-impression to have crashes like that.
We manually track in app message opens and clicks with trackInAppOpen
and trackInAppClick
. We're seeing that these events aren't firing consistently, and there are instances where we can see that an in app was shown to a user (by looking at other events that we track) without trackInAppOpen
ever being fired. There are some instances where trackInAppClick
gets fired without a trackInAppOpen
, and some where neither of the two are ever fired. Any thoughts on why this is happening?
We are on SDK version 1.1.2.
When trying to implement InApp messages with the WYSIWYG editor, the animation glitches on iOS devices, we're testing with the latest library version.
NOTE: Setting Use preset animations to show and hide the message as false and using Display Type as Full, it works like 80% percent of times, but issue remains.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>In-App Testing</title>
<meta name="description" content="Test" />
<meta name="author" content="CT Test" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, user-scalable=no" />
<style type="text/css">html,
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
.backdrop-wrapper {
display: flex;
align-items: center;
justify-content: center;
padding: 0 20px;
height: 100%;
}
.close {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
border: none;
top: 0;
width: 48px;
height: 48px;
right: 0;
}
.container {
position: relative;
display: flex;
flex-direction: column;
background-color: white;
border-radius: 16px;
overflow: hidden;
text-align: center;
color: #1f3549;
width: 100%;
max-width: 330px;
min-height: 240px;
max-height: 240px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.25);
}
.content {
display: flex;
padding: 26px 20px;
flex-direction: column;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.content h1 {
margin: 0;
padding: 0;
font-weight: bold;
line-height: 26px;
font-size: 22px;
}
.content h2 {
margin: 0;
padding: 0;
font-weight: normal;
line-height: 22px;
font-size: 16px;
}
.content .text {
margin: 12px 0 0 0;
}
.content .text:first-child {
margin: 0;
}
</style>
</head>
<body>
<div class="backdrop-wrapper">
<div class="container">
<a class="close" href="iterable://dismiss"> X </a>
<div class="content">
<h1 class="text">In-App test
</h1>
<h2 class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque gravida auctor tincidunt. Interdum et malesuada fames ac ante ipsum primis in faucibus.
</h2>
</div>
</div>
</div>
</body>
</html>
We're seeing on a range of Android devices that the InApp messages are being rendered incorrectly. We've tried different Display type
settings, including Center
, Full
, and Bottom
, but the webview often gets rendered at the very top of the screen in way too small of a scale.
I've seen a few cases where it seemed to render correctly, so this issue may be conditional. But we're definitely seeing the majority of the tests being incorrectly rendered.
react-native
: v63.3@iterable/react-native-sdk
: v1.0.18 & v1.0.12I looked through IterableInAppFragmentHTMLNotification but couldn't locate any obvious reason this was occurring.
Could possibly be caused by this but I didn't validate that guess.
This issue was addressed in one of the latest Iterable Android SDK releases. Could we get those changes updated in the React Native SDK?
The override is unsubscribing users from existing subscriptions and there's no way for us to grab an user's existing subscriptions to prevent them from being unsubscribed.
We need a way to add a user to a subscription without removing them from existing subscriptions. The current updateSubscriptions method does not allow that.
Is there a way to handle a push notification that is sent to a user when the app is in the foreground?
When building the iOS app the compilation fails with the following error: Type 'UIUserInterfaceIdiom' has no member 'mac'
the mac value was added in iOS 14, as specified in the documentation: https://developer.apple.com/documentation/uikit/uiuserinterfaceidiom/mac
Now it works well on iOS, but it doesn't work at all on Android.
I have completed it according to the configuration document on the Android side:
classpath 'com.google.gms:google-services:4.3.3'
apply plugin: 'com.google.gms.google-services'
implementation "com.google.firebase:firebase-messaging:20.2.3"
google-services.json
file in app module.setEmail
method and found the token in Audience > Contact Lookup
devices array.When I use Test Push
to send notifications on Iterable, I can't receive them.
Am I missing any configuration? who can help me? Thank you everyone!
I am not receiving in-app message on Android and iOS. There is not custom configuration. All has been handled by default Iterable React Native SDK in-app message behavior.
iOS - On Iterable, the devices array is not present in user profile when registering a new user.
iOS - Does not receive Push Notification nor in-app Message
Android - On Iterable, the devices array is present in user profile when registering a new user.
Received Push Notification, but It does not receive the in-app message.
Android's in-app messages logs
I/ReactNativeJS: 'not', { sentTime: 1651448351373,
data:
{ notificationType: 'InAppUpdate',
itbl: '{"isGhostPush":true,"messageId":"BACKGROUND_NOTIFICATION","templateId":0}' },
messageId: '0:1651448351386344%1e935ec0f9fd7ecd',
ttl: 2419200,
from: '734978458139' }
V/IterableRequest: 💛 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Response from : https://api.iterable.com/api/inApp/getMessages
V/IterableRequest: 💛 {
"inAppMessages": []
}
"@iterable/react-native-sdk": "^1.2.3"
"react-native": "0.66.3"
Hello!
When I'm trying to create an IOS release build this error happens on linking.
Undefined symbols for architecture arm64:
"Swift._ArrayBuffer._copyContents(initializing: Swift.UnsafeMutableBufferPointer<A>) -> (Swift.IndexingIterator<Swift._ArrayBuffer<A>>, Swift.Int)", referenced from:
generic specialization <Swift._ArrayBuffer<IterableSDK.InboxMessageViewModel>> of Swift._copyCollectionToContiguousArray<A where A: Swift.Collection>(A) -> Swift.ContiguousArray<A.Element> in libIterable-iOS-SDK.a(InboxViewControllerViewModel.o)
package: "@iterable/react-native-sdk": "^1.0.28"
RN version: 63.4
Xcode version: 12.4
The getLastPushPayload()
function's behavior is not consistent across platforms.
On Android, getLastPushPayload()
only returns data corresponding to the current app session because it stores data in memory which gets forgotten when the app is killed.
On iOS, getLastPushPayload()
returns data corresponding to the current app session or a previous app session because it persists data for an hour.
In my opinion, the Android behavior is preferable. Is there a reason why the iOS behavior exists? Ideally we'd like a way to determine which payload was responsible for launching the app without running into the situation where the returned data was for a previous app launch. At the very least it would be nice to have a flag on the returned result to indicate if it was an old result or not so we can distinguish between the 2 iOS scenarios.
The read
field on all InApp messages is stored locally on a single device, so this field is reset if a user logs out, and then logs back in, or switches device. We had expected this to be stored on the API, to ensure a user doesn't seen old messages already seen, even if they switch devices or have to re-auth.
We recently integrated the InApp messages to replace some of our custom built announcement features. Overall the integration went very smoothly, but there was one case where the iOS and Android sdks (and by extension, this one) worked counter to how we expected, and how the documentation implies it works.
Looking at this statement from the docs:
Iterable will not show the same in-app message to the same user more than once unless the message has been re-sent or selected in a mobile inbox.
There is a huge exception to this that wasn't clear until we completed our integration and did testing.
When a message is consumed
, the SDK's update the API (android, ios)
When a message is read
, no API call is made (android, ios).
These docs indicate that the only API calls made by the Iterable SDK when a Message is read is to track In-App Open
event, which seems to indicate this was a deliberate decision to not create an API endpoint for storing this read
data field.
This means if we leave messages in the state of not consumed
but read
sitting in the message inbox, if the user re-auths, switches devices, then they will re-receive all those messages as they will all be immediately reset to read = false
.
It would be nice to have this read
field stored on the API, rather than locally on the device, so that this state is persisted through app re-installs or device switches.
I'm getting this error when trying to build our iOS app:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_RCTEventEmitter", referenced from:
type metadata for Iterable_React_Native_SDK.ReactIterableAPI in ReactIterableAPI.o
"_OBJC_METACLASS_$_RCTEventEmitter", referenced from:
_OBJC_METACLASS_$_ReactIterableAPI in ReactIterableAPI.o
"_RCTRegisterModule", referenced from:
_initialize_ReactIterableAPI in RNIterableAPI.o
ld: symbol(s) not found for architecture x86_64
Details on my setup:
I tried cleaning and removing derived data, without success so far. Any help appreciated!
The was first brought up in another issue here, but we recently saw the same behavior. We never noticed in our previous app as we had a legacy integration where the API created the users in Iterable for the client on signup.
Iterable.setUserId
or Iterable.setEmail
Iterable.trackEvent
) fail since user does not exist.react-native
0.64.0
@iterable/react-native-sdk
1.0.26
Hi Iterable Support, could you help to add Iterable.savedConfig.logLevel === 1 to stop console?
static initialize(apiKey, config = new IterableConfig()) {
if (config.logLevel === 1) console.log("initialize: " + apiKey); // please add this
Iterable.savedConfig = config;
this.setupEventHandlers();
const version = this.getVersionFromPackageJson();
return RNIterableAPI.initializeWithApiKey(apiKey, config.toDict(), version);
}
// and for each console.log please add:
Iterable.savedConfig.logLevel === 1 && console.log(
or could you allow us to fork this library?
Very apprecaited!
Hi, I'm getting the following error when trying to build using
$ set -o pipefail && xcodebuild "-workspace" "/Users/vagrant/git/ios/myapp.xcworkspace" "-scheme" "myapp" "COMPILER_INDEX_STORE_ENABLE=NO" "archive" "-archivePath" "/var/folders/g2/xnd8hpjs50v433gfrybz2nxh0000gn/T/xcodeArchive538601221/myapp.xcarchive" "-destination" "generic/platform=iOS" | xcpretty
▸ Processing Iterable-iOS-AppExtensions-Info.plist
▸ Copying Iterable-iOS-AppExtensions-umbrella.h
▸ Copying IterableAppExtensions.h
❌ /Users/vagrant/git/ios/Pods/Iterable-iOS-AppExtensions/notification-extension/NotificationContentParser.swift:122:86: cannot find type 'UNNotificationActionIcon' in scope
private static func getNotificationIcon(forActionButton button: ActionButton) -> UNNotificationActionIcon? {
^~~~~~~~~~~~~~~~~~~~~~~~
❌ /Users/vagrant/git/ios/Pods/Iterable-iOS-AppExtensions/notification-extension/NotificationContentParser.swift:51:60: extra argument 'icon' in call
icon: getNotificationIcon(forActionButton: button),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
❌ /Users/vagrant/git/ios/Pods/Iterable-iOS-AppExtensions/notification-extension/NotificationContentParser.swift:66:51: extra argument 'icon' in call
icon: getNotificationIcon(forActionButton: button))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Last lines of the Xcode's build log:
CompileSwift normal arm64 (in target 'Iterable-iOS-AppExtensions' from project 'Pods')
cd /Users/vagrant/git/ios/Pods
/Applications/Xcode-12.5.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-frontend -frontend -emit-bc /Users/vagrant/git/ios/Pods/Iterable-iOS-AppExtensions/notification-extension/ITBNotificationServiceExtension.swift /Users/vagrant/git/ios/Pods/Iterable-iOS-AppExtensions/notification-extension/NotificationContentParser.swift /Users/vagrant/git/ios/Pods/Iterable-iOS-AppExtensions/notification-extension/NotificationExtensionConstants.swift /Users/vagrant/git/ios/Pods/Iterable-iOS-AppExtensions/notification-extension/TestFile.swift -supplementary-output-file-map /var/folders/g2/xnd8hpjs50v433gfrybz2nxh0000gn/T/supplementaryOutputs-f53c70 -target arm64-apple-ios12.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode-12.5.1.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.5.sdk -I /Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/BuildProductsPath/Release-iphoneos/Iterable-iOS-AppExtensions -F /Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/BuildProductsPath/Release-iphoneos/Iterable-iOS-AppExtensions -application-extension -g -import-underlying-module -module-cache-path /Users/vagrant/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -swift-version 5 -enforce-exclusivity\=checked -O -D COCOAPODS -serialize-debugging-options -Xcc -working-directory -Xcc /Users/vagrant/git/ios/Pods -Xcc -I/Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/swift-overrides.hmap -Xcc -iquote -Xcc /Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/IterableAppExtensions-generated-files.hmap -Xcc -I/Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/IterableAppExtensions-own-target-headers.hmap -Xcc -I/Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/IterableAppExtensions-all-non-framework-target-headers.hmap -Xcc -ivfsoverlay -Xcc /Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/all-product-headers.yaml -Xcc -iquote -Xcc /Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/IterableAppExtensions-project-headers.hmap -Xcc -I/Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/BuildProductsPath/Release-iphoneos/Iterable-iOS-AppExtensions/include -Xcc -I/Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/DerivedSources-normal/arm64 -Xcc -I/Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/DerivedSources/arm64 -Xcc -I/Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/DerivedSources -Xcc -DPOD_CONFIGURATION_RELEASE\=1 -Xcc -DCOCOAPODS\=1 -Xcc -ivfsoverlay -Xcc /Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/unextended-module-overlay.yaml -target-sdk-version 14.5 -module-name IterableAppExtensions -num-threads 8 -o /Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/Objects-normal/arm64/ITBNotificationServiceExtension.bc -o /Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/Objects-normal/arm64/NotificationContentParser.bc -o /Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/Objects-normal/arm64/NotificationExtensionConstants.bc -o /Users/vagrant/Library/Developer/Xcode/DerivedData/myapp-cqgalcmhdntyqvhcnbgkzxocasyy/Build/Intermediates.noindex/ArchiveIntermediates/myapp/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/Iterable-iOS-AppExtensions.build/Objects-normal/arm64/TestFile.bc
/Users/vagrant/git/ios/Pods/Iterable-iOS-AppExtensions/notification-extension/NotificationContentParser.swift:122:86: error: cannot find type 'UNNotificationActionIcon' in scope
private static func getNotificationIcon(forActionButton button: ActionButton) -> UNNotificationActionIcon? {
^~~~~~~~~~~~~~~~~~~~~~~~
/Users/vagrant/git/ios/Pods/Iterable-iOS-AppExtensions/notification-extension/NotificationContentParser.swift:51:60: error: extra argument 'icon' in call
icon: getNotificationIcon(forActionButton: button),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/vagrant/git/ios/Pods/Iterable-iOS-AppExtensions/notification-extension/NotificationContentParser.swift:66:51: error: extra argument 'icon' in call
icon: getNotificationIcon(forActionButton: button))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
** ARCHIVE FAILED **
The following build commands failed:
CompileSwift normal arm64
CompileSwiftSources normal arm64 com.apple.xcode.tools.swift.compiler
i'm not sure how to debug this error (related to some notification icons). Any help would be most appreciated!
I created a test inappmessage and sent to user on Android device.
The message reached the device but message content was not shown on screen.
I see that screen color changed a bit and it looks like SDK tried to show the message but its content was not shown due to some issues. I checked with several Android devices under Android 7, 9, 11 and the result always the same.
Looks like Android is unable to "render" html content of the message.
I checked same template with iOS emulator and device and all works fine.
"@iterable/react-native-sdk": "^1.2.2"
I also tried the latest 1.3.1 - same results.
Here is the device log:
2022-05-15 00:41:15.937 27687-27842/ D/itblFCMMessagingService: 💚 Iterable ghost silent push received
2022-05-15 00:41:26.559 27687-27687/ D/IterableApi: 💚 Performing automatic push registration
2022-05-15 00:41:26.563 27687-27687/ D/IterableInAppManager: 💚 Calling onNewInApp on XKLk0djGNCPXpB1fQEZDnijubuem6Wx9SaXxjCpQ9LAPw6
2022-05-15 00:41:26.575 27687-27687/ D/IterableInAppManager: 💚 Response: SHOW
Here is the message:
{ "messageId": "XKLk0djGNCPXpB1fQEZDnijubuem6Wx9SaXxjCpQ9LAPw6", "campaignId": 4236646, "createdAt": 1652564475602, "expiresAt": 1660340475602, "content": { "html": "<!DOCTYPE html><html lang=\"en\"><head><title></title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><style>\n*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}@media (max-width:520px){.row-content{width:100%!important}.image_block img.big{width:auto!important}.column .border{display:none}table{table-layout:fixed!important}}</style></head><body style=\"background-color:#fff;margin:0;padding:0;-webkit-text-size-adjust:none;text-size-adjust:none\">\n<table class=\"nl-container\" width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"mso-table-lspace:0;mso-table-rspace:0;background-color:#fff\"><tbody><tr><td><table class=\"row row-1\" align=\"center\" width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"mso-table-lspace:0;mso-table-rspace:0\"><tbody><tr><td><table class=\"row-content\" align=\"center\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" \nstyle=\"mso-table-lspace:0;mso-table-rspace:0;color:#000;width:500px\" width=\"500\"><tbody><tr><td class=\"column column-1\" width=\"100%\" style=\"mso-table-lspace:0;mso-table-rspace:0;font-weight:400;text-align:left;vertical-align:top;border-bottom:0 dotted transparent;border-left:0 dotted transparent;border-right:0 dotted transparent;border-top:0 dotted transparent;padding-top:5px;padding-bottom:5px\"><table class=\"button_block\" width=\"100%\" border=\"0\" cellpadding=\"10\" cellspacing=\"0\" \nrole=\"presentation\" style=\"mso-table-lspace:0;mso-table-rspace:0\"><tr><td><div align=\"center\">\n<a href=\"https://support.iterable.com/hc/en-us/articles/360044425951\" target=\"_blank\" style=\"text-decoration:none;display:inline-block;color:#ffffff;background-color:#3AAEE0;border-radius:4px;width:auto;border-top:1px solid #3AAEE0;font-weight:400;border-right:1px solid #3AAEE0;border-bottom:1px solid #3AAEE0;border-left:1px solid #3AAEE0;padding-top:5px;padding-bottom:5px;font-family:Arial, Helvetica Neue, Helvetica, sans-serif;text-align:center;mso-border-alt:none;word-break:keep-all;\"><span style=\"padding-left:20px;padding-right:20px;font-size:16px;display:inline-block;letter-spacing:normal;\"><span style=\"font-size: 16px; line-height: 2; word-break: break-word; mso-line-height-alt: 32px;\">Button</span></span></a>\n</div></td></tr></table><table class=\"image_block\" width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"mso-table-lspace:0;mso-table-rspace:0\"><tr><td style=\"width:100%;padding-right:0;padding-left:0\"><div align=\"center\" style=\"line-height:10px\"><img class=\"big\" \nsrc=\"https://d15k2d11r6t6rl.cloudfront.net/public/users/Integrators/669d5713-9b6a-46bb-bd7e-c542cff6dd6a/694d608ca4384f3aa1e686bdd8d3eab4/scientists-in-laboratory-3735780.jpg\" style=\"display:block;height:auto;border:0;width:500px;max-width:100%\" width=\"500\"></div></td></tr></table><table class=\"text_block\" width=\"100%\" border=\"0\" cellpadding=\"10\" cellspacing=\"0\" role=\"presentation\" style=\"mso-table-lspace:0;mso-table-rspace:0;word-break:break-word\"><tr><td><div style=\"font-family:sans-serif\">\n<div class=\"txtTinyMce-wrapper\" style=\"font-size:14px;mso-line-height-alt:16.8px;color:#555;line-height:1.2;font-family:Arial,Helvetica Neue,Helvetica,sans-serif\"><p style=\"margin:0;font-size:14px;text-align:center\">This is test in app message Oleg O</p></div></div></td></tr></table></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table></body></html>", "payload": {}, "inAppDisplaySettings": { "top": { "displayOption": "AutoExpand" }, "right": { "percentage": 0 }, "bottom": { "displayOption": "AutoExpand" }, "left": { "percentage": 0 }, "bgColor": { "alpha": 0.8, "hex": "#234345" }, "shouldAnimate": false }, "webInAppDisplaySettings": { "position": "Center" } }, "customPayload": {}, "trigger": { "type": "immediate" }, "saveToInbox": true, "inboxMetadata": { "title": "test message", "subtitle": "test msg body", "icon": "https://placekitten.com/200/300" }, "priorityLevel": 300.5, "read": true, "jsonOnly": false, "typeOfContent": "Static", "messageType": "Mobile" },
Please change the Iterable initialization code in **ReactIterableAPI.swift**
because the function you are calling doesn't have a defined method in your sdk. And because of that we got error **Extra arguments at positions #5, #6 in cal**
To resolve this error
Error screenshot
IterableAPI.initialize2(apiKey: apiKey,
launchOptions: launchOptions,
config: iterableConfig,
apiEndPointOverride: apiEndPointOverride,
linksEndPointOverride: linksEndPointOverride) { result in
resolver(result)}
it doesn't have this param in methods
linksEndPointOverride: linksEndPointOverride) { result in
resolver(result)
To run your example or integration in my app, I did the following changes and it works perfectly.
IterableAPI.initialize2(apiKey: apiKey,
launchOptions: launchOptions,
config: iterableConfig,
apiEndPointOverride: apiEndPointOverride,
callback: {result in resolver(result)}
);
}
The type for the initialize function in typescript:
static initialize(apiKey: string, config: IterableConfig = new IterableConfig()): Promise<boolean> {
is only accurate on iOS. On android there it is not resolving a promise so when we try to use the supposed promise returned from the function our app crashes. It works just fine on iOS though.
Android code function that is missing a promise:
https://github.com/Iterable/react-native-sdk/blob/master/android/src/main/java/com/iterable/reactnative/RNIterableAPIModule.java#L72
public void initializeWithApiKey(String apiKey, ReadableMap configReadableMap, String version) {
iOS function that does have it correctly:
https://github.com/Iterable/react-native-sdk/blob/master/ios/RNIterableAPI/ReactIterableAPI.swift#L54
func initialize(apiKey: String,
config configDict: [AnyHashable: Any],
version: String,
resolver: @escaping RCTPromiseResolveBlock,
rejecter: @escaping RCTPromiseRejectBlock) {
We can work around this by just always assuming the initialize works on android and ignoring the promise, but it seems sketchy that the types aren't right and it would be nice to have some visibility if the initialization fails.
When I tested whether the key is valid, I got an error message.
Run: curl -H "Api_Key: *********************68d5d6" https://api.iterable.com/api/users/registerDeviceToken
{
"msg": "Disabled API key or insufficient privileges",
"code": "BadApiKey",
"params": {
"ip": "173.248.225.222",
"endpoint": "/api/users/registerDeviceToken",
"apiKeyIdentifier": "ba68d5d6",
"apiKeyType": "Mobile"
}
}
IOS project is crashing after adding of Iterable React Native SDK I'm using React Native version 0.63.4, while Iterable React Native SDK is using 0.62.2, so in order to be able to install SDK I used --legacy-peer-deps command during installation process.
Error which I'm getting from Xcode is:
ld: warning: Could not find or use auto-linked library 'swiftWebKit'
Undefined symbols for architecture x86_64:
"_swift_FORCE_LOAD$_swiftWebKit", referenced from:
_swift_FORCE_LOAD$swiftWebKit$_Iterable_React_Native_SDK in libIterable-React-Native-SDK.a(ReactIterableAPI.o)
_swift_FORCE_LOAD$swiftWebKit$_Iterable_React_Native_SDK in libIterable-React-Native-SDK.a(Serialization.o)
_swift_FORCE_LOAD$swiftWebKit$_IterableSDK in libIterable-iOS-SDK.a(CommerceItem.o)
_swift_FORCE_LOAD$swiftWebKit$_IterableSDK in libIterable-iOS-SDK.a(IterableLogging.o)
_swift_FORCE_LOAD$swiftWebKit$_IterableSDK in libIterable-iOS-SDK.a(IterableActionContext.o)
_swift_FORCE_LOAD$swiftWebKit$_IterableSDK in libIterable-iOS-SDK.a(IterableAPI.o)
_swift_FORCE_LOAD$swiftWebKit$_IterableSDK in libIterable-iOS-SDK.a(IterableAppIntegration.o)
...
(maybe you meant: _swift_FORCE_LOAD$swiftWebKit$_IterableSDK, _swift_FORCE_LOAD$swiftWebKit$_Iterable_React_Native_SDK )
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Could not find or use auto-linked library 'swiftWebKit'
Undefined symbol: _swift_FORCE_LOAD$_swiftWebKit
Immediately after upgrading from 1.3.0 to 1.3.1, the following error prevents the app from booting:
TypeError: Cannot read property 'prototype' of undefined
at ?anon_0_ (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=io.betterhalf.app:151379:101)
System:
OS: macOS 12.3.1
CPU: (8) arm64 Apple M1 Pro
Memory: 108.48 MB / 16.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 16.14.0 - ~/.nvm/versions/node/v16.14.0/bin/node
Yarn: 1.22.17 - /opt/homebrew/bin/yarn
npm: 8.3.1 - ~/.nvm/versions/node/v16.14.0/bin/npm
Watchman: 2021.09.27.00 - /usr/local/bin/watchman
Managers:
CocoaPods: Not Found
SDKs:
iOS SDK:
Platforms: DriverKit 21.4, iOS 15.4, macOS 12.3, tvOS 15.4, watchOS 8.5
Android SDK:
API Levels: 25, 27, 28, 29, 30, 31, 32
Build Tools: 30.0.2, 30.0.3, 31.0.0, 32.0.0, 32.0.0, 33.0.0
System Images: android-31 | Google APIs ARM 64 v8a, android-32 | Google APIs ARM 64 v8a, android-Sv2 | Google APIs ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2021.1 AI-211.7628.21.2111.8309675
Xcode: 13.3.1/13E500a - /usr/bin/xcodebuild
Languages:
Java: 11.0.13 - /Users/diegolopez/.sdkman/candidates/java/current/bin/javac
npmPackages:
@react-native-community/cli: ^7.0.1 => 7.0.3
react: ^17.0.2 => 17.0.2
react-native: ^0.68.2 => 0.68.2
While running the app on a real device getting the following error in the file ReactIterableAPI.swift
Iterable initialize
method giving error Extra arguments at position #5, #6 in a call . For your reference, I enclosed a screenshot link while running the app and the error code. error screenshot
DispatchQueue.main.async { IterableAPI.initialize2(apiKey: apiKey, launchOptions: launchOptions, config: iterableConfig, apiEndPointOverride: apiEndPointOverride, linksEndPointOverride: linksEndPointOverride) { result in resolver(result) } IterableAPI.setDeviceAttribute(name: "reactNativeSDKVersion", value: version) }
TypeError: RNIterableAPI.disableDeviceForCurrentUser is not a function. (In 'RNIterableAPI.disableDeviceForCurrentUser()', 'RNIterableAPI.disableDeviceForCurrentUser' is undefined)
disableDeviceForCurrentUser
Iterable.js:162:8
tap$argument_0
identity.ts:78:18
TapSubscriber.prototype._next
tap.js:59:31
prototype.next
Subscriber.js:66:23
PairwiseSubscriber.prototype._next
pairwise.js:38:34
prototype.next
Subscriber.js:66:23
DistinctUntilChangedSubscriber.prototype._next
distinctUntilChanged.js:69:34
prototype.next
Subscriber.js:66:23
MapSubscriber.prototype._next
map.js:55:30
prototype.next
Subscriber.js:66:23
prototype.next
Subject.js:60:29
prototype._next
Subscriber.js:89:30
prototype.next
Subscriber.js:66:23
prototype.next
Subject.js:60:29
stateSubject.subscribe$argument_0
StateObservable.js:39:30
SafeSubscriber.prototype.__tryOrUnsub
Subscriber.js:207:20
SafeSubscriber.prototype.next
Subscriber.js:145:34
prototype._next
Subscriber.js:89:30
prototype.next
Subscriber.js:66:23
ObserveOnSubscriber.dispatch
observeOn.js:48:29
prototype._execute
AsyncAction.js:71:22
prototype.flush
AsyncScheduler.js:52:39
prototype.schedule
QueueAction.js:32:29
ObserveOnSubscriber.prototype.scheduleMessage
observeOn.js:53:48
ObserveOnSubscriber.prototype._next
observeOn.js:56:29
prototype.next
Subscriber.js:66:23
prototype.next
Subject.js:60:29
AnonymousSubject.prototype.next
Subject.js:144:29
<anonymous>
createEpicMiddleware.js:60:27
<anonymous>
refreshMiddleware.ts:11:24
<anonymous>
notificationsMiddleware.ts:39:24
<anonymous>
linkMiddleware.ts:22:14
<anonymous>
configMiddleware.ts:46:24
<anonymous>
segmentMiddleware.ts:15:22
<anonymous>
apiCallMiddleware.js:7:28
rehydrate
persistStore.js:69:21
_rehydrate
persistReducer.js:73:27
migrate.then$argument_0
persistReducer.js:98:21
tryCallOne
core.js:37:14
setImmediate$argument_0
core.js:123:25
callImmediates
[native code]:0
flushedQueue
[native code]:0
invokeCallbackAndReturnFlushedQueue
[native code]:0
Ran into this issue in our project - we are using Objective-C rather than Swift.
Looking at the declarations in RNIterableAPI.m
, it looks like disableDeviceForCurrentUser
is indeed missing; instead I see disableDeviceForAllUsers
. Yet in ReactIterableAPI.swift
I see disableDeviceForCurrentUser
and not disableDeviceForAllUsers
.
constructor(props) {
super(props);
this.inAppHandler = (message) => message;
const config = new IterableConfig();
config.autoPushRegistration = false;
config.checkForDeferredDeepLink = true;
config.inAppDisplayInterval = 3.0; // Min gap between in-apps. No need to set this in production.
config.urlHandler = this.urlHandler;
config.inAppHandler = this.inAppHandler;
Iterable.initialize(apiKey, config);
}
JSON value '{
createdAt = {
};
customPayload = {
event = screen;
eventName = Home;
};
expiresAt = {
};
messageId = R7DpzM5vRfQukvkXIwu4uAJRDNnUVnGsdlPvKno5;
read = 0;
saveToInbox = 0;
trigger = {
type = 0;
};
}' of type NSMutableDictionary cannot be converted to NSNumber
+[RCTConvert NSNumber:]
RCTConvert.m:57
__41-[RCTModuleMethod processMethodSignature]_block_invoke_16
__41-[RCTModuleMethod processMethodSignature]_block_invoke.164
-[RCTModuleMethod invokeWithBridge:module:arguments:]
facebook::react::invokeInner(RCTBridge*, RCTModuleData*, unsigned int, folly::dynamic const&)
facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int)::$_0::operator()() const
invocation function for block in facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int)
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_lane_serial_drain
_dispatch_lane_invoke
_dispatch_workloop_worker_thread
_pthread_wqthread
start_wqthread
customActionHandler
to this lib.Open app
option NOT selected.@iterable/react-native-sdk
1.0.12
(forked by #79)react-native
0.63.3
Android OS
10
This one is related to the #76 we worked through, except the solution isn't as straightforward. I couldn't figure out a proper PR to fix this, as it relates to behavior between react-native-sdk
and iterable-android-sdk
.
The problem starts here when we are thinking about the case where openApp
is false
AND the Android app is closed/terminated. When this occurs, this react-native-sdk
never receives the call here. I suspect this may be related to this comment which talks about the different times of initializing this lib vs iterable-android-sdk
.
I've found that the iterable-android-sdk
has no knowledge that there is 'linked' iterable-react-sdk
that actually cares about these calls, and so no effort is made to 'wake up' the RN side in order to pass along the event.
Given time constraints I couldn't figure out the 'right' way to fix this in a PR'able solution, but was able to hack into iterable-android-sdk
a call directly to an Android service we created which spins up our app in a headlessJS
so that we're able to take the action in the background. You can see the important code changes here, but ignore all the node_modules
spam.
The way better place to make this change would be here, as it could be PR'ed into to make this lib work out of the box for others. But as I said above, I found that function doesn't get called when the app is closed, which is why I had to go back all the way to iterable-android-sdk
.
This was the last major issue we found so far when creating a full suite of notification actions using this lib, so with this rough fix in place we're at a good place for final testing before releasing to production.
First, I'm excited that this has launched, but I will say that the documentation could use a little polish. It's not immediately clear what steps actually need implemented to get Iterable up and running in a React Native project as it links to lots of documentation that walks you through native integrations... This has caused a ton of confusion. I've worked on integrating this stuff for probably upwards of 60 hours on an ejected Expo project and yet still am unable to send a push notification to my device successfully... Not to mention in app messages and other things. (edit: was able to successfully send an in-app message finally)
That being said, now that I can build the app for the simulator, the build is failing when trying to archive. It comes down to this line (which is allegedly required, maybe?, in the AppDelegate.m file):
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[IterableAPI registerToken:deviceToken];
}
which throws Use of undeclared identifier 'IterableConfig'
even though @import IterableSDK;
is called in the file.
Is this even necessary? The documentation leads you down a path where you're not really sure what's required for a React Native project
I'm following React Native Iterable documentation and it says that didRegisterForRemoteNotificationsWithDeviceToken
should be implemented.
I'm adding this code to AppDelegate.m and I'm getting an error: "Use of undeclared identifier 'deviceToken'".
Or If I type it like this, I'm getting this error:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.