iOS SDK setup

Push Notifications are a must-have tool for engaging and retaining users in today's competitive app marketplace. In this setup guide, we’ll show you how to quickly and easily add push notifications to your iOS app for free using OneSignal.

These instructions are for adding the OneSignal SDK to your iOS native app with Swift or Objective-C.

Setting up push notifications for your iOS app using OneSignal

iOS push notifications are essential for driving sustained user engagement and retention in your iOS app. They empower you to deliver real-time updates, reminders, and personalized messages directly to your users, improving the overall user experience and stickiness of your app. By integrating OneSignal’s SDK with your app, you can take advantage of Apple Push Notification Service (APNS) to ensure your notifications are delivered seamlessly across iOS devices. This guide will walk you through the steps to configure push notifications for your iOS app, so you can seamlessly connect with your users.

Requirements

  • iOS 11+ or iPadOS 11+ device (iPhone, iPad, iPod Touch) to test on. Xcode 14+ simulator works running iOS 16+
  • mac with Xcode 12+
  • Configured OneSignal App and Platform

Preparing your iOS app for push notifications

Before you can enable iOS push notifications, it's crucial to ensure that your app is correctly configured to communicate with Apple Push Notification Service (APNS). APNS is responsible for managing and delivering push notifications to your app’s users. If you have not done so already, follow the configuration steps below to set up your OneSignal account, register your app with Apple, configure necessary permissions in OneSignal, and set up certificates to allow your iOS app to send push notifications reliably.

Configure your OneSignal app and platform

If your team already created an account with OneSignal, ask to be invited as an admin role so you can setup the app. Otherwise, sign up for a free account at onesignal.com to get started!

Details on configuring your OneSignal app (click to expand)

You can setup multiple platforms (iOS, Android, Web, Email, SMS) within the same OneSignal App under Settings > Platforms. If you want to create a new app select New App/Website. If this is your first OneSignal app, you will see the next page.



Name your app and organization something recognizable, then select the platform to setup. You can always set up more platforms in this OneSignal App later within Settings > Platforms.

Click Next: Configure Your Platform.


To configure your app, follow the prompts based on the platforms you support.

After you setup your credentials, click Save & Continue.

Choose your Apps Target SDK, the click Save & Continue.


Finally, you will be directed to install the SDK and provided your OneSignal App ID. Make sure to save your App ID as you will need it later.

If you need a teammate or your developer to assist, you can click Invite them to the app and select Done when finished.


Continue through the documentation to finish adding OneSignal to your app.

iOS notification setup guide

Open Xcode and have your OneSignal dashboard ready. If you don't have access to your company's OneSignal dashboard, ask your team to follow Manage Team Members and invite you!

1. Add capabilities

This step will make sure your project is able to receive remote/push notifications.

Select the root project > your main app target > Signing & Capabilities.

If you do not see Push Notifications enabled, click + Capability and add Push Notifications.

Click + Capability again and add Background Modes. Then check Remote notifications.

2. Add Notification Service Extension

The OneSignalNotificationServiceExtension allows your iOS application to receive rich notifications with images, buttons, and badges. It's also required for OneSignal's Confirmed Delivery analytics features.

In Xcode Select File > New > Target...

Select Notification Service Extension then Next.

Enter the product name as OneSignalNotificationServiceExtension and press Finish.

Do not activate the scheme on the dialog that is shown after selecting "Finish".

Press Cancel on the Activate scheme prompt.

By canceling, you keep Xcode debugging your app instead of the extension you just created. If you activated by accident, you can switch back to debug your app target (middle-top next to the device selector).

By canceling, you keep Xcode debugging your app instead of the extension you just created. If you activated by accident, you can switch back to debug your app target (middle-top next to the device selector).

Select the OneSignalNotificationServiceExtension target and General settings.

Set Minimum Deployments to be the same value as your Main Application Target. This should be iOS 11 or higher.

Set the OneSignalNotificationServiceExtension Target Minimum Deployments value to be the same as your Main Application Target.

Set the OneSignalNotificationServiceExtension Target Minimum Deployments value to be the same as your Main Application Target.

3. Add App Groups

App Groups allow your app and the OneSignalNotificationServiceExtension to communicate when a notification is received, even if your app is not active. This is required for badges and Confirmed Deliveries.

Select your Main App Target > Signing & Capabilities > + Capability > App Groups.

Within App Groups, click the + button.

Set the App Groups container to be group.YOUR_BUNDLE_IDENTIFIER.onesignal where YOUR_BUNDLE_IDENTIFIER is the same as your Main Application "Bundle Identifier".

