iOS SDK setup
How to add push notifications and in-app messages to your iOS app with OneSignal.
Overview
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 integrating our SDK into your iOS app.
Requirements
- Xcode 14+ (Setup instructions use Xcode 16.2).
- iOS 12+ or iPadOS 12+ device (iPhone, iPad, iPod Touch). Xcode simulator works running iOS 16.2+.
- Configured OneSignal app and platform.
Configure your OneSignal app and platform
Required
Before enabling push notifications, make sure your app is set up with the platforms you support— Apple (APNS), Google (FCM), Huawei (HMS), and/or Amazon (ADM). Follow the steps below to configure your OneSignal account and platform settings.
If your team already has a OneSignal account, ask to be invited as an admin role so you can configure the app. Otherwise, sign up for a free account to get started.
Details on configuring your OneSignal app (click to expand)
You can configure multiple platforms (iOS, Android, Huawei, Amazon) within a single OneSignal app.
1. Create or select your app
- Select your app and go to Settings > Push & In-App to add platforms to an existing app.
- Or create a new app by clicking New App/Website.

Example shows creating a new app.
2. Set up and activate a platform
- If creating an app, choose a recognizable app and organization name.
- Select a platform to activate.
- Click Next: Configure Your Platform.

Example setting up your first OneSignal app, org, and channel.
3. Configure platform credentials
Follow the prompts based on your platforms:
- Android: Set up Firebase Credentials
- iOS: p8 Token (Recommended) or p12 Certificate
- Amazon: Generate API Key
- Huawei: Authorize OneSignal
Click Save & Continue after entering your credentials.
4. Choose target SDK
Select your app's target SDK and click Save & Continue.

Select which SDK you are using to be navigated to the docs.
5. Install SDK and save your App ID
You’ll be shown your OneSignal App ID — make sure to save it, as you’ll need it during SDK installation.
If needed, invite a teammate or developer by clicking Invite, then click Done.

Save your App ID for SDK setup and invite any more team members.
Continue through the rest of our documentation to complete the integration.
iOS setup
The following steps are required for adding push notifications to iOS notifications including images, Badges, and Confirmed Delivery.
1. Add Push Notifications capability to App Target
The Push Notifications capability allows your app to register a push token, granting the ability to receive push notifications. For more details, see Apple's Enable the push notifications capability docs.
Select your App Target > Signing & Capabilities. If you do not see the "Push Notifications" capability, click + Capability and add Push Notifications.

The App Target is given Push Notifications capability.
2. Add Background Modes capability to app target
The Remote notifications Background Modes option allows notifications to wake your app and update it silently in the background. For more details, see Apple's Pushing background updates to your App docs.
Click + Capability again and add Background Modes. Then check Remote notifications.

The app target is given Remote Notifications background execution mode.
3. Add App Target to App Group
The App Groups capability allows communication with the Notification Service Extension (next step) and is required for confirmed delivery and badges. For more details, see Apple's Configuring app groups doc.
If your app is already associated with an App Group, see Use custom App Group name.
Already using App Groups? (Click to expand...)
Use custom App Group name
By default, our SDK expects your App Group to be named in the specific format group.your_bundle_id.onesignal
, but you can also specify a custom name.
Simply add a property named OneSignal_app_groups_key
in your Info.plist and set its value to any valid container name.

Custom app group set inside the main targetInfo.plist
.
If you do not have an App Group, click + Capability again and add App Groups.
In the App Groups capability click + and add the identifier in format:
group.your_bundle_id.onesignal
Including the group.
and .onesignal
prefix and suffix is required unless using a custom app group name.
For example, given the bundle identifier com.onesignal.MyApp
, the container name should be set to group.com.onesignal.MyApp.onesignal
then press OK. You may need to click the refresh circle arrow to make sure it syncs.
Bundle identifier exact matching
Your App Group container name must exactly match your bundle identifier's spelling and capitalization. This applies to all related targets and apps sharing the container.

The App Target is part of the App Group.
4. Add Notification Service Extension
The Notification Service Extension (NSE) allows your iOS application to receive rich notifications with images, buttons, and badges. It's also required for OneSignal's Confirmed Delivery analytics features. For more details, see Apple's Modifying content in newly delivered notifications docs.
In Xcode Select File > New > Target...
Select Notification Service Extension then Next.

Select the Notification Service Extension target.
Enter the product name as OneSignalNotificationServiceExtension
and press Finish.

