Customizing iOS SDK

Customize Pushwoosh iOS SDK to meet your goals and preferences


  • Create Pushwoosh account if you do not already have one.
  • Real device with iOS 9 and later. The Xcode simulator doesn't support push notifications so you must test on a real device.
  • A Mac with a new version of Xcode.
  • An iOS Push Certificate. For details, please read iOS configuration.


Background modes

To ensure that Pushwoosh SDK always receives the push token it is highly recommended to enable the Remote notifications option from the Background modes section of the Capabilities tab in your Xcode project. You can also enable this support by including the UIBackgroundModes key with the remote-notification value in your app’s Info.plist file.

Notification alert in foreground

By default Pushwoosh iOS SDK displays the notification banner when the app is running in the foreground. You can control this behavior by setting the following boolean flag in your code (i.e. in your AppDelegate):
//set false to disable foreground notications, true to enable it
Pushwoosh.sharedInstance().showPushnotificationAlert = true;
//set 0 to disable foreground notications, 1 to enable it
[[Pushwoosh sharedInstance] setShowPushnotificationAlert:0];

Controlling log level

To assist with debugging and integration, SDK will print all requests to the console by default. When you are ready for the production build, set "Pushwoosh_LOG_LEVEL" string key in your Info.plist file to one of the following values, depending on how much you want to see:
NONE - No logs from SDK ERROR - Only display errors in console WARNING - Also display warnings INFO - Add informational messages DEBUG - Add debug information VERBOSE - Everything SDK can print and more

Deep linking