Press OK and repeat for the OneSignalNotificationServiceExtension Target.

Select the OneSignalNotificationServiceExtension Target > Signing & Capabilities > + Capability > App Groups.

Within App Groups, click the + button.

Set the App Groups container to be group.YOUR_BUNDLE_IDENTIFIER.onesignal where YOUR_BUNDLE_IDENTIFIER is the same as your Main Application "Bundle Identifier".

DO NOT INCLUDE OneSignalNotificationServiceExtension.

Do not include OneSignalNotificationServiceExtension

Do not include OneSignalNotificationServiceExtension

Optional instructions to setup custom App Group Name (click to expand)

This step is only required if you do not want to use the default app group name (which is group.{your_bundle_id}.onesignal).

Open your Info.plist file and add a new OneSignal_app_groups_key as a String type.

Enter the group name you checked in the last step as it's value.

Make sure to do the same for the Info.plist under the OneSignalNotificationServiceExtension folder.

You may need to restart Xcode after doing this to clear any cache.

4. Add SDK

Choose one of the following methods and use it consistently to avoid errors.

Swift Package Manager

The OneSignal SDK can be added as a Swift Package (works with Objective-C as well).

Instructions on adding OneSignal with Swift Package Manager (click to expand)

Select your Project > Package Dependencies > + button.

Enter Package URL: https://github.com/OneSignal/OneSignal-XCFramework

Make sure Dependency Rule is set to Up to Next Major Version

Click Add Package

Add the libraries to the following packages as directed. Note that if you do not include the OneSignalInAppMessages and OneSignalLocation libraries, you will not have access to those features.

  • Required: OneSignalExtension to the OneSignalNotificationServiceExtension Target.
  • Required: OneSignalFramework to your Application Target.
  • Recommended: OneSignalInAppMessages to your Application Target.
  • Optional: OneSignalLocation to your Application Target.

Click Add Package.

In this example, we exclude the OneSignalLocation library and therefore will not have access to storing location within OneSignal.

In this example, we exclude the OneSignalLocation library and therefore will not have access to storing location within OneSignal.

Select your Application Target > General > Frameworks, Libraries, and Embedded Content.

Check to ensure the required OneSignalFramework and other optionally selected libraries (OneSignalInAppMessages and OneSignalLocation) have been added.

In this example, we correctly see the OneSignalFramework and OneSignalInAppMessages libraries are added. The OneSignalLocation library is missing because we excluded it in the previous step.

In this example, we correctly see the OneSignalFramework and OneSignalInAppMessages libraries are added. The OneSignalLocation library is missing because we excluded it in the previous step.

Select the OneSignalNotificationServiceExtension Target > General > Frameworks and Libraries.

Check to ensure the required OneSignalFramework and other optionally selected libraries (OneSignalInAppMessages and OneSignalLocation) have been added.

CocoaPods

The OneSignal SDK can be added with CocoaPods.

Instructions on adding OneSignal with CocoaPods (click to expand)

Ensure your installed Cocoapods version is 1.12.1 or newer!

Close your current Xcode project and in the project root, run sudo gem install cocoapods.

Run pod init from the terminal in your project directory.

Open the newly created Podfile with your favorite code editor.

Add the OneSignal dependency under your project name target as well as
OneSignalNotificationServiceExtension target like below.

target 'your_project_name' do
  pod 'OneSignal/OneSignal', '>= 5.0.0', '< 6.0'
  pod 'OneSignal/OneSignalInAppMessages', '>= 5.0.0', '< 6.0'
  # If your app does not use CoreLocation, you can remove this:
  pod 'OneSignal/OneSignalLocation', '>= 5.0.0', '< 6.0'
  # Your other pods here
end

target 'OneSignalNotificationServiceExtension' do
  pod 'OneSignal/OneSignal', '>= 5.0.0', '< 6.0'
  pod 'OneSignal/OneSignalInAppMessages', '>= 5.0.0', '< 6.0'
  # If your app does not use CoreLocation, you can remove this:
  pod 'OneSignal/OneSignalLocation', '>= 5.0.0', '< 6.0'
end

Run the following commands in your terminal in your project directory.

pod repo update
pod install

Open the newly created <project-name>.xcworkspace file.

Make sure to always open the workspace from now on. You can also do this automatically by running xed . from the root of your project.

5. Initialization

Storyboard

If using the Storyboard, navigate to your AppDelegate file and add the OneSignal initialization code to didFinishLaunchingWithOptions. Replace YOUR_ONESIGNAL_APP_ID with your OneSignal App ID.

