iOS Quickstart
This guide walks you through integrating PushEngage push notifications into a native iOS application. Estimated time: 15 minutes.
After completing this guide, your app will receive push notifications with rich media support. See the iOS SDK Reference for the full API.
Prerequisites
- Xcode installed
- Apple Developer account with a valid App ID configured on the Apple Developer Portal
- APNs certificate (.p12) (create one)
- PushEngage account and App ID (see Get Your App ID)
Step 1 — Install the SDK
Choose either Swift Package Manager or CocoaPods. Use only one method.
- Swift Package Manager
- CocoaPods
- In Xcode, go to File → Add Package Dependencies.
- Paste
https://github.com/awesomemotive/pushengage-ios-sdkinto the search bar. - Click Add Package.
- Under Add to Target, select your main app target.
- Click Add Package.
If CocoaPods is not installed, run:
sudo gem install cocoapods
Initialize a Podfile in your project root:
pod init
Add the PushEngage dependency to your Podfile:
target 'YourProjectName' do
use_frameworks!
pod 'PushEngage'
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
end
end
end
end
Install the pods:
pod repo update
pod install
Open the generated .xcworkspace file in Xcode going forward (not .xcodeproj).
Step 2 — Configure Xcode Capabilities
Enable Push Notifications
- In Xcode, select the root project in the Project Navigator and choose your main app target.
- Go to Signing & Capabilities.
- Click + Capability and add Push Notifications.
If Push Notifications is not visible in Xcode: go to your Apple Developer account → Certificates, Identifiers & Profiles → select your App ID → enable Push Notifications → return to Xcode and try again.
Enable Background Modes
- Click + Capability and add Background Modes.
- Check both Remote notifications and Background fetch.
Step 3 — Connect to PushEngage Dashboard
- Log in to your PushEngage Dashboard.
- Navigate to Site Settings → Installation → iOS SDK.
Under "1. Configure your Apple iOS APNs settings":
- Enter your App Push Id (your iOS Bundle Identifier, e.g.
com.example.MyApp). - Upload your APNs Certificate (.p12).
- Enter the Private Key Password you set when exporting the .p12.
- Click Update.
Under "2. Install the SDK":
- Click Copy next to the App ID — you'll pass it to
setAppIDin the next step.
Step 4 — Initialize the SDK
Add PushEngage initialization to your AppDelegate:
- Swift
- Objective-C
- SwiftUI
import UIKit
import PushEngage
class AppDelegate: UIResponder, UIApplicationDelegate {
override init() {
super.init()
PushEngage.swizzleInjection(isEnabled: true)
}
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
PushEngage.setAppID(id: "YOUR_APP_ID")
PushEngage.setInitialInfo(for: application, with: launchOptions)
PushEngage.enableLogging = true
return true
}
}
#import "AppDelegate.h"
@import PushEngage;
@implementation AppDelegate
- (instancetype)init {
self = [super init];
if (self) {
[PushEngage swizzleInjectionWithIsEnabled:YES];
}
return self;
}
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[PushEngage setAppIdWithKey:@"YOUR_APP_ID"];
[PushEngage setInitialInfoFor:application with:launchOptions];
[PushEngage setEnableLogging:YES];
return YES;
}
@end
import SwiftUI
import PushEngage
@main
struct YourApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
override init() {
super.init()
PushEngage.swizzleInjection(isEnabled: true)
}
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
PushEngage.setAppID(id: "YOUR_APP_ID")
PushEngage.setInitialInfo(for: application, with: launchOptions)
PushEngage.enableLogging = true
return true
}
}
Replace YOUR_APP_ID with the App ID copied in Step 3.
Remove or set PushEngage.enableLogging = false before releasing to production. Leaving it enabled exposes internal SDK data in production app logs.
Step 5 — Send a Test Notification
- Build and run your app on a physical iOS device — push notifications do not work in the simulator.
- Accept the notification permission prompt when it appears.
- In the PushEngage Dashboard, go to Campaign → Push Broadcasts → Create New Push Broadcast.
- Send a test notification to yourself.
You should receive the notification within a few seconds. Your integration is complete. To unlock rich notifications and images, continue with the steps below.
Enable Rich Notifications
The following steps enable rich notifications (images, action buttons) and app badge sync. They require adding iOS extension targets to your Xcode project.
Step 6 — Add Notification Service Extension
The Notification Service Extension enables rich notifications (images, action buttons). It is required for full PushEngage functionality.
Create the Extension
- In Xcode, go to File → New → Target.
- Select Notification Service Extension and click Next.
- Name it
PushEngageNotificationServiceExtensionand click Finish. - When prompted to activate the scheme, click Cancel — this keeps Xcode's debugging focus on your main app.
- Select the new extension target in the Project Navigator and set its Deployment Target to iOS 10 or above.
Add SDK Dependency to the Extension
- Swift Package Manager
- CocoaPods
- Select your project in the navigator.
- Select the
PushEngageNotificationServiceExtensiontarget. - Go to General → Frameworks, Libraries, and Embedded Content.
- Click +, find
PushEngage, and add it.
Update your Podfile to add the extension target:
target 'YourProjectName' do
use_frameworks!
pod 'PushEngage'
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
end
end
end
target 'PushEngageNotificationServiceExtension' do
pod 'PushEngage'
end
end
Run:
pod repo update
pod install
Implement the Extension
Replace the auto-generated NotificationService.swift with:
import UserNotifications
import PushEngage
@available(iOSApplicationExtension 10.0, *)
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
var request: UNNotificationRequest?
override func didReceive(
_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
) {
self.request = request
self.contentHandler = contentHandler
self.bestAttemptContent = request.content.mutableCopy() as? UNMutableNotificationContent
if let bestContent = bestAttemptContent {
PushEngage.didReceiveNotificationExtensionRequest(request, bestContentHandler: bestContent)
contentHandler(bestContent)
}
}
override func serviceExtensionTimeWillExpire() {
if let contentHandler = contentHandler,
let request = request,
let bestAttemptContent = bestAttemptContent {
guard let content = PushEngage.serviceExtensionTimeWillExpire(
request, content: bestAttemptContent
) else {
contentHandler(bestAttemptContent)
return
}
contentHandler(content)
}
}
}
Step 7 — Add Notification Content Extension (Optional)
The Notification Content Extension renders the custom expanded UI for PushEngage notifications sent with a matching category. Without it, notifications still deliver normally, but any custom expanded layout falls back to iOS's default view.
Create the Extension
- In Xcode, go to File → New → Target.
- Select Notification Content Extension and click Next.
- Name it
PushEngageNotificationContentExtensionand click Finish. - When prompted to activate the scheme, click Cancel.
- Set the Deployment Target to iOS 10 or above.
- Open the extension's
Info.plist. Under NSExtension → NSExtensionAttributes → UNNotificationExtensionCategory, set the array to contain the category identifier(s) you'll send with custom-UI notifications (must match thecategoryIdentifiercheck in your extension code).
Add SDK Dependency (CocoaPods only)
Add to your Podfile:
target 'PushEngageNotificationContentExtension' do
use_frameworks!
pod 'PushEngage'
end
Run pod install.
Implement the Extension
import UIKit
import UserNotifications
import UserNotificationsUI
import PushEngage
@available(iOSApplicationExtension 10.0, *)
class NotificationViewController: UIViewController, UNNotificationContentExtension {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
}
func didReceive(_ notification: UNNotification) {
if notification.request.content.categoryIdentifier == "your_category_identifier" {
let payload = PushEngage.getCustomUIPayLoad(for: notification.request)
// Pass payload to your custom SwiftUI or UIKit view
}
}
}
Step 8 — Add App Groups
App Groups enable communication between the main app and notification extensions. This step is required.
- Select your main app target in Xcode → Signing & Capabilities → + Capability → App Groups.
- Click + to add a new App Group with a unique name, e.g.,
group.com.yourcompany.yourapp. - In your main app target's
Info.plist, add:- Key:
PushEngage_App_Group_Key - Value:
group.com.yourcompany.yourapp
- Key:
- In
PushEngageNotificationServiceExtension'sInfo.plist, add the same key and value. - Select the extension target → Signing & Capabilities → enable the same App Group.
Troubleshooting
Build error: User Script Sandboxing
In Xcode → Build Settings → search for User Script Sandboxing → set to No.
Conflict between Firebase SDK and PushEngage swizzling
Disable PushEngage swizzling and wire up all four delegate methods below — omitting any one will silently break notifications, click tracking, or foreground display:
// In AppDelegate.init()
PushEngage.swizzleInjection(isEnabled: false)
// In AppDelegate
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
PushEngage.registerDeviceToServer(with: deviceToken)
}
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
PushEngage.receivedRemoteNotification(application: application,
userInfo: userInfo,
completionHandler: completionHandler)
}
// Set yourself as UNUserNotificationCenter delegate, then:
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler:
@escaping (UNNotificationPresentationOptions) -> Void) {
PushEngage.willPresentNotification(center: center,
notification: notification,
completionHandler: completionHandler)
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
PushEngage.didReceiveRemoteNotification(with: response)
completionHandler()
}