Troubleshooting for the Apple SDK

Common issues and solutions for Airship SDK setup, initialization, and integration.

If you don’t see a channel ID in the console logs or encounter errors during initialization, review the following common problems and solutions.

takeOff Errors

The takeOff method throws an error in the following conditions:

  • takeOff has already been successfully called
  • takeOff was called without an AirshipConfig instance and failed to parse AirshipConfig.plist
  • takeOff was called without an AirshipConfig instance and the parsed AirshipConfig.plist is invalid (missing credentials)
  • takeOff was called with an AirshipConfig instance that has invalid config (missing credentials)

Credential Validation

The takeOff method only validates that credentials are present and formatted correctly—it does not verify that the credentials are valid against Airship servers. If the config is properly set up and Airship is only called once, no error will be thrown even if the credentials themselves are invalid.

Symptoms of invalid credentials:

  • No channel ID appears in the console logs
  • Warnings or errors in the logs after initialization
  • Channel is not created in the Airship dashboard

To verify your credentials:

  • Check that your credentials in the Airship dashboard (under SettingsAPIs & IntegrationsApp Keys) match what you’ve configured in your app
  • Ensure you’re using the correct credentials for your build configuration (development vs production)
  • Verify both production and development credentials are correctly set

Common Issues

takeOff called multiple times

  • Ensure takeOff is only called once per app launch
  • Check that you’re not calling it in both application(_:didFinishLaunchingWithOptions:) and your App’s init() method
  • SwiftUI apps should only call takeOff in the App’s init() method

Missing or invalid credentials

  • Verify your credentials in the Airship dashboard under SettingsAPIs & IntegrationsApp Keys
  • Check that you’re using the correct credentials for your build configuration (development vs production)
  • Ensure both productionAppKey/productionAppSecret and developmentAppKey/developmentAppSecret are set before calling takeOff
  • Verify credentials match the expected format and character set
  • Check that credentials are not empty strings or contain extra whitespace

AirshipConfig.plist not found or invalid

  • Verify the file exists in your app bundle
  • Check that the file is included in your target’s Copy Bundle Resources build phase
  • Ensure all required keys (productionAppKey, productionAppSecret, developmentAppKey, developmentAppSecret) are present in the plist file
  • Verify the plist file format is valid XML

Checking Push Notification Status

If push notifications aren’t working as expected, you can check the notification status to diagnose the issue. The SDK provides detailed information about the current state of push notifications.

Get Current Notification Status

Check notification status

let status = await Airship.push.notificationStatus

print("User notifications enabled: \(status.isUserNotificationsEnabled)")
print("Notifications allowed: \(status.areNotificationsAllowed)")
print("Privacy feature enabled: \(status.isPushPrivacyFeatureEnabled)")
print("Push token registered: \(status.isPushTokenRegistered)")
print("User opted in: \(status.isUserOptedIn)")
print("Fully opted in: \(status.isOptedIn)")
print("Display status: \(status.displayNotificationStatus)")
 Note

This async property is not available in Objective-C. Use the userPushNotificationsEnabled property and check authorization status directly with UNUserNotificationCenter.

Listen for Status Changes

To monitor notification status changes in real-time:

Monitor notification status

Task {
    for await status in await Airship.push.notificationStatusUpdates {
        print("Notification status changed:")
        print("User opted in: \(status.isUserOptedIn)")
        print("Fully opted in: \(status.isOptedIn)")
    }
}
 Note

This async stream is not available in Objective-C. Use the userPushNotificationsEnabled property and check authorization status directly with UNUserNotificationCenter.

Understanding Notification Status Fields

The AirshipNotificationStatus struct provides detailed information about why push might not be working:

FieldDescription
isUserNotificationsEnabledWhether Airship.push.userPushNotificationsEnabled is set to true
areNotificationsAllowedWhether the user has granted notification permissions (at least one authorized type)
isPushPrivacyFeatureEnabledWhether the push privacy feature is enabled in AirshipPrivacyManager
isPushTokenRegisteredWhether a push token has been successfully registered with the system
displayNotificationStatusThe system permission status (.granted, .denied, .notDetermined, .ephemeral)
isUserOptedIntrue if user notifications are enabled, privacy feature is enabled, notifications are allowed, and display status is granted
isOptedIntrue if isUserOptedIn is true AND a push token is registered

Common Status Scenarios

Status: isUserNotificationsEnabled = false

  • Cause: Airship.push.userPushNotificationsEnabled has not been set to true
  • Solution: Enable user notifications in your app code

Status: areNotificationsAllowed = false

  • Cause: User denied notification permissions or permissions not yet requested
  • Solution: Request notification permissions or guide user to system settings

Status: isPushPrivacyFeatureEnabled = false

  • Cause: Push privacy feature is disabled in Privacy Manager
  • Solution: Enable the push privacy feature: Airship.privacyManager.enabledFeatures = [.push]

Status: isPushTokenRegistered = false

  • Cause: Device hasn’t received a push token from APNs yet
  • Solution: Check network connectivity, APNs certificate configuration, and device/simulator limitations

Status: isUserOptedIn = true but isOptedIn = false

  • Cause: Push token registration is pending or failed
  • Solution: Check console logs for APNs registration errors, verify network connectivity, and ensure proper entitlements