Overview
This guide explains how to integrate OneSignal push notifications into a .NET MAUI application. It covers everything from installation to configuration and service worker management.Requirements
- .NET 7.0+
- Visual Studio 2019 or newer
- Configured OneSignal app and platform
- macOS with Xcode 14+ (setup instructions use Xcode 16.2)
- Device with iOS 12+, iPadOS 12+, or Xcode simulator running iOS 16.2+
- CocoaPods 1.16.2+
- Android 7.0+ device or emulator with Google Play Store (Services) installed
Configure your OneSignal app and platform
Configure your OneSignal app with the platforms you support — Apple (APNs), Google (FCM), Huawei (HMS), and/or Amazon (ADM).SDK Setup
1. Add SDK
Using the .NET CLI: dotnet add package OneSignalSDK.DotNet
Optional: Disable the location module
Starting withOneSignalSDK.DotNet 6.2.0, you can exclude OneSignal’s native location module from iOS and Android builds when your app does not use location features. By default, OneSignalSDK.DotNet includes the native location module so OneSignal.Location works without extra setup.
Add the OneSignalDisableLocation MSBuild property to your app project:
<PropertyGroup>
<OneSignalDisableLocation>true</OneSignalDisableLocation>
</PropertyGroup>
OneSignal.Location.RequestPermission() and OneSignal.Location.IsShared = value no-op on native builds without the location module. OneSignal.Location.IsShared returns false.
For regular development, make sure the property is set for the app build that consumes the SDK. If you build from source with project references or scripts, pass the property to dotnet build so it applies to the referenced SDK projects too:
dotnet build -f net10.0-ios -p:OneSignalDisableLocation=true
dotnet build -f net10.0-android -p:OneSignalDisableLocation=true
OneSignalDisableLocation value in build cache keys or clean build outputs when toggling it. This avoids restoring stale iOS app bundles, Android intermediates, or bin/obj outputs that were produced with the location module enabled.
OneSignalDisableLocation is an MSBuild-only setting. Gradle properties are not supported for disabling the .NET SDK location module.2. Initialize SDK
Initialize OneSignal inApp.xaml.cs file.
Replace YOUR_APP_ID with your OneSignal App ID found in your OneSignal dashboard Settings > Keys & IDs.
using OneSignalSDK.DotNet;
using OneSignalSDK.DotNet.Core;
using OneSignalSDK.DotNet.Core.Debug;
public App() {
InitializeComponent();
// Enable verbose OneSignal logging to debug issues if needed.
OneSignal.Debug.LogLevel = LogLevel.VERBOSE;
// OneSignal Initialization
OneSignal.Initialize("YOUR_APP_ID");
// RequestPermissionAsync will show the notification permission prompt.
// We recommend removing the following code and instead using an In-App Message to prompt for notification permission (See step 5)
OneSignal.Notifications.RequestPermissionAsync(true);
MainPage = new AppShell();
}
3. Adding an iOS Service Extension
Microsoft has a guide on generating a Notification Service Extension here, using Visual Studio and Visual Studio for Mac, but does not have any guidance on how you would create this for VSCode at this time. If you generate a service extension following the guide above, you can follow this the code in our sample project found on Githubusing System;
using Foundation;
using OneSignalSDK.DotNet;
using OneSignalSDK.DotNet.iOS;
using UIKit;
using UserNotifications;
namespace OneSignalNotificationServiceExtension
{
[Register("NotificationService")]
public class NotificationService : UNNotificationServiceExtension
{
Action<UNNotificationContent> ContentHandler { get; set; }
UNMutableNotificationContent BestAttemptContent { get; set; }
UNNotificationRequest ReceivedRequest { get; set; }
protected NotificationService(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
public override void DidReceiveNotificationRequest(UNNotificationRequest request, Action<UNNotificationContent> contentHandler)
{
ReceivedRequest = request;
ContentHandler = contentHandler;
BestAttemptContent = (UNMutableNotificationContent)request.Content.MutableCopy();
NotificationServiceExtension.DidReceiveNotificationExtensionRequest(request, BestAttemptContent, contentHandler);
}
public override void TimeWillExpire()
{
// 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.
NotificationServiceExtension.ServiceExtensionTimeWillExpireRequest(ReceivedRequest, BestAttemptContent);
ContentHandler(BestAttemptContent);
}
}
}
Android setup
Make sure your OneSignal app is configured for the Android platform using your Firebase credentials. Set up your notification icons to match your app’s branding. If this step is skipped, a default bell icon will display for your push notifications. Build for Android At this point, you should be able to build and run your app on a physical Android device or emulator without issues.- Continue with the iOS setup, if applicable.
- Or jump ahead to Testing the OneSignal SDK integration.
iOS setup
Make sure your OneSignal app is configured for the iOS platform using either the p8 Token (Recommended) or p12 Certificate. Follow these steps to add push notifications to your iOS app, including support for Badges, Confirmed receipt, and images.1. Add Push Notifications capability to app target
The Push Notifications capability allows your app to register a push token and receive notifications.- Open your app’s
.xcworkspacefile in Xcode. - Select your app target > Signing & Capabilities
- Click + Capability and add Push Notifications capability
2. Add Background Modes capability to app target
This enables your app to wake in the background when push notifications arrive.- Add Background Modes capability
- Enable Remote notifications
3. Add app target to App Group
App Groups allow data sharing between your app and the Notification Service Extension. Required for confirmed receipt and Badges.- If you do NOT have an App Group configured
- If you DO have an App Group
- Add App Groups capability
- In the App Groups capability click +
- Add a new container ID in format:
group.your_bundle_id.onesignal
- Keep group. and .onesignal prefix and suffix. Replace
your_bundle_idwith your app’s bundle identifier. - For example, bundle identifier
com.onesignal.MyApp, will have the container namegroup.com.onesignal.MyApp.onesignal.
4. Add Notification Service Extension
The Notification Service Extension (NSE) enables rich notifications and confirmed receipt analytics.- In Xcode: File > New > Target…
- Select Notification Service Extension, then Next.
- Set the product name to
OneSignalNotificationServiceExtensionand press Finish. - Press Don’t Activate on the Activate scheme prompt.
5. Add NSE target to app group
Use the same App Group ID you added in step 3.- Go to OneSignalNotificationServiceExtension > Signing & Capabilities
- Add App Groups
- Add the exact same group ID
group.your_bundle_id.onesignal then make sure to add your App Group ID to both the App Target and OneSignalNotificationServiceExtension Target’s Info.plist! See step 3 for more information.6. Update NSE code
- Navigate to the OneSignalNotificationServiceExtension folder
- Replace the contents of the
NotificationService.swiftorNotificationService.mfile with the following:
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)
}
}
}
7. Add OneSignal to the NSE target
ios/Podfile to include:
target 'OneSignalNotificationServiceExtension' do
pod 'OneSignalXCFramework', '>= 5.0.0', '< 6.0'
end
cd ios pod install cd ..
Common pod install errors
You may run into the following errors, here is how you can resolve them.Build for iOS
You should now be able to build and run your app on a real iOS device or iOS simulator (16.2+).Common iOS build errors
Testing the OneSignal SDK integration
This guide helps you verify that your OneSignal SDK integration is working correctly by testing push notifications, subscription registration, and in-app messaging.- Go to Device Manager in Android Studio.
- Select your emulator device and click Edit.
- Go to Additional Settings or More.
- Set the Boot option to Cold Boot.
- Save changes and restart the emulator.
Check mobile subscriptions
Launch your app on a test device.
requestPermission method during initialization.Check your OneSignal dashboard
- Go to Audience > Subscriptions.
- You should see a new entry with the status “Never Subscribed”.
Return to the app and tap Allow on the prompt.
Refresh the OneSignal dashboard Subscription's page.
Set up test users
test users are helpful for testing a push notification before sending a message.Add to Test Users.
Name your subscription.
Create a test users segment.
Name the segment.
Test Users (the name is important because it will be used later).Add the Test Users filter and click Create Segment.
Send test push via API
Get your App API Key and App ID.
Update the provided code.
YOUR_APP_API_KEY and YOUR_APP_ID in the code below with your actual keys. This code uses the Test Users segment we created earlier.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"
}'
Run the code.
Check images and confirmed receipt.
Check for confirmed receipt.
- No image received? Your Notification Service Extension might be missing.
- No confirmed receipt? Review the troubleshooting guide here.
- Having issues? Copy-paste the api request and a log from start to finish of app launch into a
.txtfile. Then share both withsupport@onesignal.com.
Send an in-app message
In-app messages let you communicate with users while they are using your app.Close or background your app on the device.
Create an in-app message.
- 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.
Customize the message content if desired.
Set Trigger to 'On app open'.
Schedule frequency.
Make message live.
Open the app and see the message.
- Start a new session
- You must close or background the app for at least 30 seconds before reopening. This ensures a new session is started.
- For more, see how in-app messages are displayed.
- Still in the
Test Userssegment?- If you reinstalled or switched devices, re-add the device to Test Users and confirm it’s part of the Test Users segment.
- Having issues?
- Follow Getting a Debug Log while reproducing the steps above. This will generate additional logging that you can share with
support@onesignal.comand we will help investigate what’s going on.
- Follow Getting a Debug Log while reproducing the steps above. This will generate additional logging that you can share with
- Gathering Subscriptions, setting Test Users, and creating Segments.
- Sending Push with images and Confirmed receipt using Segments and our Create message API.
- Sending In-app messages.
User identification
Previously, we demonstrated how to create mobile Subscriptions. Now we’ll expand to identifying Users across all their subscriptions (including push, email, and SMS) using the OneSignal SDK. We’ll cover External IDs, tags, multi-channel subscriptions, privacy, and event tracking to help you unify and engage users across platforms.Assign External ID
Use an External ID to identify users consistently across devices, email addresses, and phone numbers using your backend’s user identifier. This ensures your messaging stays unified across channels and 3rd party systems (especially important for Integrations). Set the External ID with our SDK’slogin method each time they are identified by your app.
Add Tags
Tags are key-value pairs of string data you can use to store user properties (likeusername, role, or preferences) and events (like purchase_date, game_level, or user interactions). Tags power advanced Message Personalization and Segmentation allowing for more advanced use cases.
Set tags with our SDK addTag and addTags methods as events occur in your app.
In this example, the user reached level 6 identifiable by the tag called current_level set to a value of 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:
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 corresponding subscriptions.- Use the
addEmailmethod to create email subscriptions. - Use the
addSmsmethod to create SMS subscriptions.
- 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.
Privacy & user consent
To control when OneSignal collects user data, use the SDK’s consent gating methods:setConsentRequired(true): Prevents data collection until consent is given.setConsentGiven(true): Enables data collection once consent is granted.
Prompt for push permissions
Instead of callingrequestPermission() immediately on app open, take a more strategic approach. Use an in-app message to explain the value 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
Use SDK listeners to react to user actions and state changes. The SDK provides several event listeners for you to hook into. See our SDK reference guide for more details.Push notification events
addClickListener(): Detect when a notification is tapped. Helpful for Deep Linking.addForegroundLifecycleListener(): Control how notifications behave in foreground.
User state changes
addObserver()for user state: Detect when the External ID is set.addPermissionObserver(): Track the user’s specific interaction with the native push permission prompt.addObserver()for push subscription: Track when the push subscription status changes.
In-app message events
addClickListener(): Handle in-app click actions. Ideal for deep linking or tracking events.addLifecycleListener(): Track full lifecycle of in-app messages (shown, clicked, dismissed, etc.).
Advanced setup & capabilities
Explore more capabilities to enhance your integration:- 🔁 Migrating to OneSignal from another service
- 🌍 Location tracking
- 🔗 Deep Linking
- 🔌 Integrations
- 🧩 Mobile Service Extensions
- 🛎️ Action buttons
- 🌐 Multi-language messaging
- 🛡️ Identity Verification
- 📊 Custom Outcomes
- 📲 Live Activities
Mobile SDK setup & reference
Make sure you’ve enabled all key features by reviewing the Mobile push setup guide. For full details on available methods and configuration options, visit the Mobile SDK reference.support@onesignal.comPlease include:- Details of the issue you’re experiencing and steps to reproduce if available
- Your OneSignal App ID
- The External ID or Subscription ID if applicable
- The URL to the message you tested in the OneSignal Dashboard if applicable
- Any relevant logs or error messages
