Native iOS
Direct Apple integration
P8 Keys
Token-based authentication
Secure
End-to-end encryption
Real-time
Instant delivery
Apple Developer Account Requirements
Before configuring APNS, ensure you have:
Apple Developer Account
Paid membership ($99/year)
App ID with Push
Push Notifications capability enabled
Bundle Identifier
Unique app identifier (e.g., com.myapp.ios)
Team ID
Found in Membership details
Developer Account
Creating Push Certificates
Configure your App ID for push notifications:
Access Certificates
Go to Apple Developer Portal → Certificates, Identifiers & Profiles.
Select or Create App ID
Under Identifiers, select your existing App ID or create a new one. Enable the Push Notifications capability.
Configure Push
Click Configure next to Push Notifications. You can create either Development or Production certificates, but we recommend using P8 keys instead.
Recommendation: Use P8 Keys
P8 Key Configuration
Create an APNS authentication key (recommended approach):
Create Key
In Apple Developer Portal, go to Keys and click the + button to create a new key.
Enable APNS
Name your key (e.g., "APNS Push Key") and check Apple Push Notifications service (APNs). Click Continue.
Download Key
Click Register, then Download. Save the .p8 file securely. You can only download this file once!
Note Key ID
Record the Key ID shown on the key details page. You'll need this along with your Team ID.
# P8 Key File
# File: AuthKey_XXXXXXXXXX.p8
# Contains your private key (keep secure!)
# Key ID (10 characters)
APNS_KEY_ID=XXXXXXXXXX
# Team ID (from Membership page)
APNS_TEAM_ID=YYYYYYYYYY
# Bundle ID (your app's identifier)
APNS_BUNDLE_ID=com.yourcompany.yourappKey Security
Adding APNS to Console
Configure APNS credentials in the Sylphx dashboard:
Navigate to Settings
Go to App Settings → Notifications → Push Providers.
Add APNS Provider
Click Add Provider and select Apple Push Notification Service.
Upload P8 Key
Upload your .p8 file and enter your Key ID, Team ID, and Bundle ID.
Select Environment
Choose Development for testing or Production for App Store builds.
Test Connection
Click Test Connection to verify your credentials.
import { platform } from '@/lib/platform'
// APNS is automatically configured once added in the dashboard
// No additional SDK configuration needed
// Verify APNS is configured
const providers = await platform.notifications.getProviders()
console.log(providers.apns)
// {
// enabled: true,
// environment: 'production',
// bundleId: 'com.yourcompany.yourapp',
// }Sending to iOS Devices
Send push notifications to iOS devices:
import { platform } from '@/lib/platform'
// Send to a specific user (uses their registered device token)
await platform.notifications.send({
userId: user.id,
title: 'New Message',
body: 'Sarah sent you a message',
data: {
messageId: '123',
},
})
// Send with iOS-specific options
await platform.notifications.send({
userId: user.id,
title: 'Order Update',
body: 'Your order has shipped!',
// APNS-specific configuration
apns: {
// Alert customization
alert: {
title: 'Order Update',
subtitle: 'Order #12345',
body: 'Your order has shipped!',
},
// Badge count
badge: 5,
// Sound
sound: 'default', // or custom sound file name
// Content available (for background updates)
contentAvailable: true,
// Mutable content (for notification extensions)
mutableContent: true,
// Category for actionable notifications
category: 'ORDER_UPDATE',
// Thread ID for grouping
threadId: 'order-12345',
// Target content ID (for replacing notifications)
targetContentId: 'order-12345',
// Interruption level (iOS 15+)
interruptionLevel: 'active', // 'passive' | 'active' | 'time-sensitive' | 'critical'
// Relevance score (0-1, for notification summary)
relevanceScore: 0.8,
},
data: {
orderId: '12345',
trackingUrl: 'https://tracking.example.com',
},
})// Send directly to a device token
await platform.notifications.sendToToken({
token: 'apns-device-token...',
title: 'Welcome!',
body: 'Thanks for enabling notifications',
apns: {
badge: 1,
sound: 'default',
},
})
// Batch send to multiple tokens
const result = await platform.notifications.sendToTokens({
tokens: ['token1...', 'token2...', 'token3...'],
title: 'New Feature',
body: 'Check out our latest update!',
})
console.log(result)
// {
// success: 2,
// failure: 1,
// failedTokens: ['token3...'],
// }APNS Options
| Property | Type | Description |
|---|---|---|
alert | object | Alert content (title, subtitle, body) |
badge | number | App badge number |
sound | string | Sound file name or "default" |
contentAvailable | boolean= false | Enable background fetch |
mutableContent | boolean= false | Allow notification extension |
category | string | Action category identifier |
threadId | string | Thread for grouping notifications |
interruptionLevel | string | iOS 15+ interruption level |
relevanceScore | number | Score for notification summary (0-1) |
Testing on Simulator vs Device
Understanding the differences when testing push notifications:
Physical Device
- Full APNS support
- Real device tokens
- Background notifications
- Notification extensions
- Production environment
Simulator
- Xcode 14+ supports push
- Drag .apns files to test
- Simulated tokens only
- No real APNS connection
- Limited extension support
// Create a test payload file: test.apns
{
"Simulator Target Bundle": "com.yourcompany.yourapp",
"aps": {
"alert": {
"title": "Test Notification",
"body": "This is a test push notification"
},
"badge": 1,
"sound": "default"
},
"customData": {
"key": "value"
}
}
// Drag the .apns file onto the simulator to trigger the notification
// Or use xcrun from command line:
// xcrun simctl push booted com.yourcompany.yourapp test.apns// You can also test from the dashboard:
// 1. Go to App Settings → Notifications → Push Providers → APNS
// 2. Click "Send Test Notification"
// 3. Enter a device token (from your app logs)
// 4. Customize the payload and send
// Or use the SDK for testing
await platform.notifications.sendTest({
provider: 'apns',
token: 'device-token-from-logs...',
title: 'Test Notification',
body: 'This is a test!',
})Development vs Production
Troubleshooting APNS
Common issues and solutions:
BadDeviceTokenCause: Token format is invalid or malformed
Solution: Ensure you're using the correct hex string format. Token should be 64 characters.
DeviceTokenNotForTopicCause: Token was generated for a different app bundle
Solution: Verify the bundle ID matches the one used to generate the token
UnregisteredCause: App was uninstalled or token invalidated
Solution: Remove the token from your database and wait for a new registration
ExpiredProviderTokenCause: Your P8 key authentication token expired
Solution: Tokens expire after 1 hour. The SDK handles this automatically.
InvalidProviderTokenCause: P8 key, Key ID, or Team ID is incorrect
Solution: Verify all credentials match your Apple Developer account
TopicDisallowedCause: Push not enabled for this App ID
Solution: Enable Push Notifications capability in Apple Developer Portal
// Enable debug mode for detailed logging
const result = await platform.notifications.send({
userId: user.id,
title: 'Test',
body: 'Debug test',
debug: true, // Returns detailed response
})
console.log(result)
// {
// success: false,
// provider: 'apns',
// error: {
// code: 'BadDeviceToken',
// message: 'The specified device token is invalid.',
// timestamp: '2024-01-15T10:30:00Z',
// },
// apnsResponse: {
// statusCode: 400,
// headers: { ... },
// },
// }