App Templates won’t appear when the app is killed. However, they are working if the app is coming from the background. What could be the reason for this case?
If the app templates work only when they come from the app's background state but not when the app is killed, it is likely that the SDK was not correctly initialized. Make sure to call the SDK initialization code right after the didFinishLaunchingWithOptions iOS native method inside the AppDelegate class. This will enable the SDK to subscribe to the necessary iOS delegate methods to start.
func application(_ application: UIApplication,
didFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().delegate = self
Insider.initWithLaunchOptions(launchOptions,
partnerName: "your_partner_name",
appGroup: appGroup)
Insider.register(withQuietPermission: false)
return true
}
If you are initializing the SDK right after the didFinishLaunchingWithOptions iOS native method but still unable to see an App Template at launch, UI of the application might be delayed due to the logics handled inside your app. In this case, you can consider calling an event at viewDidAppear method of your Home controller. You can trigger your App Templates when your application screens are ready using this event.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
Insider.tagEvent("home_tag")?.build()
}
The images in our rich push notifications won’t appear on iOS devices. What could be the reason?
Various reasons may cause this issue:
The app group’s identifier might be incorrect
You might have a problem with your app group registration. In this case, Xcode does not recognize the app group assigned in the Signing and Capabilities.
Or the app group string is not a match with the Signing and Capabilities, App Delegate, InsiderNotificationService and InsiderNotificationContent file. You should check these for typos.
You might have another push handler inside the project.
Refer to push handling issues.
The images in our carousel push notifications won’t appear on iOS devices. What could be the reason?
- It might be due to the app groups. You might have a problem with the app group registration. In this case, Xcode does not recognize the app group assigned in the Signing and Capabilities.
Or the app group string is not a match with the Signing and Capabilities, App Delegate and NotificationViewController file insider the InsiderNotificationContent folder. You should check these for typos. - You might have another push handler inside the project. Refer to push handling issues.
How can I use Insider podfile with a static library on the iOS platform?
If the static libraries are used inside the project, you should use a specific podfile structure. See below for an example:
platform: ios, '10.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
use_frameworks!
dynamic_frameworks = ['InsiderMobile', 'InsiderMobileAdvancedNotification']
pre_install do |installer |
installer.pod_targets.each do |pod |
if ! dynamic_frameworks.include ? (pod.name)
puts "Overriding the static_framework? mothod for #(pod.name)"
def pod.static_framework ?
true
end
def pod.build_type;
Pod::BuildType.static_library
end
end
end
end
target 'InsiderDemo'
do
permissions_path = '../node_modules/react-native-permissions/ios'
pod 'Permission-LocationAlways',: path => "#{permissions_path}/LocationAlways/Permission-LocationAlways.podspec"
pod 'Permission-LocationWhenInUse',: path => "#{permissions_path}/LocationWhenInUse/Permission-LocationWhenInUse.podspec"
pod 'Permission-Microphone',: path => "#{permissions_path}/Microphone/Permission-Microphone.podspec"
# Pods
for InsiderDemo
pod 'FBLazyVector',: path => "../node_modules/react-native/Libraries/FBLazyVector"
pod 'FBReactNativeSpec',: path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
pod 'RCTRequired',: path => "../node_modules/react-native/Libraries/RCTRequired"
pod 'RCTTypeSafety',: path => "../node_modules/react-native/Libraries/TypeSafety"
pod 'React',: path => '../node_modules/react-native/'
pod 'React-Core',: path => '../node_modules/react-native/'
pod 'React-CoreModules',: path => '../node_modules/react-native/React/CoreModules'
pod 'React-Core/DevSupport',: path => '../node_modules/react-native/'
pod 'React-RCTActionSheet',: path => '../node_modules/react-native/Libraries/ActionSheetIOS'
pod 'React-RCTAnimation',: path => '../node_modules/react-native/Libraries/NativeAnimation'
pod 'React-RCTBlob',: path => '../node_modules/react-native/Libraries/Blob'
pod 'React-RCTImage',: path => '../node_modules/react-native/Libraries/Image'
pod 'React-RCTLinking',: path => '../node_modules/react-native/Libraries/LinkingIOS'
pod 'React-RCTNetwork',: path => '../node_modules/react-native/Libraries/Network'
pod 'React-RCTSettings',: path => '../node_modules/react-native/Libraries/Settings'
pod 'React-RCTText',: path => '../node_modules/react-native/Libraries/Text'
pod 'React-RCTVibration',: path => '../node_modules/react-native/Libraries/Vibration'
pod 'React-Core/RCTWebSocket',: path => '../node_modules/react-native/'
pod 'React-cxxreact',: path => '../node_modules/react-native/ReactCommon/cxxreact'
pod 'React-jsi',: path => '../node_modules/react-native/ReactCommon/jsi'
pod 'React-jsiexecutor',: path => '../node_modules/react-native/ReactCommon/jsiexecutor'
pod 'React-jsinspector',: path => '../node_modules/react-native/ReactCommon/jsinspector'
pod 'ReactCommon/callinvoker',: path => "../node_modules/react-native/ReactCommon"
pod 'ReactCommon/turbomodule/core',: path => "../node_modules/react-native/ReactCommon"
pod 'Yoga',: path => '../node_modules/react-native/ReactCommon/yoga',: modular_headers => true
pod 'DoubleConversion',: podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog',: podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly',: podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
use_native_modules!
inherit!: search_paths
end
target 'InsiderNotificationContent'
do
inherit!: search_paths
# Pods
for InsiderNotificationContent
pod "InsiderMobileAdvancedNotification"
end
target 'InsiderNotificationService'
do
inherit!: search_paths
# Pods
for InsiderNotificationService
pod "InsiderMobileAdvancedNotification"
endWhat are App Groups? How can we get them?
Applications within the same app groups can easily share data. A development may have one or more app groups for the applications. One application may have multiple app groups as well.
To get app groups:
- Visit Apple’s iOS Developer Center and log in to your account.
- Select Certificates, IDs & Profiles.
- Select Identifiers > AppGroups and click the + button to create a new group.
- Enter a name and an identifier for the new group and click the Continue button.
- Click the Register button to create the group.
- Click the Done button to return to the list of registered app groups.
How can we check if the Insider Notification Targets are set correctly?
To check if the Insider Notification Targets are set correctly, you should follow these steps:
- Set a breakpoint inside the InsiderNotificationService folder > NotificationService.m/NotificationService.swift file method.
- Run the project.
- Go to Debug at the top bar of Xcode.
- Click the Attach to Process by PID or Name.
- Enter InsiderNotificationService in the text field on the prompt.
- Click the Attach button.
- Send a test push.
After you set the breakpoint, if the test push is not fired, it means that the targets integration is incorrect. You should deintegrate the InsiderNotification targets and add them again.
How should we use an external push provider and Insider integration NotificationService together?
When integrating an external push provider with Insider, you might duplicate the NotificationService extension. You can create a separate NotificationService extension to handle push notifications.
If you have two NotificationService extensions, they may conflict inside the application. Instead, you should use one NotificationService extension, and handle the received push notifications according to their sources. The example below handles the NotificationService for both Insider and external push providers.
@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@property (nonatomic, strong) UNNotificationRequest *receivedRequest;
@property (nonatomic, strong) NSString *source;
@end
// DO NOT FORGET to change this to your app group
static NSString *APP_GROUP = @"group.com.useinsider.iGurmeV3";
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.receivedRequest = request;
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
NSDictionary *notificationData = request.content.userInfo;
self.source = [notificationData objectForKey:@"source"];
// YOU CAN CUSTOMIZE THESE
NSString *nextButtonText = @">>";
NSString *goToAppText = @"Launch App";
if ([self.source isEqual: @"Insider"]) {
[InsiderPushNotification showInsiderRichPush:request appGroup:APP_GROUP nextButtonText:nextButtonText goToAppText:goToAppText success:^(UNNotificationAttachment *attachment) {
self->_bestAttemptContent.attachments = [self->_bestAttemptContent.attachments arrayByAddingObject:attachment];
self.contentHandler(self.bestAttemptContent);
}];
return;
}
//one signal
[OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
self.contentHandler(self.bestAttemptContent);
}
- (void)serviceExtensionTimeWillExpire {
if ([self.source isEqual: @"Insider"]) {
self.contentHandler(self.bestAttemptContent);
return;
}
// one signal
[OneSignal serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
self.contentHandler(self.bestAttemptContent);
}
@end
I cannot connect to the test wizard. When I click the prompt after scanning the QR code, my iOS device is not recognized.
You are experiencing this issue due to the customized open URL handlers. Insider has its own method to handle open URLs once the method is natively triggered.
If you have any customization on your end, these methods should include Insider’s handleURL method for the SDK to function correctly.
Let’s say you have a method declared in AppDelegate as follows:
override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
/* random code inserted to override the openURL method start */
eventChannel?.setStreamHandler(linkStreamHandler)
return linkStreamHandler.handleLink(url.absoluteString)
/* random code inserted to override openURL method end */
}
It will handle the methods associated with the code base, but it will not function properly for the Insider SDK to proceed further.
If you want to override the openURL methods, check the source of the URI and handle it accordingly.
Insider URL has its own markage in the scheme value of the URI as follows:
url.scheme == "insiderpartnername"
Let’s say your partner name is Control. Insider’s URL scheme will be as follows:
url.sceheme == “insiderControl”
If you want to modify the example above based on your needs, you can apply a function as follows (assuming that your partner name is Control):
override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if (url.scheme == "insiderControl") {
Insider.handle(url)
return true
}
/* 3rd party code sample */
eventChannel?.setStreamHandler(linkStreamHandler)
return linkStreamHandler.handleLink(url.absoluteString)
/* 3rd party code sample */
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
// FIXME: Please change with your partner name.
// Make sure that all the letters are lowercase.
// Make sure insider added as prefix to your_partner_name
if ([[url scheme] isEqualToString:@"insideryour_partner_name"]) {
[Insider handleUrl:url];
}
return TRUE;
}How can I disable Insider swizzlers?
Insider SDK uses swizzlers to capture native iOS delegates. This works seamlessly without interrupting the app itself or other third-party libraries.
Nevertheless, if you are working with a third party that explicitly collides with Insider’s swizzlers due to its structure, Insider SDK allows you to disable its own swizzlers to overcome the issue.
We currently have support to disable the didRegisterForRemoteNotificationsWithDeviceToken swizzler.
To disable a swizzler:
You can open your app's Info.plist file as a Property List or Source Code to disable certain Insider swizzlers.
- Property List
The following example demonstrates editing of the Info.plist file as a property list.