Name the Notification Service Extension OneSignalNotificationServiceExtension
.
Do not activate the scheme on the dialog that is shown after selecting "Finish".
Press Don't Activate 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).
Select the OneSignalNotificationServiceExtension Target and General settings.
Set Minimum Deployments to be the same value as your App Target. iOS 15 or higher is recommended.

Set the OneSignalNotificationServiceExtension Target Minimum Deployments value to be the same as your App Target.
Note your minimum deployment target
It is important to maintain the same minimum deployment target across your Targets.
If using Cocoapods, you may need to set this in your Podfile as well.
5. Add NSE Target to App Group
All Targets that belong to a single App Group must use the same identifier.
Select OneSignalNotificationServiceExtension > Signing & Capabilities > + Capability > App Groups, then add the same App Group identifier as your App Target.
Important: Use the exact same App Group name you set in step 3. Add App Target to App Group. Do not use the OneSignalNotificationServiceExtension bundle ID for the App Group.
You may need to click the refresh circle arrow to make sure it syncs.

The NSE now belongs to the same App Group as your App Target.
6. Update NSE code
In the project navigator, select the OneSignalNotificationServiceExtension folder and open the NotificationService.swift
or NotificationService.m
file.

Navigate to your NotificationService file.
Replace its contents with the following code and save.
import UserNotifications
import OneSignalExtension
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var receivedRequest: UNNotificationRequest!
var bestAttemptContent: UNMutableNotificationContent?
// Note this extension only runs when `mutable_content` is set
// Setting an attachment or action buttons automatically sets the property to true
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
// print("Running NotificationServiceExtension")
// bestAttemptContent.body = "[Modified] " + bestAttemptContent.body
OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler)
}
}
override func serviceExtensionTimeWillExpire() {
// 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
// Note, this extension only runs when mutable-content is set
// Setting an attachment or action buttons automatically adds this
- (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
// NSLog(@"Running NotificationServiceExtension");
// self.bestAttemptContent.body = [@"[Modified] " stringByAppendingString:self.bestAttemptContent.body];
[OneSignalExtension didReceiveNotificationExtensionRequest:self.receivedRequest
withMutableNotificationContent:self.bestAttemptContent
withContentHandler:self.contentHandler];
}
- (void)serviceExtensionTimeWillExpire {
// 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
At this step you will see an error. This is OK and will resolve when adding the OneSignal package to the OneSignalNotificationServiceExtension target.

The NotificationService
file will show an error until we install the package as shown in the next step.
SDK setup
This section will guide you through integrating OneSignal's core features. By the end of this section, you will have a basic integration with our SDK enabling you to trigger in-app messages and receive push notifications.
1. Add SDK
Add our SDK using Xcode Package Dependencies Manager or CocoaPods. There are 4 available libraries. If you do not want In-app messages and/or Location-triggered notifications you can omit those packages.
Library | Required | Target |
---|---|---|
OneSignalExtension | ✅ | OneSignalNotificationServiceExtension |
OneSignalFramework | ✅ | App |
OneSignalInAppMessages | Recommended | App |
OneSignalLocation | Optional | App |
Using CocoaPods? (Click to expand...)
Add SDK with CocoaPods
Requirements: CocoaPods 1.16.2+ (Setup instructions use CocoaPods 1.16.2).
Open your Podfile
and add the following:
# If platform is uncommented, set to the same value as your minimum deployment target in Xcode
# platform :ios, '15.0'
target 'your_project_name' do
pod 'OneSignal/OneSignal', '>= 5.2.9', '< 6.0'
# If your app does not use In-App messages, you can remove this:
pod 'OneSignal/OneSignalInAppMessages', '>= 5.2.9', '< 6.0'
# If your app does not use CoreLocation, you can remove this:
pod 'OneSignal/OneSignalLocation', '>= 5.2.9', '< 6.0'
# Your other pods here
end
target 'OneSignalNotificationServiceExtension' do
pod 'OneSignal/OneSignal', '>= 5.2.9', '< 6.0'
end
Add the dependencies to your main app target and OneSignalNotificationServiceExtension target. If platform
is uncommented, make sure it is the same value as the minimum deployment target in Xcode.
Run the following command to pull down the OneSignal iOS SDK pod and add it to your project:
pod repo update && pod install
Once the installation is complete, make sure to open the XCWorkspace file named after your project (e.g., <project-name>.xcworkspace
)
Always open the workspace
When using the OneSignal iOS SDK pod, you must exclusively use the
.xcworkspace
file to open the project.
Add SDK with Xcode Package Dependencies
Navigate to File > Add Package Dependencies... and enter the URL to the OneSignal iOS SDK repository:
https://github.com/OneSignal/OneSignal-iOS-SDK
Select the onesignal-ios-sdk package and click Add Package.
Choose Package Products for OneSignal-iOS-SDK.
- Important: Add the OneSignalExtension to the OneSignalNotificationServiceExtension Target.
- Add the OneSignalFramework to your App Target.
- If you plan on using in-app messages (recommended) and/or location tracking, then add those packages to your App Target as well.

If your app doesn't require location tracking, you can remove the OneSignalLocation
package as shown in this example.
For more details, see Apple's Adding package dependencies doc.
2. Initialize SDK
Depending on your Xcode interface setup, initialize OneSignal following these options.
Using SwiftUI? (Click to expand...)
Initialize SDK (SwiftUI)
If using SwiftUI interface, navigate to your <APP_NAME>App.swift
file and initialize OneSignal with the provided methods.
Replace YOUR_APP_ID
with your OneSignal App ID found in your OneSignal dashboard Settings > Keys & IDs. If you don't have access to the OneSignal app, ask your Team Members to invite you.
import SwiftUI
import OneSignalFramework
@main
struct YOURAPP_NAME: App {
//Connect the SwiftUI app to the UIKit app delegate
@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 {
// Enable verbose logging for debugging (remove in production)
OneSignal.Debug.setLogLevel(.LL_VERBOSE)
// Initialize with your OneSignal App ID
OneSignal.initialize("YOUR_APP_ID", withLaunchOptions: launchOptions)
// Use this method to prompt for push notifications.
// We recommend removing this method after testing and instead use In-App Messages to prompt for notification permission.
OneSignal.Notifications.requestPermission({ accepted in
print("User accepted notifications: \(accepted)")
}, fallbackToSettings: false)
return true
}
}
Using Storyboard? (Click to expand...)
Initialize SDK (Storyboard)
If using Storyboard interface, navigate to your AppDelegate file and initialize OneSignal with the provided methods.
Replace YOUR_APP_ID
with your OneSignal App ID found in your OneSignal dashboard Settings > Keys & IDs. If you don't have access to the OneSignal app, ask your Team Members to invite you.
import UIKit
import OneSignalFramework
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Enable verbose logging for debugging (remove in production)
OneSignal.Debug.setLogLevel(.LL_VERBOSE)
// Initialize with your OneSignal App ID
OneSignal.initialize("YOUR_APP_ID", withLaunchOptions: launchOptions)
// Use this method to prompt for push notifications.
// We recommend removing this method after testing and instead use In-App Messages to prompt for notification permission.
OneSignal.Notifications.requestPermission({ accepted in
print("User accepted notifications: \(accepted)")
}, fallbackToSettings: false)
return true
}
// Remaining contents of your AppDelegate Class...
}
#import <OneSignalFramework/OneSignalFramework.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Enable verbose logging for debugging (remove in production)
[OneSignal.Debug setLogLevel:ONE_S_LL_VERBOSE];
// Initialize with your OneSignal App ID
[OneSignal initialize:@"YOUR_APP_ID" withLaunchOptions:launchOptions];
// Use this method to prompt for push notifications.
// We recommend removing this method after testing and instead use In-App Messages to prompt for notification permission.
[OneSignal.Notifications requestPermission:^(BOOL accepted) {
NSLog(@"User accepted notifications: %d", accepted);
} fallbackToSettings:false];
// Login your customer with externalId
// [OneSignal login:@"EXTERNAL_ID"];
return YES;
}
Testing
This guide will help you verify that your OneSignal SDK integration is functioning correctly. You'll test push notifications, subscription management, and in-app messaging.
Check mobile subscriptions
- Launch your app on a test device.
- You should immediately see the native push permission prompt because of the
requestPermission
method added in the initialization step above. - IMPORTANT: Before responding to the prompt, check your OneSignal dashboard:
- Navigate to Audience > Subscriptions.
- You should see a new entry with status "Never Subscribed".