Make sure to import the OneSignal headers:

  • Swift: import OneSignalFramework
  • Objective-C: #import <OneSignalFramework/OneSignalFramework.h>
import UIKit
import OneSignalFramework

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: 
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  
  // Remove this method to stop OneSignal Debugging
  OneSignal.Debug.setLogLevel(.LL_VERBOSE)
  
  // OneSignal initialization
  OneSignal.initialize("YOUR_ONESIGNAL_APP_ID", withLaunchOptions: launchOptions)
  
  // requestPermission will show the native iOS notification permission prompt.
  // We recommend removing the following code and instead using an In-App Message to prompt for notification permission
  OneSignal.Notifications.requestPermission({ accepted in
    print("User accepted notifications: \(accepted)")
  }, fallbackToSettings: true)
  
  // Login your customer with externalId
  // OneSignal.login("EXTERNAL_ID")
  
  return true
}
  
// Remaining contents of your AppDelegate Class...
}
#import <OneSignalFramework/OneSignalFramework.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
  // Remove this method to stop OneSignal Debugging  
  [OneSignal.Debug setLogLevel:ONE_S_LL_VERBOSE];
  
  // OneSignal initialization
  [OneSignal initialize:@"YOUR_ONESIGNAL_APP_ID" withLaunchOptions:launchOptions];

  // requestPermission will show the native iOS notification permission prompt.
  // We recommend removing the following code and instead using an In-App Message to prompt for notification permission
  [OneSignal.Notifications requestPermission:^(BOOL accepted) {
    NSLog(@"User accepted notifications: %d", accepted);
  } fallbackToSettings:true];
  
  // Login your customer with externalId
  // [OneSignal login:@"EXTERNAL_ID"];
  
  return YES;
}

SwiftUI

If using SwiftUI, update your main 'APP_NAME'App.swift file and add the OneSignal initialization code. Replace YOUR_ONESIGNAL_APP_ID with your OneSignal App ID.

import SwiftUI
import OneSignalFramework

@main
struct YOURAPP_NAME: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
       // Remove this method to stop OneSignal Debugging
       OneSignal.Debug.setLogLevel(.LL_VERBOSE)
        
       // OneSignal initialization
       OneSignal.initialize("YOUR_ONESIGNAL_APP_ID", withLaunchOptions: launchOptions)

       // requestPermission will show the native iOS notification permission prompt.
       // We recommend removing the following code and instead using an In-App Message to prompt for notification permission
       OneSignal.Notifications.requestPermission({ accepted in
         print("User accepted notifications: \(accepted)")
       }, fallbackToSettings: true)

       // Login your customer with externalId
       // OneSignal.login("EXTERNAL_ID")
            
       return true
    }
}

OneSignalNotificationServiceExtension

In the project navigator, select the OneSignalNotificationServiceExtension folder and open the NotificationService.m or NotificationService.swift file.

Replace the whole file's contents with the following code.

import UserNotifications

import OneSignalExtension

class NotificationService: UNNotificationServiceExtension {
    
    var contentHandler: ((UNNotificationContent) -> Void)?
    var receivedRequest: UNNotificationRequest!
    var bestAttemptContent: UNMutableNotificationContent?
    
    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.receivedRequest = request
        self.contentHandler = contentHandler
        self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        
        if let bestAttemptContent = bestAttemptContent {
            /* DEBUGGING: Uncomment the 2 lines below to check this extension is executing
                          Note, this extension only runs when mutable-content is set
                          Setting an attachment or action buttons automatically adds this */
            // print("Running NotificationServiceExtension")
            // bestAttemptContent.body = "[Modified] " + bestAttemptContent.body
            
            OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler)
        }
    }
    
    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            OneSignalExtension.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
            contentHandler(bestAttemptContent)
        }
    }  
}
#import <OneSignalExtension/OneSignalExtension.h>

#import "NotificationService.h"

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNNotificationRequest *receivedRequest;
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.receivedRequest = request;
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    
    /* DEBUGGING: Uncomment the 2 lines below and comment out the one above to ensure this extension is executing
                  Note, this extension only runs when mutable-content is set
                  Setting an attachment or action buttons automatically adds this */
    // NSLog(@"Running NotificationServiceExtension");
    // self.bestAttemptContent.body = [@"[Modified] " stringByAppendingString:self.bestAttemptContent.body];
    
    [OneSignalExtension didReceiveNotificationExtensionRequest:self.receivedRequest
                       withMutableNotificationContent:self.bestAttemptContent
                                   withContentHandler:self.contentHandler];
}