In your Info.plist file add URL types array with URL Identifier and URL Scheme. In the example below the URL Scheme is com.pushwoosh and the URL Identifier is promotion.
In your App Delegate file (usually AppDelegate.m) add openURL delegate function as outlined in the example below. The example checks for the correct page, parses "id" value from the URL and opens PromoPageViewController in response.
func open(_ url: URL, options: [String : Any] = [:], completionHandler completion: ((Bool) -> Swift.Void)? = nil) {
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
let page = components?.host
var promotionId: String?
if page == "promotion" {
let items = components?.queryItems ?? []
for item in items {
if == "id" {
promotionId = item.value
//show PromoPageViewController
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSString *page =;
NSString *promotionId = nil;
//return if this is not a promotion deep link
if(![page isEqualToString:@"promotion"])
return NO;
for(NSURLQueryItem *item in components.queryItems)
if([ isEqualToString:@"id"])
promotionId = item.value;
PromoPageViewController *vc = [[PromoPageViewController alloc] init];
vc.promotionId = promotionId
[self presentViewController:vc animated:YES completion:nil];

In-app purchase tracking

By default, tracking of in-app purchases is disabled. If you want to track in-app purchases when configuring Customer Journeys, set the Pushwoosh_PURCHASE_TRACKING_ENABLED flag to true in the info.plist file. You can find a list of available flags in the table below.
If you want to track in-app purchases manually, you can use the code below.
In paymentQueue:updatedTransactions: delegate method call sendSKPaymentTransactions method of PushManager
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
// In-Apps Tracking Pushwoosh code here
// the rest of the code, consume transactions, etc
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
[[PushNotificationManager pushManager] sendSKPaymentTransactions:transactions];
//the rest of the code, consume transactions, etc

Geozones push notifications

Gezones push notifications are encapsulated into a separate framework PushwooshGeozones.
1. To add PushwooshGeozones.framework to your project using a dependency manager, put the following lines in your podfile or cartfile:
pod 'PushwooshXCFramework/Geozones'
github "Pushwoosh/pushwoosh-ios-sdk"
If you want to use PushwooshGeozones.xcframework, enter the following Package URL:
Also, you can simply drag and drop the framework into Link Binaries With Libraries in your project's Build Phases.
2. Add the following keys to your Info.plist:
  • NSLocationWhenInUseUsageDescription(required) for app to track Geozones only while running in the foreground.
  • NSLocationAlwaysAndWhenInUseUsageDescription - (required) for app to track Geozones in both conditions and to show a permission request dialog pop-up.
  • NSLocationAlwaysUsageDescription(optional) for app to track Geozones at all times; should be used if your app targets iOS 10 and earlier versions.
<string>for app to track Geozones in both conditions and to show a permission request dialog pop-up</string>
<string>for app to track Geozones only while running in the foreground</string>
3. Import the framework:
import PushwooshGeozones
#import <PushwooshGeozones/PWGeozonesManager.h>
4. Start Geozones tracking when needed:
GitHub Swift Code
GitHub Objective-C Code
Swift Example
Objective-C example

Creating a Rich Media queue

In case there are several Rich Media pages to display simultaneously (for example, trigger events for two or more In-Apps take place at one moment, or a Rich Media page is being displayed already at the moment a different trigger event occurs), you can set up a queue for Rich Media pages displaying. To create a queue, follow the steps described below.
  1. 1.
    Create a class which implements PWRichMediaPresentingDelegate:
@interface ChainedRichMediaPresentingDelegate () <PWRichMediaPresentingDelegate>
@property (nonatomic) NSMutableArray *queue;
@property (nonatomic) BOOL inAppIsPresenting;
@implementation ChainedRichMediaPresentingDelegate
- (instancetype)init {
self = [super init];
if (self) {
_queue = [NSMutableArray new];
return self;
- (BOOL)richMediaManager:(PWRichMediaManager *)richMediaManager shouldPresentRichMedia:(PWRichMedia *)richMedia {
[_queue addObject:richMedia];
return !_inAppIsPresenting;
- (void)richMediaManager:(PWRichMediaManager *)richMediaManager didPresentRichMedia:(PWRichMedia *)richMedia {
_inAppIsPresenting = YES;
- (void)richMediaManager:(PWRichMediaManager *)richMediaManager didCloseRichMedia:(PWRichMedia *)richMedia {
_inAppIsPresenting = NO;
[_queue removeObject:richMedia];
if (_queue.count) {
[[PWRichMediaManager sharedManager] presentRichMedia:_queue.firstObject];
- (void)richMediaManager:(PWRichMediaManager *)richMediaManager presentingDidFailForRichMedia:(PWRichMedia *)richMedia withError:(NSError *)error {
[self richMediaManager:richMediaManager didCloseRichMedia:richMedia];
2. Set the delegate:
[PWRichMediaManager sharedManager].delegate = [ChainedRichMediaPresentingDelegate new];

Custom UNNotificationCenterDelegate

If you want to use your own UNNotificationCenterDelegate (for example, for local notifications), you should inform Pushwoosh SDK about it for proper behavior. You can do it with the notificationCenterDelegateProxy property of Pushwoosh instance:
[Pushwoosh.sharedInstance.notificationCenterDelegateProxy addNotificationCenterDelegate:my_delegate];
Then, implement UNNotificationCenterDelegate methods in your delegate:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
if (!PWMessage.isPushwooshMessage(notification.request.content.userInfo)) {
// handle your notification
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if (!PWMessage.isPushwooshMessage(response.notification.request.content.userInfo)) {
// handle your notification
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
if (![PWMessage isPushwooshMessage:notification.request.content.userInfo]) {
//handle your message
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler {
if (![PWMessage isPushwooshMessage:response.notification.request.content.userInfo]) {
//handle your message

Custom push sound

To play a custom sound when on a push notification receiving, first put the audio file into your project's root folder. For example, here's the Pushwoosh sample app with the sound files included:
Then, specify the sound file's name in push parameters – fill in the Sound field of the iOS-specific settings of your message or specify the file name as a value for the "ios_sound" param of the createMessage API request.
Audio file for custom iOS sound has to be in one of the following formats: .aif, .caf, .wav. Make sure to specify the format in the file's name; otherwise, it will be ignored by Pushwoosh iOS SDK.
Consider App Store limitations on bundle size when adding the sound file to your bundle.

Complete list of iOS SDK Info.plist properties

Possible values
Sets the Pushwoosh application ID for production build
Type: String
Sets the Pushwoosh application ID for development build
Type: String
Shows notification foreground alert
YES (default) / NO
Type: Boolean
Sets the notification alert style
BANNER (default) / ALERT / NONE
Type: String
Overrides the Pushwoosh server base url
Type: String
If YES, Deep Links received in silent pushes will be processed automatically
YES (default) / NO
Type: Boolean
Allows the SDK to send network requests to Pushwoosh servers
YES (default) / NO
Type: Boolean
Allows the SDK to collect and to send device data (OS version status, locale and model) to the server
YES (default) / NO
Type: Boolean
Allows the SDK to collect and to send device OS version to the server
YES (default) / NO
Type: Boolean
Allows the SDK to collect and to send device locale to the server
YES (default) / NO
Type: Boolean
Allows the SDK to collect and to send device model to the server
YES (default) / NO
Type: Boolean
Pushwoosh SDK logging level. For details, refer to Controlling Log Level
Type: String
Allows the SDK to track in-app purchases. Needed for Customer Journey Builder.
YES / NO (default) Type: Boolean

iOS Provisional Push

Supported on iOS 12 and later.

How it works

Provisional push notifications appear silently in the user’s Notification Center but not on the lock screen. This type of pushes doesn’t need to be allowed by a user explicitly: you can start sending them as soon as a user installs and launches your app.
However, users still can subscribe to your prominent push notifications: when opening the Provisional Push, they have two options to choose their experience – to keep pushes in Notification Center without alerts and sounds or allow you to send pushes prominently so that they appear on the lock screen.
Provisional Pushes are designed to let users make informed decisions about whether they’d like to receive notifications from your app. As the APN native subscription request is shown to users only once and to subscribe later, they should go to their phone’s system settings, and some users might not subscribe since they aren’t aware of what value they get with your pushes. Provisional Pushes give users this understanding: they can see what content you deliver in push notifications and decide whether they need to be notified about this content prominently.
Please note that Provisional Pushes, when implemented, replace the native APN prompt, which means users cannot subscribe to prominent notifications until they open their Notification Center and choose to receive Provisional Pushes as prominent ones.

How to implement

1. Integrate the Pushwoosh iOS SDK by following the guide.
2. Add the following string to your project's AppDelegate before calling the registerForPushNotifications() method:
if #available(iOS 12.0, *) {
Pushwoosh.sharedInstance().additionalAuthorizationOptions = UNAuthorizationOptions.provisional
if (@available(iOS 12.0, *)) {
[Pushwoosh sharedInstance].additionalAuthorizationOptions = UNAuthorizationOptionProvisional;
That's it! App users will receive messages directly to their Notification Center once they install the app.

Share your feedback with us

Your feedback helps us create a better experience, so we would love to hear from you if you have any issues during the SDK integration process. If you face any difficulties, please do not hesitate to share your thoughts with us via this form.