Enable push notifications in a Cordova app (iOS)
This guide walks you through enabling push notifications in your Cordova app on iOS using the Acoustic Connect SDK.
Language: JavaScript, with TypeScript definitions. The Notification Service Extension and Notification Content Extension are implemented in Swift and ship with the plugin — you don't write or maintain this Swift code yourself.
Availability: Pro, Premium, and Ultimate
Scope: Test setup — building, running on the simulator or a connected iPhone, and verifying push delivery. Covers both automatic and manual push mode.
Sample app: See our GitHub repository for a reference implementation to compare your configuration against.
Prerequisites
- Apple Developer Program membership — push notifications require a paid account. Required role: Account Holder or Admin.
- The Connect Cordova plugin, integrated in your project with a Connect app key from a Mobile app integration created after April 2026 — earlier integrations don't support push. See Integrate the Connect SDK into a Cordova app to install the plugin first.
Overview
- Get an APNs authentication key.
- Share your push notification credentials with your Connect administrator.
- Register an App Group and enable capabilities in the Apple Developer portal.
- Configure push notifications in ConnectConfig.json.
- Build — the plugin wires up Xcode automatically.
- Add code to request notification permission from your users.
- Forward native delegate callbacks to the SDK (only if using manual push mode).
Step 1: Get an APNs authentication key
Connect uses token-based APNs authentication. A single .p8 key works across all apps in your team.
- In your Apple Developer account, go to Certificates, Identifiers & Profiles > Keys > +.
- Enter a name and enable Apple Push Notifications service (APNs).
- Click Configure, set Environment to Sandbox & Production unless your security team requires tighter scoping — this can't be changed later.
- Save > Continue > Register.
- Download the
.p8file — Apple only allows this once. - Note the Key ID and your Team ID (10-character string, top-right of the portal).
Step 2: Share push notification credentials with your Connect administrator
| Credential | Where to find it |
|---|---|
| Encryption key | The .p8 file from Step 1 |
| Key ID | The confirmation page, or the file name |
| Team ID | Top-right of the Apple Developer portal, or under Membership |
| Bundle ID | Your Cordova project's config.xml — the id attribute on the <widget> element |
| Environment | Sandbox — this guide covers test setup |
NoteYour Connect administrator needs to upload these credentials before push notifications will be delivered. See Connect mobile apps in the Connect user guide. Steps 3–5 can be completed while you wait.
Step 3: Configure the Apple Developer portal
Push notifications in Connect require three components sharing an App Group — a container that lets them exchange push data. The identifier must be identical across all three or delivery tracking and rich media silently fail.
| Component | Purpose |
|---|---|
| Main app | Initializes the SDK and requests notification permission |
| Notification Service Extension (NSE) | Downloads rich media and records delivery, including dismissed notifications |
| Notification Content Extension (NCE) | Renders the expanded notification view on long-press |
Do the following in the portal:
Register or update your App ID
If you are registering a new App ID:
- In your Apple Developer account, go to Identifiers > +.
- Select App IDs > App and click Continue.
- Enter a description and your bundle ID.
- Under Capabilities, enable Push Notifications and App Groups.
- Click Continue > Register.
If your App ID already exists:
- Click the App ID in the list to open it.
- Under Capabilities, enable Push Notifications and App Groups.
- Click Save.
Register App IDs for the extensions
This step is automated — you don't do it in the portal. The plugin creates the ConnectNSE and ConnectNCE extension targets in Xcode for you on every build (see Step 5).
Create an App Group
- Go to Identifiers > + and select App Groups.
- Enter a description and an identifier using the
group.prefix (for example,group.com.yourcompany.yourapp). - Click Continue > Register.
- Go back to your main App ID and assign the App Group you just created.
You'll assign this same App Group to the NSE and NCE extension App IDs later, in Step 5, after the plugin creates the extension targets.
Step 4: Configure push in ConnectConfig.json
Back in your project root (outside Xcode), open ConnectConfig.json and add the following keys inside the Connect object.
{
"Connect": {
"AppKey": "...",
"PostMessageUrl": "...",
"iOSPushMode": "automatic",
"iOSAppGroupIdentifier": "group.com.yourcompany.yourapp",
"iOSDevelopmentTeam": "YOUR_TEAM_ID"
}
}| Key | Value |
|---|---|
iOSPushMode | 'automatic' (default) — the SDK installs its own notification delegate and handles APNs registration, delivery, and tap actions. 'manual' — your app owns UNUserNotificationCenter.delegate and forwards events via AcousticConnect.push.didReceiveNotification() / didReceiveResponse(). |
iOSAppGroupIdentifier | The App Group identifier from Step 3. Substituted automatically into the NSE/NCE Swift source and into the host app's and both extensions' entitlements files — you don't edit any .entitlements file by hand. |
iOSDevelopmentTeam | Required. Your 10-character Apple Team ID. Stamped onto the main app target and both extension targets automatically on every prepare. |
Step 5: Build — the plugin wires up Xcode
Build for iOS.
npx cordova build iosEvery build wires up Xcode for you automatically — you do not need to manually create extension targets, edit a Podfile, or hand-edit an entitlements file.
What happens automatically on every build
- Copies the NSE (
NotificationService.swift) and NCE (NotificationViewController.swift) source intoplatforms/ios/, with your App Group identifier substituted in. - Creates the
ConnectNSEandConnectNCEapp-extension targets in your.xcodeproj(idempotently — safe to run every prepare), links the required system frameworks (UserNotifications, andUserNotificationsUI+UIKitfor the NCE), and adds an "Embed Foundation Extensions" build phase on the main app target. - Adds
ConnectNSEandConnectNCEas CocoaPods targets in yourPodfileand runspod install— only when the Podfile actually changed, to avoid an unnecessary reinstall on every build. - Adds the App Group and
aps-environmententitlement to the main app's entitlements file (and both extensions'). - Adds
UIBackgroundModes→remote-notificationtoInfo.plist.
What you still do manually, once:
In Xcode:
- Open
platforms/ios/App.xcworkspace(never the.xcodeproj— CocoaPods generates the workspace). - Select the main app target → Signing & Capabilities → confirm a Team is set. This is automatic — you already set
iOSDevelopmentTeamin ConnectConfig.json in Step 4. - Add the Push Notifications capability to the main app target. This is the one capability the plugin doesn't add for you —
UIBackgroundModesis added automatically, but the capability entry itself is not.
In the Apple Developer portal:
- Assign the App Group from Step 3 to the two extension App IDs the plugin just created for
ConnectNSEandConnectNCE.
WarningIf Xcode doesn't offer App Groups as a capability, or your App Group isn't selectable, Xcode hasn't picked up your portal changes yet. Go to Xcode > Settings > Apple Accounts, select your account and team, click Download Manual Profiles, then try again.
Step 6: Request notification permission
const result = await AcousticConnect.push.requestPermission();
if (result.granted) {
console.log('Notification permission granted');
} else {
console.log('Notification permission denied:', result.error);
}push.requestPermission() presents the system permission dialog when the state is undetermined. Call it at an appropriate moment in your UX rather than on first launch.
WarningiOS only shows the system permission dialog once. If the user denies it, the only way to re-enable notifications is through the Settings app.
Check the current state without prompting:
const granted = await AcousticConnect.push.getPermissionState();
// true = granted, false = denied, null = not yet determinedStep 7: Handle manual push mode
If iOSPushMode is 'manual', your app's own native delegate handles APNs callbacks and forwards them:
await AcousticConnect.push.didReceiveAuthorization(granted, error);
await AcousticConnect.push.didReceiveNotification(userInfo);
await AcousticConnect.push.didReceiveResponse(actionIdentifier, userInfo);These three methods reject with ACOUSTIC_PUSH_MODE_NOT_MANUAL if called while the SDK is running in automatic mode.
Testing
Enable debug logging
With "useRelease": false in ConnectConfig.json (the default), the plugin sets CONNECT_DEBUG, TLF_DEBUG, and EODebug at runtime, and verbose native logging appears in the Xcode console.
On the simulator — instant verification
You can test push delivery in the simulator using .apns payload files — drag them onto the running simulator. This confirms basic delivery and NCE invocation, but rich-media images may not have time to load; use a real iPhone to validate images.
{
"Simulator Target Bundle": "com.yourcompany.yourapp",
"aps": {
"alert": { "title": "New arrivals", "body": "Fresh styles just landed." },
"sound": "default"
}
}{
"Simulator Target Bundle": "com.yourcompany.yourapp",
"aps": {
"alert": { "title": "New arrivals", "body": "Fresh styles just landed." },
"sound": "default",
"mutable-content": 1
}
}On an iPhone — real APNs delivery
- Build and run on a physical iPhone.
- Grant notification permission when prompted. A new mobile contact is created in Connect.
- Coordinate with your marketing team to send a test push, or do it yourself — see Test your push notification setup.
- Verify the notification appears, images load, and push signals appear in the contact's activity feed in Connect.
Troubleshooting
Push notifications not being delivered
- If you're testing on a device, check your debug log for an APNs token. If none appears, confirm the Push Notifications capability is added to the main app target and that the device has network access. (On the simulator, no token is ever generated.)
- Confirm the user granted notification permission.
- Confirm
remote-notificationis inUIBackgroundModesinInfo.plist(added automatically — check if you've overriddenInfo.plistmanually). - Confirm the bundle ID matches the App ID with Push Notifications enabled in the portal.
Rich push images not showing
- Confirm the image URL is accessible over HTTPS.
- Confirm
iOSAppGroupIdentifierin ConnectConfig.json matches the App Group assigned to all three App IDs in the portal. - Confirm
pod installran after any App Group change — check theafter_prepareconsole output forPodfile changed — running pod install.
Extension targets missing or stale after a fresh clone / plugin re-add
Run npx cordova prepare ios (or npx cordova build ios) again — the extension targets, embed phase, and entitlements are rebuilt idempotently by the after_prepare hook each time. If signing looks stale specifically, re-open Xcode, confirm Signing & Capabilities shows a Team on all three targets, and re-download provisioning profiles if App Groups isn't selectable.
[after_prepare] pod install failed
[after_prepare] pod install failedCocoaPods isn't installed, or your local spec repo is stale. Run sudo gem install cocoapods && pod repo update, then npx cordova build ios again.
Unable to find host target(s) for ConnectNSE, ConnectNCE during pod install
Unable to find host target(s) for ConnectNSE, ConnectNCE during pod installThis can happen on a fresh platform add, when the Podfile still references extension targets from a previous prepare but the .xcodeproj was reset. The plugin's before_prepare hook detects and strips stale references automatically, and after_prepare re-adds them once the project is consistent again — if you still see this error, re-run npx cordova prepare ios once more before investigating further.
Next step: Identify app users
Push setup is now complete. To make the most of push notifications, identify the people receiving them — see Identify users at sign-in.