- (void)serviceExtensionTimeWillExpire {
    // Called just before the extension will be terminated by the system.
    // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
    
    [OneSignalExtension serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
    
    self.contentHandler(self.bestAttemptContent);
}

@end
Example of the NotificationService.swift file.

Example of the NotificationService.swift file.

6. Testing

Run your app on a physical device to make sure it builds correctly.

If you used the provided code, then the requestPermission method, should prompt you to subscribe to push notifications. You can always change this later but for now, click "Allow" to subscribe to push notifications.

Check your OneSignal Dashboard Audience > Subscriptions to see your Subscription and click the options button on the left to set yourself as a Test Subscription.

📘

Troubleshooting

If running into issues, see our Mobile Troubleshooting Guide.

Try our example projects on our Github repository.

If stuck, contact support directly or email [email protected] for help.

For faster assistance, please provide:

  • Your OneSignal App ID
  • Details, logs, and/or screenshots of the issue.
  • Steps to reproduce

Users & subscriptions

Required if using integrations.
Recommended for messaging across multiple channels (push, email, sms).

If you need user consent before tracking their data. OneSignal provides user consent methods to help delay initialization of our SDK until consent is provided. See Handling Personal Data for details.

External ID & aliases

When a user downloads and opens your mobile app or uninstalls and re-installs your app on the same device, a Subscription and a User is created within the OneSignal app.

You can identify that user across multiple subscriptions by setting the External ID property. The External ID should be distinct user ID representing a single user. We recommend using the same user ID as in your Integrations or main analytics tool.

When you authenticate users in your app, call our login method at any time to link this subscription to a user.

let externalId = "123456789" // You will supply the external id to the OneSignal SDK
OneSignal.login(externalId)
NSString* externalUserId = @"123456789"; // You will supply the external user id to the OneSignal SDK
[OneSignal login:externalUserId];

Our mobile SDKs have methods for detecting User state changes that might be helpful for internal tracking.

📘

External ID & custom aliases

If your users have multiple user IDs, we do support additional custom Aliases. However, you should still always set the External ID as this is the main alias we use to identify users. See Users for details.

🚧

iOS development: APNS environments

Apple (APNS) has 2 different environments in which it will generate a push tokens: production and development. Each iOS Subscription in OneSignal has the test_type property with 0 or null for production and 1 for development.

When testing your app on development environments, APNS will assign a development push token to the iOS Subscription which will set test_type to 1. Subscriptions with this type of setup can only receive notifications sent directly to them.

Once you start sending to iOS Subscriptions with production environment push tokens (test_type is null or 0), you will not be able to send to your development push tokens anymore. You will need to re-install the app on the device using the production environment and you will get a new Subscription ID.

Add email and phone number subscriptions

Recommended if using email and SMS messaging.

Like push subscriptions, email addresses and phone numbers each are a new subscription within OneSignal. Your email and sms subscriptions will be tied to the same user if created using our SDK or if you setting the External ID. You can Import your current user data and use our APIs and/or SDK methods to capture new email addresses and phone numbers when provided to you by your users.

// Pass in email provided by customer
OneSignal.User.addEmail("[email protected]")

// Pass in phone number provided by customer
OneSignal.User.addSms("+11234567890")

// Pass in email provided by customer
[OneSignal.User addEmail:@"[email protected]"];

// Pass in phone number provided by customer
[OneSignal.User addSms:@"+11234567890"];

📘

Users & subscriptions

See Users and Subscriptions for more details.

Property & event tags

Tags are custom key : value pairs of String data used for tracking any custom user events and properties. Setting tags is required for more complex Segments and Message Personalization.

For event triggered messages, use tags with Time Operators to note the date and time the event is/occurred and setup automations for sending to those users. See Abandoned Cart Example for details.

OneSignal.User.addTag(key: "key", value: "value")
[OneSignal.User addTagWithKey:@"key" value:@"value"];

📘

Data tags

If you want to store custom data within OneSignal for segmentation, message personalization, and event triggered automation, see Tags for details.

Importing users and subscriptions

If you have a list of user data from a previous source, you can import it into OneSignal following our Import guides.


Message configuration

Common setup items to get the most of your integration.

Deep linking

See our Deep Linking guide to set those up for push and other messaging channels.

iOS customizations

For a list of other things you can do, see our iOS Customizations page.



👍

Basic SDK setup complete!

For details on the above methods and other methods available, see our Mobile SDK reference.