As seen in the example above, we have created a dictionary named Insider to store custom SDK properties inside the app's Info.plist file. Inside our new dictionary, we have created a new array entry named Disabled Swizzlers. In this example, you can see a single disabled swizzler named didRegisterForRemoteNotificationsWithDeviceToken as a string entry inside the array.
- Source Code
The following example demonstrates editing of the Info.plist file as source code, and shows the entire property list.
<?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>Insider</key>
<dict>
<key>Disabled Swizzlers</key>
<array>
<string>didRegisterForRemoteNotificationsWithDeviceToken</string>
</array>
</dict>
</dict>
</plist>If you have other properties in your Info.plist file, add the Insider’s property list among them as displayed below.
<key>Insider</key>
<dict>
<key>Disabled Swizzlers</key>
<array>
<string>didRegisterForRemoteNotificationsWithDeviceToken</string>
</array>
</dict>Triggering the disabled didRegisterForRemoteNotificationsWithDeviceToken swizzler manually
If you disable the didRegisterForRemoteNotificationsWithDeviceToken swizzler, you can manually register for push tokens instead.
To trigger it manually, add the following code snippet in your AppDelegate class:
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[Insider registerDeviceTokenWithApplication:application deviceToken:deviceToken];
}You can use this code snippet to continue sending your device token to Insider and receive push notifications without a swizzler for the didRegisterForRemoteNotificationsWithDeviceToken method.
Issues with Sandboxing on Xcode 15
If you are having any issues with sandboxing on Xcode 15, you may consider setting the ENABLE_USER_SCRIPT_SANDBOXING option to No for the Notification Targets. The errors you encounter might be as follows:
- Sandbox: bash(72986) deny(1) file-write-data /Users/XXX/ios/Pods/resources-to-copy-InsiderNotificationService.txt
- Sandbox: bash(72986) deny(1) file-write-data /Users/XXX/ios/Pods/resources-to-copy-InsiderNotificationContent.txt