An iOS device and an Android device showing the native push permission prompts

The Subscriptions page of the OneSignal dashboard showing a subscription with "Never Subscribed" status
- Return to the app and tap "Allow" on the permission prompt.
- Refresh your OneSignal dashboard Subscription's page.
- The subscription's status should now show "Subscribed".

The Subscriptions page of the OneSignal dashboard showing a subscription with "Subscribed" status
Setup test subscriptions
Test subscriptions are helpful for testing a push notification before sending a message.
Next to the subscription, click Options (three dots button) and select Add to Test Subscriptions.

Name your subscription so you know its your device and can find it in the Test Subscriptions page.

Create a test users segment
To test push and in-app messages faster, navigate to Audience > Segments > New Segment.
Name the segment Test Users
(the name is important because it will be used later) and add the Test Users filter. Click Create Segment when finished.

Screenshot of a segment utilizing the "Test Users" filter
Send test push via API
Test sending a push notification via our API.
In your OneSignal dashboard, navigate to Settings > Keys & IDs. Copy the following code into your terminal, replacing YOUR_APP_API_KEY
and YOUR_APP_ID
with the correct IDs found in Keys & IDs.
curl -X \
POST --url 'https://api.onesignal.com/notifications' \
--header 'content-type: application/json; charset=utf-8' \
--header 'authorization: Key YOUR_APP_API_KEY' \
--data \
'{
"app_id": "YOUR_APP_ID",
"target_channel": "push",
"name": "Testing basic setup",
"headings": {
"en": "👋"
},
"contents": {
"en": "Hello world!"
},
"included_segments": [
"Test Users"
],
"ios_attachments": {
"onesignal_logo": "https://avatars.githubusercontent.com/u/11823027?s=200&v=4"
},
"big_picture": "https://avatars.githubusercontent.com/u/11823027?s=200&v=4"
}'
Check images and confirmed delivery
If all setup steps were completed successfully, the test devices should receive a notification with an image included:

iOS and Android devices displaying message sent from API
After the message is received, in your OneSignal dashboard, go to Delivery > Sent Messages and click on the message to see the message report.
You should see the confirmed stat, meaning the device received the push.

Screenshot showing the delivery statistics page for the sent message
If on our Professional plan or higher, you can scroll down to the Audience Activity section to see the confirmed delivery for individual devices:

Screenshot showing the Audience Activity report for the sent message
Send an in-app message
In-app messages are a great way to communicate information at specific points while users are in your app.
- Close or background your app on the device.
- In your OneSignal dashboard, navigate to Messages > In-App > New In-App.
- Find and select the Welcome message.
- Set your Audience as the Test Users segment we used previously.

Audience of the "Welcome" in-app message targeting the "Test Users" segment
- Add any quick customizations you want.

Edited version of the "Welcome" in-app message
- Verify the Trigger is set to On app open.
- Under Schedule > How often do you want to show this message? select Every time trigger conditions are satisfied.
- Click Make Message Live so it is available to your Test Users each time they open the app.

Schedule of the "Welcome" in-app message set to show "Every time trigger conditions are satisfied"
- After the in-app message is live, open your app. You should see it display:

The "Welcome" in-app message displayed on an iOS and Android device
If you did not see the in-app message:
Make sure you started a new session.
In step 1, we mentioned you need to close or background your app on the device. This is because users must meet the in-app audience criteria before a new session starts. In OneSignal, a new session starts when the user opens your app after it has been in the background or closed for at least 30 seconds. For more details, see our guide on how in-app messages are displayed.
Put the app into the background or close it. Wait 30 seconds, then open the app again. It should appear.
Make sure you are still in the Test Users segment.
If you uninstalled the app and re-installed it or testing on a different device, make sure to set the new subscription as a test subscription. Then try again. See Subscriptions for more details.
Still having issues?
Follow Getting a Debug Log while reproducing the steps above. This will generate additional logging that you can share with [email protected] and we will help investigate what's going on.
Testing complete!
You have successfully setup the OneSignal SDK and learned important concepts like:
- Gathering Subscriptions, setting Test subscriptions, and creating Segments.
- Sending Push with images and Confirmed Delivery using Segments and our Create message API.
- Sending In-app messages.
Continue with this guide to identify users in your app and setup additional features.
User identification
Previously we demonstrated the concept of Subscriptions by creating a mobile subscription. Now we will take a look at how to identify Users across all their subscriptions including how to create email and sms subscriptions via the SDK.
Assign External ID
Assign users an External ID to reference them using your backend's identifier. The External ID should be readily available in your app and map to other 3rd party systems you may be using to identify users. This is especially important for Integrations.
Set the External ID with our SDK's login
method each time they are identified by your app.
Subscription ID, OneSignal ID, & External ID
OneSignal generates unique read-only IDs for subscriptions (Subscription ID) and users (OneSignal ID).
As users download your app on different devices, subscribe to your website, and/or provide you email addresses and phone numbers outside of your app, new subscriptions will be created.
Setting the External ID via our SDK is highly recommended to identify users across all their subscriptions, regardless of how they are created.
Add data tags
Data Tags (or just "tags") are used to set user properties and track events. They enable Message Personalization and more unique Segmentation allowing for more advanced use cases.
Set tags with our SDK addTag(s)
methods and see our Tags guide for more details.
In this example, the app has added the user's current in-game level as a tag called current_level
set to a value of 6
:

A user profile in OneSignal with a tag called "current_level" set to "6"
We can create a segment of users that have a level of between 5 and 10, and use that to send targeted and personalized messages:

Segment editor showing a segment targeting users with a current_level value of greater than 4 and less than 10

Screenshot showing a push notification targeting the Level 5-10 segment with a personalized message

The push notification is received on an iOS and Android device with the personalized content
Add email and/or SMS subscriptions
Earlier we saw how our SDK creates mobile Subscriptions to send push and in-app messages. You can also reach users through emails and SMS channels by creating the appropriate subscriptions.
When users provide consent to receive additional communication types, use our SDK addEmail
method and addSms
method to create these subscriptions.
Best practices for multi-channel communication
- Obtain explicit consent before adding email or SMS subscriptions.
- Explain the benefits of each communication channel to users.
- Provide channel preferences so users can select which channels they prefer.
After adding subscriptions under and External ID, you can view all channels associated with each user in the OneSignal dashboard Audience > Users > Find their External ID or using the View user API.

A user profile with push, email, and SMS subscriptions, unified by the external ID.
Privacy
If you want to prevent OneSignal from collecting user data until user consent is provided, you can implement the setConsentRequired()
method. When you or the user is ready to send our servers data, call the setConsentGiven()
method.
See our Privacy & security docs for more details including Data Collected by the OneSignal SDK and Handling Personal Data.
Prompt for push permissions
While we showed the requestPermission
method earlier in the setup code, we recommend a more strategic approach to asking for push permissions.
Instead of prompting immediately on app open, use in-app messages to explain the benefits of push notifications before requesting permission.
For best practices and implementation details, see our Prompt for push permissions guide.
Listen to push, user, and in-app events
The SDK provides several event listeners for you to hook into. See our SDK reference guide for more details.
Handling push clicks and foreground events
Track when users interact with push notifications using the addClickListener
method. This is helpful for Deep Linking.
Control notification behavior when your app is in the foreground using the addForegroundLifecycleListener
method with preventDefault
to conditionally decide to display it or not.
If you want to customize the notification before it is displayed to the user, see the Mobile Service Extensions docs for details.
Listening to user state changes
Track when the External ID is set with the addObserver()
method for user state . This is a good place to collect the OneSignal ID and/or Subscription ID if needed.
Track the user's specific interaction with the push permission prompt with the addPermissionObserver()
method.
Track when the push subscription status changes with the addObserver()
method for push.
Listen and handle in-app message events
Track when and how the user interacts with in-app messages with the addClickListener()
method for in-app. This is a good place for Deep Linking with in-app messages or doing something custom when specific elements are clicked.
If you are interested in tracking the in-app message lifecycle from before it is displayed to after it is dismissed, use the addLifecycleListener()
method.
Advanced
Review the Mobile push setup doc to make sure you are setting up all the features. Common examples:
- Migrating to OneSignal from another service – If you are moving to OneSignal or need to use multiple push SDKs in your app.
- Location tracking – Setup and ask permission to track user location points for segmentation.
- Deep Linking – Direct users to specific app content when interacting with notifications.
- Integrations – Setup Mixpanel, Amplitude, HubSpot, Segment, and more!
- Mobile Service Extensions – Customizing the notification before it is displayed.
- Action buttons – Add custom actions to your notifications instead of just opening the app.
- Multi-language messaging - How to send messages in different languages.
- Identity Verification – Prevent bad actors from impersonating your users.
- Custom Outcomes – Track user actions from notifications, such as purchases.
- Live Activities – Another messaging channel to update iOS users in real time.
Updated 15 days ago