This is a developers' guide for setting up an Urban Airship configuration for native iOS apps. We will take you through the basic technical steps for configuring Apple and UA services, show you how to send your first basic push notification and Message Center message, and provide detailed samples and instructions for using advanced Urban Airship features.


Getting Started

There are a few important steps to get out of the way when integrating Urban Airship with your app for the first time. Follow these instructions carefully to ensure that you will have a smooth development experience.

APNS Setup

While you are setting up your development and production apps, you need to configure them for push services. For detailed instructions on this process, please see the APNS Setup documentation.

SDK Installation

The Urban Airship SDK can be installed using CocoaPods, Carthage, or manually. Pick the option that makes the most sense for your project.


Before you begin, ensure that you have CocoaPods installed. If you are having troubles with CocoaPods, check out the troubleshooting guide.

$ gem install cocoapods

Update the podfile

Specify the UrbanAirship-iOS-SDK pod in your podfile and make sure to specify the flag use_frameworks!

Example podfile:

use_frameworks! target "Your_Target_Name" do pod 'UrbanAirship-iOS-SDK' end

Explicitly specify the tvOS platform in your podfile when targeting tvOS. Cocoapods automatic platform selection can also be used if the platform must be left unspecified.

When targeting tvOS - specify the platform in your podfile:

platform :tvos, '10.0'

Install the pods

After running pod install, an Xcode workspace (extension .xcworkspace) will be generated. Make sure to always open it instead of the project file (extension .xcodeproj) when building your projects.

$ pod install


Before you begin, ensure you have Carthage installed.

Adding the SDK framework to your application

Follow Carthage's adding frameworks to an application instructions to add AirshipKit.framework to your application.

Specify the Urban Airship iOS SDK in your cartfile:

github "urbanairship/ios-library"

If you are creating a Notification Service Extension, follow the instructions in the iOS Notification Service Extension Guide.

Verify Enable Modules and Link Frameworks Automatically are enabled in the project's Build Settings.


Start by downloading the latest version of the iOS SDK.

Copy AirshipKit

Copy the AirshipKit directory into the top level of your app's source directory.

Include AirshipKit as a project dependency

Drag AirshipKit.xcodeproj out of the AirshipKit folder and into your app project in Xcode (directly under the top level of the project structure). Now AirshipKit will be built at compile-time for the active architecture.

Add AirshipKit to Embedded Binaries:

To add the framework to Embedded Binaries, click the add + button and select AirshipKit.framework iOS nested under the path AirshipKit.xcodeproj/AirshipResources/ios/Products

This should result in AirshipKit.framework appearing in both the Embedded Binaries and the Linked Frameworks and Libraries sections of the General tab for your target.

Verify Build Settings:

Enable Modules should be set to Yes

Link Frameworks Automatically should be set to Yes

Notification Service Extension

In order to take advantage of iOS 10 notification attachments, such as images, animated gifs, and video, you will need to create a notification service extension by following the iOS Notification Service Extension Guide.

Update the Target's Capabilities

Use Xcode to enable push notifications in the target's Capabilities pane:

Enable background notifications that were introduced in iOS 7 by including the UIBackgroundModes key with the remote-notification value in your app's Info.plist file. When viewing the plist in Xcode, UIBackgroundModes is displayed as Required background modes and remote-notification is displayed as App downloads content in response to push notifications.

You can also enable Background Modes and Remote notifications under the target's Capabilities section:

Create Airship Config Options

Example AirshipConfig.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">
  <string>Your Development App Key</string>
  <string>Your Development App Secret</string>
  <string>Your Production App Key</string>
  <string>Your Production App Secret</string>

Create a plist AirshipConfig.plist and include it in your application's target. The default config will be loaded from the AirshipConfig.plist file if its included in the application target.


Example app delegate changes:

import AirshipKit


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {


    return true
@import AirshipKit;


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [UAirship takeOff];

    return YES;


TakeOff must be called on the main thread and before application returns.

The Urban Airship SDK requires only a single entry point in the app delegate, known as takeOff. Inside your application delegate's application:didFinishLaunchingWithOptions: method, initialize a shared UAirship instance by calling UAirship takeOff . This will bootstrap the SDK and look for settings specified in the AirshipConfig.plist config file.

App Transport Security

Message Center content features such as Landing Pages are only able to load SSL-encrypted web content out of the box. This iOS feature, known as App Transport Security, requires all web connections to use SSL, and only allows for whitelisting exceptions on an individual basis. Content hosted on Urban Airship's servers is already SSL-encrypted, but if you plan to use your own content, you will need to make sure it is accessible behind SSL so that iOS will not prevent the SDK from loading it. While we generally recommend leaving these default settings alone, if your app will need to load plain HTTP content then you can whitelist individual domains in your app's Info.plist file. For more information, see Apple's App Transport Security Technote.

Send Your First Push Notification

Enable notifications for a quick test after calling takeOff:

UAirship.push().userPushNotificationsEnabled = true
UAirship.push().defaultPresentationOptions = [.alert, .badge, .sound]
[UAirship push].userPushNotificationsEnabled = YES;
[UAirship push].defaultPresentationOptions = (UNNotificationPresentationOptionAlert |
                                              UNNotificationPresentationOptionBadge |

Remote notifications are only available on a real device. You will not be able to send any notifications through APNS on a simulator.

At this point in the guide, if you followed all the steps above you should be ready to send a test push notification to verify everything is set up properly.

Before sending a push, you must enable user notifications. The SDK does not enable user notifications by default in order to avoid prompting the user for permissions before your app is ready to do so. But for a testing purposes, you can enable user notifications in the app delegate immediately after takeOff. You may also want to set default foreground presentation options to display the notification in the foreground on iOS 10. On older devices, make sure you background the app before sending the push. For more information on customizing push notifications or receiving callbacks, see Push Notifications.

Follow Send Your First Notification or our API reference for details on sending the first notification.


The Urban Airship SDK can be built to support tvOS applications. Because of the difference in the underlying design between tvOS and iOS - only a subset of Urban Airship's iOS features are available on tvOS.

tvOS currently supports the following features:

  • Badges
  • Content-available Pushes
  • Analytics (Including Urban Airship Connect and Insight)

tvOS Sample

The tvOS sample is written in Swift and can be used to test and explore the supported feature set with minimal configuration steps. To get started with the tvOS sample, check out the tvOS Sample readme for step-by-step setup instructions.

Push Notifications

Push notifications on the tvOS platform are more restricted to promote a less distracting user experience. On tvOS, user-visible notifications are restricted to badges. Badge operations in tvOS are the same as in iOS. For more information about badge operations in tvOS see Badging in iOS.

Content-available pushes are also available for performing content fetching and other silent operations in the background.

Handling Push Notifications

Sample UAPushNotificationDelegate implementation:

class PushHandler: NSObject, UAPushNotificationDelegate {
    func receivedBackgroundNotification(_ notificationContent: UANotificationContent, completionHandler: @escaping (UIBackgroundFetchResult) -> Swift.Void) {
        // Application received a background notification
        print("The application received a background notification");

        // Call the completion handler

    func receivedForegroundNotification(_ notificationContent: UANotificationContent, completionHandler: @escaping () -> Swift.Void) {
        // Application received a foreground notification
        print("The application received a foreground notification");

        // Let system handle it

    func presentationOptions(for notification: UNNotification) -> UNNotificationPresentationOptions {
        return [.badge]

Handling notifications on tvOS is nearly identical to iOS. tvOS handles push notifications received outside the application, but if a notification is received while the app is active, it's up to the application developer to handle it.

The tvOS sample UI includes a complete implementation of the UAPushNotificationDelegate protocol that handles badges and content-available pushes. However, if you wish to customize this behavior, you can provide your own implementation.


Urban Airship on tvOS fully supports analytics for tvOS implementations written in Swift. For tvOS implementations written in TVML, screen tracking is currently unsupported. For more information see Analytics Events and Uploading.

Urban Airship Channel IDs

The Channel ID is a unique identifier that ties together an application/device pair on iOS devices. The Channel ID is used to target pushes to specific devices using the Urban Airship API.

Channel ID Access:

let channelID = UAirship.push().channelID
print("My Application Channel ID: \(channelID)")
NSString *channelID = [UAirship push].channelID;
NSLog(@"My Application Channel ID: %@", channelID);

The Channel ID will be logged for all apps. You can get the channelID with a couple of extra lines to your application:

Don't worry if this value initially comes back as null on your app's first run as the Channel ID will be created and persisted during registration.

Adding an NSNotificationCenter observer for UAChannelCreatedEvent:

// Add observer to the UAChannelCreatedEvent
[[NSNotificationCenter defaultCenter] addObserver:self
                                             name:UAChannelCreatedEvent object:nil];

Implementing the UARegistrationDelegate protocol:

func registrationSucceeded(forChannelID channelID: String, deviceToken: String) {
    // Registration succeeded
- (void)registrationSucceededForChannelID:(NSString *)channelID deviceToken:(nonnull NSString *)deviceToken {
    // Registration succeeded

Setting the registration delegate on UAPush:

UAirship.push().registrationDelegate = self
[UAirship push].registrationDelegate = self;

You can listen for channel creation by either adding an NSNotificationCenter observer for UAChannelCreatedEvent or by implementing the UARegistrationDelegate protocol and setting the registration delegate on UAPush . You can listen for channel updates by adding an NSNotificationCenter observer for UAChannelUpdatedEvent .

Channel Capture Tool

The Channel ID is valuable for troubleshooting individual device issues in production apps. iOS SDKs since 6.1.0 include a Channel Capture tool that can be used to expose the Channel ID to the user, who can then send it to support. App developers are asked to enable the channel capture tool or to provide another mechanism to get the user's channelID.

The Channel Capture tool can be enabled or disabled using the channelCaptureEnabled flag in your app's AirshipConfig.plist.

  • The Channel Capture tool is enabled by default. This is the recommended setting.
  • If the app disables the Channel Capture tool, it should provide some other mechanism to expose the user's Channel ID.

When channel capture is enabled and the app becomes active, the Channel Capture tool only operates if it is active. There are two situations where it is active:

Activating the Channel Capture tool:

let duration : NSTimeInterval = 180
NSTimeInterval duration = 180;
[[UAirship shared].channelCapture enable:duration];
  • Background App Refresh is disabled in the app's system settings, or
  • The Channel Capture tool has been activated for a specific duration, either by

If the Channel Capture tool is active, it looks for a special token placed by the user on the device's clipboard. Urban Airship Support can help developers generate this token. If and only if the special token matches an SDK-generated token, a dialog is displayed that allows the user to copy their Channel ID. The Channel ID can then be sent from the user to support to help troubleshoot the issue.

Advanced Configuration

Overriding AirshipConfig.plist programmatically:

// Defaults to any value in AirshipConfig.plist
let config = UAConfig.default()

// Set any custom values
config.developmentAppKey = "DEV APP KEY"
config.developmentAppSecret = "DEV APP SECRET"

// TakeOff with custom config
// Defaults to any value in AirshipConfig.plist
UAConfig *config = [UAConfig defaultConfig];

// Set any custom values
config.developmentAppKey = @"DEV APP KEY"
config.developmentAppSecret = @"DEV APP SECRET"

// TakeOff with custom config
[UAirship takeOff:config];

The SDK provides a number of advanced configuration features that are defined by the UAConfig class. Only a subset of options will be outlined in this guide. For a full list of options, check out the available properties on the UAConfig class.

Every option is able to be defined by the AirshipConfig.plist by setting the corresponding UAConfig property name to the desired value. Alternatively you can define any value programmatically by setting properties directly on a UAConfig instance and providing it during UAirship takeOff: .

Automatic Integration

Manual integration:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Set up the UNUserNotificationCenter delegate
    UNUserNotificationCenter.current().delegate = self

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    UAAppIntegration.application(UIApplication.shared, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    UAAppIntegration.application(UIApplication.shared, didFailToRegisterForRemoteNotificationsWithError: error)

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    UAAppIntegration.application(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler)

// UNUserNotificationCenterDelegate methods

func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (options: UNNotificationPresentationOptions) -> Void) {
        willPresentNotification: notification,
        withCompletionHandler: completionHandler)

func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
    didReceiveNotificationResponse: response,
    withCompletionHandler: completionHandler)
// UIApplicationDelegate methods

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Set up the UNUserNotificationCenter delegate
    [UNUserNotificationCenter currentNotificationCenter].delegate = self;

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [UAAppIntegration application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    [UAAppIntegration application:application didFailToRegisterForRemoteNotificationsWithError:error];

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [UAAppIntegration application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];

// UNUserNotificationCenterDelegate methods

- (void) userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    [UAAppIntegration userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler];

- (void) userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
    [UAAppIntegration userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];

The Urban Airship SDK will automatically integrate with your app, so you do not need to implement any of the push-related UIApplicationDelegate or UNUserNotificationCenterDelegate protocol methods. The SDK is able to do this by intercepting app delegate messages and forwarding them to your original app delegate, using a technique known as method swizzling.

This should be compatible with the vast majority of applications out of the box, but if you have advanced use cases for your app delegate, or if you would otherwise prefer to disable this behavior, you can set automaticSetupEnabled to NO.

If you choose to disable automatic integration, you will need to forward the appropriate methods to the Urban Airship SDK.


Log levels can be set independently for production and development modes by setting developmentLogLevel and productionLogLevel config options.

Push Notifications

Urban Airship's SDK provides a simple interface for managing push notifications within your iOS application.

Enabling User Notifications

Enable user notifications:

UAirship.push().userPushNotificationsEnabled = true
[UAirship push].userPushNotificationsEnabled = YES;

Enabling userPushNotificationsEnabled will prompt the user for permission to send notifications. To increase the likelihood that the user will accept, you should avoid prompting the user for permission immediately, and instead wait for a more appropriate time in the app.

The Urban Airship SDK makes a distinction between "user notifications", which can be seen by the user, and other forms of push that allow you to send data to your app silently, or in the background. Enabling or disabling user notifications is a preference often best left up to the user, so by default, user notifications are disabled.

Notification Options

Update remote notification options

UAirship.push().notificationOptions = [.alert, .badge, .sound]
[UAirship push].notificationOptions = (UANotificationOptionAlert | UANotificationOptionBadge | UANotificationOptionSound);

By default the Urban Airship SDK will request Alert, Badge, and Sound notification options for remote notifications. This can be configured by setting different types of notificationOptions on the UAPush instance.

Provisional authorization

UAirship.push().notificationOptions = [.alert, .badge, .sound, .provisional]
UAirship.push().userPushNotificationsEnabled = true
[UAirship push].notificationOptions = (UANotificationOptionAlert | UANotificationOptionBadge | UANotificationOptionSound | UANotificationOptionProvisional);
[UAirship push].userPushNotificationsEnabled = YES;

Starting in iOS 12, apps can request provisional authorization along with the usual notification options. When requesting provisional authorization apps do not need to prompt the user for permission initially, and notifications will be delivered in a non-interruptive manner to the Notification Center until the user explicitly chooses to keep delivering messages either prominently or quietly. Because this form of authorization requires no initial user prompt, it is acceptable to programmatically enable user notifications, which is still required for any visible notification delivery.

Foreground Presentation Options

Setting default presentation options:

UAirship.push().defaultPresentationOptions = [.alert, .badge, .sound]
[UAirship push].defaultPresentationOptions = (UNNotificationPresentationOptionAlert |
                                              UNNotificationPresentationOptionBadge |

The SDK provides support for foreground presentation options that were introduced in iOS 10. The three UNNotificationPresentationOptions constants are badge, sound, and alert. These constants specify how to present a notification when the application receives a remote notification in the foreground. You can set default presentation options that will be applied to all remote-notifications, and you can also provide options per notification by providing a UAPushNotificationDelegate .

Handling Notifications

Set the UAPushNotificationDelegate on UAPush:

UAirship.push().pushNotificationDelegate = customPushDelegate
[UAirship push].pushNotificationDelegate = customPushDelegate;

Sample UAPushNotificationDelegate implementation:

class SamplePushHandler: NSObject, UAPushNotificationDelegate {

    func receivedBackgroundNotification(_ notificationContent: UANotificationContent, completionHandler: @escaping (UIBackgroundFetchResult) -> Swift.Void) {
        // Background content-available notification

    func receivedForegroundNotification(_ notificationContent: UANotificationContent, completionHandler: @escaping () -> Swift.Void) {
        // Foreground notification

    func receivedNotificationResponse(_ notificationResponse: UANotificationResponse, completionHandler: @escaping () -> Void) {
        // Notification response

    @available(iOS 10.0, *)
    func presentationOptions(for notification: UNNotification) -> UNNotificationPresentationOptions {
        // iOS 10 foreground presentation options
        return [.alert, .sound]
@implementation PushHandler

    -(void)receivedBackgroundNotification:(UANotificationContent *)notificationContent completionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
        // Background content-available notification

    -(void)receivedForegroundNotification:(UANotificationContent *)notificationContent completionHandler:(void (^)())completionHandler {
        // Foreground notification

    -(void)receivedNotificationResponse:(UANotificationResponse *)notificationResponse completionHandler:(void (^)())completionHandler {
        // Notification response

    - (UNNotificationPresentationOptions)presentationOptionsForNotification:(UNNotification *)notification {
        // iOS 10 foreground presentation options
        return UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound;

iOS handles push notifications received outside the application, but if a notification is received while the app is active, it's up to the application developer to handle it. Versions prior to iOS 10 require the application developer to manually create an alert view and populate it with the notification contents. In iOS 10 and above, the application developer has the additional option of using a system-generated alert view. A system-generated alert view is presented if the alert type is included in the UNNotificationPresentationOptions set on UAPush's defaultPresentationOptions property. These presentation options can be configured on a notification by notification basis by implementing the UAPushNotificationDelegate protocol's presentationOptions callback and returning the desired presentation options.

The sample UI includes a complete implementation of the UAPushNotificationDelegate protocol that handles alerts, sounds, and badges. However, if you wish to customize this behavior, you can provide your own implementation.


Setting the badge value:

[[UAirship push] setBadgeNumber:20];

You can set (or reset) the badge number within your application by setting the badge number on the UAPush instance.

Reset the badge:

[[UAirship push] resetBadge];

A typical application will reset the badge any time a user starts the app or resumes it from the background. This can be done by making UAPush resetBadge calls from application:didFinishLaunchingWithOptions: and applicationDidBecomeActive.

Enabling auto-badge:

UAirship.push().autobadgeEnabled = true
[UAirship push].autobadgeEnabled = YES;

Additionally, Urban Airship support an auto-badge feature. This allows incrementing the badge from a push instead of setting the exact value for the badge. When using auto-badge, make sure to only modify the badge value through Urban Airship methods to ensure the value keeps in sync.

Quiet Time

// Set the quiet time from 7:30pm - 7:30am
UAirship.push().setQuietTimeStartHour(19, startMinute: 30, endHour: 7, endMinute: 30)

// Enable quiet time
UAirship.push().isQuietTimeEnabled = true

// Update registration
// Set the quiet time from 7:30pm - 7:30am
[[UAirship push] setQuietTimeStartHour:19 startMinute:30 endHour:7 endMinute:30];

// Enable quiet time
[UAirship push].quietTimeEnabled = YES;

// Update registration
[[UAirship push] updateRegistration];

Quiet time disables notification sounds during a set time frame by removing the sound APNS option before sending the notification to the device.

Addressing Devices

To help target specific devices or users for a notification, we have Tags, Named Users and Tag Groups.


Modifying tags:

// Set tags
UAirship.push().tags = ["one", "two", "three"]

// Add a tag

// Remove a tag

// Update registration
// Setting tags
[UAirship push].tags = @[@"one", @"two", @"three"];

// Add a tag
[[UAirship push] addTag:@"a_tag"];

// Remove a tag
[[UAirship push] removeTag:@"a_tag"];

// Update registration
[[UAirship push] updateRegistration];

Tags are an easy way to group channels. Many tags can be applied to one or more devices. Then, a message sent to a tag will be sent out to all devices that are associated with that tag. After modifying tags, make sure to call updateRegistration to have the SDK sync the tags with Urban Airship.

Named Users

Setting the named user:

UAirship.namedUser().identifier = "NamedUserID"
[UAirship namedUser].identifier = @"NamedUserID";

Associating the channel with a Named User ID will implicitly disassociate the channel from the previously associated Named User ID, if an association existed.

Named Users allow you to associate multiple devices to a single user or profile that may be associated with more than one device, e.g., an end-user's iPhone and iPad. A device can have only one Named User, and a single Named User should not be associated with more than 50 devices. Named Users provide the ability to directly set tags on them (see Tag Groups).

By default, Named Users can only be associated server-side. A 403 Forbidden response is returned if Named User association is attempted when client-side association is disabled. In order to associate a Named User through the application, you must change the application's Named User security setting to allow Named Users to be set from devices. Please visit the Settings documentation to enable this option.

Tag Groups

Channel Tag Group Example:

// Add tags to a group
UAirship.push().addTags(["silver-member", "gold-member"], group:"loyalty")

// Remove tags from a group
UAirship.push().removeTags(["bronze-member", "club-member"], group:"loyalty")

// Set tags on a group
UAirship.push().setTags(["bingo"], group:"games")

// Update registration
// Add tags to a group
[[UAirship push] addTags:@[@"silver-member", @"gold-member"] group:@"loyalty"];

// Remove tags from a group
[[UAirship push] removeTags:@[@"bronze-member", @"club-member"] group:@"loyalty"];

// Set tags on a group
[[UAirship push] setTags:@[@"bingo"] group:@"games"];

// Force a registration update
[[UAirship push] updateRegistration];

Named User Tag Group Example:

// Add tags to a group
UAirship.namedUser().addTags(["silver-member", "gold-member"], group:"loyalty")

// Remove tags from a group
UAirship.namedUser().removeTags(["bronze-member", "club-member"], group:"loyalty")

// Set tags on a group
UAirship.namedUser().setTags(["bingo"], group:"games")

// Force a registration update
// Add tags to a group
[[UAirship namedUser] addTags:@[@"silver-member", @"gold-member"] group:@"loyalty"];

// Remove tags from a group
[[UAirship namedUser] removeTags:@[@"bronze-member", @"club-member"] group:@"loyalty"];

// Set tags on a group
[[UAirship namedUser] setTags:@[@"bingo"] group:@"games"];

// Force a registration update
[[UAirship namedUser] updateTags];

If setting channel tags is enabled on the device, the predefined device Tag Group cannot be modified from the device and will log an error message. Disable channel tags by disabling channelTagRegistrationEnabled on the UAPush instance if you want to modify this "default" Tag Group.

Tag groups are configurable namespaces for organizing tags for the channel and Named User. Please view the Tag Groups documentation for more details. The Create and push to a tag group guides you through creating and using Tag Groups.

By default, Tag Groups can only be modified from the server. A 403 Forbidden response is returned if Tag Groups modification is attempted when client-side Tag Groups is disabled. In order to modify Tag Groups through the application, you must change the application's Tag Group security settings to allow these tags to be set from devices. Please visit the Settings documentation to enable this option.

Custom Identifiers

Setting identifiers:

// Get the current identifiers
let identifiers = UAirship.shared().analytics.currentAssociatedDeviceIdentifiers()

// Add any custom identifier
identifiers.setIdentifier("customIdentifier", forKey:"customkey")

// Optionally include advertising ID
identifiers.advertisingID = ASIdentifierManager.sharedManager().advertisingIdentifier.UUIDString;
identifiers.advertisingTrackingEnabled = ASIdentifierManager.sharedManager().advertisingTrackingEnabled;
identifiers.vendorID = UIDevice.currentDevice().identifierForVendor?.UUIDString

// Associate the identifiers
// Get the current identifiers
UAAssociatedIdentifiers *identifiers = [[UAirship shared].analytics currentAssociatedDeviceIdentifiers];

// Add any custom identifier
[identifiers setIdentifier:@"customIdentifier" forKey:@"customKey"];

// Optionally include advertising ID
identifiers.advertisingID = [[ASIdentifierManager sharedManager].advertisingIdentifier] UUIDString];
identifiers.advertisingTrackingEnabled = [ASIdentifierManager sharedManager].advertisingTrackingEnabled;
identifiers.vendorID = [[UIDevice currentDevice].identifierForVendor UUIDString];

// Associate the identifiers
[[UAirship shared].analytics associateDeviceIdentifiers:identifiers];

In addition to Named Users, tags, and Tag Groups, you can assign up to 20 custom identifiers to users. Identifiers that define additional ways of looking at a user -- for example, iOS Vendor ID, iOS Advertising ID, Google Analytics CID, or any other identifier you deem significant -- can be added to your users.

Custom identifiers will be visible in the Connect data stream. We recommend adding any IDs that you may want to be visible in Connect, even if Connect does not yet support the relevant integration. Unlike the other identifiers (e.g., tags), you cannot use custom identifiers to target your users.

Interactive Notifications

Urban Airship provides a set of standard Interactive Notification types (See: Built-In Interactive Notification Types). It is the type that determines which buttons and corresponding labels will be available when you send a push. See the next section for where to specify that in the push payload. You control what happens when you send the push separately, by tying each button ID to a specific action.

Custom Interactive Notification Types (Categories)

Custom Categories:

// Define an action for the category
let categoryAction = UANotificationAction(identifier: "category_action",
                                               title: "Action!",
                                             options: [.authenticationRequired, .foreground, .destructive])

// Define the category
let category = UANotificationCategory(identifier: "custom_category",
                                         actions: [categoryAction],
                               intentIdentifiers: [],
                   hiddenPreviewsBodyPlaceholder: "Sensitive Content Hidden",
                                         options: [])

// Set the custom categories
UAirship.push().customCategories = [category]

// Update registration
// Define an action for the category
UANotificationAction *categoryAction = [UANotificationAction actionWithIdentifier: @"category_action"
                                                                          options:(UNNotificationActionOptionForeground |
                                                                                  UNNotificationActionOptionDestructive |

// Define the category
UANotificationCategory *category = [UANotificationCategory categoryWithIdentifier:@"custom_category"

// Set the custom categories
[UAirship push].customCategories = [NSSet setWithArray:@[category]];

// Update registration
[[UAirship push] updateRegistration];

Urban Airship reserves category IDs prefixed with "ua_". Any custom categories with that prefix will be dropped.

In order to define a custom Interactive Notification type, you must register a new category.

You can use the hiddenPreviewsBodyPlaceholder argument to specify placeholder text which will be shown instead of the push notification's body when the user has disabled notification previews for the app in iOS 11.

Custom categories are supported by setting the set of categories on UAPush customCategories .

Categories can be set after takeOff. Any modifications to the user notification categories will require an update to the registration settings by calling UAPush updateRegistration .

User Notification Action Callbacks

Custom-defined Interactive Notification types can either make use of Urban Airship's pre-defined actions, or you can write new custom action code. Callbacks are also provided through the UAPushNotificationDelegate .


Urban Airship Actions provides a convenient way to automatically perform tasks by name in response to push notifications, Message Center App Page interactions and JavaScript.

An action is an abstraction over a unary function, which takes an argument and performs a defined task, producing an optional result. Actions may restrict or vary the work they perform depending on the arguments they receive, which may include type introspection and runtime context.

The Urban Airship library comes with pre-made actions for common tasks such as setting/modifying tags, showing a landing page, enabling deep linking, scheduling or canceling action schedules, and deep linking. Actions can also be extended to enable custom application behaviors and engagement experiences.

In iOS, Actions are sent as part of the notification payload as top level key values, where the key is the name of the action and the value is the action's argument. The argument can be any valid JSON value.

Action Situations

Actions are triggered with extra context in the form of a Situation. The different situations allows actions to determine if they should run or not, and possibly do different behavior depending on the situation.

Action was invoked manually.
Action was invoked from a launched push notification.
Action was invoked from a received push notification in the foreground.
Action was invoked from a received push notification in the background.
Action was invoked from JavaScript or a URL.
Action was invoked from a foreground interactive notification button.
Action was invoked from a background interactive notification button.
Action was invoked from automation.

Action Registry

Registering an action:

UAirship.shared().actionRegistry.register(action, names: ["action_name", "action_alias"])
[[UAirship shared].actionRegistry registerAction:action names:@[@"action_name", @"action_alias"]];

Looking up an action entry:

let entry = UAirship.shared().actionRegistry.registryEntry(withName: "action_name")
UAActionRegistryEntry *entry = [[UAirship shared].actionRegistry registryEntryWithName:@"action_name"];

Setting a predicate:

// Predicate that only allows the action to run if it was launched from a push
func predicate(args: UAActionArguments) -> Bool {
    return args.situation == UASituation.launchedFromPush

// Update the predicate
UAirship.shared().actionRegistry.updatePredicate(predicate, forEntryWithName: "action_name")
// Predicate that only allows the action to run if it was launched from a push
UAActionPredicate predicate = ^(UAActionArguments *args) {
    return (BOOL)(args.situation == UASituationLaunchedFromPush);

// Update the predicate
[[UAirship shared].actionRegistry updatePredicate:predicate forEntryWithName:@"action_name"];

The action registry is the central place to register actions by name. Each entry in the registry contains an action, the names that the action is registered under, a predicate that allows filtering when an action can run, and allows specifying alternative actions for different situations.

Triggering Actions

// Run an action by name
UAActionRunner.runAction(withName: "action_name", value: "action_value", situation: UASituation.manualInvocation) { (result: UAActionResult) in
  print("Action finished!")

// Run an action directly
UAActionRunner.runAction(action, value: "action_value", situation: UASituation.manualInvocation) { (result: UAActionResult) in
  print("Action finished!")
// Optional completion handler
UAActionCompletionHandler completionHandler = ^(UAActionResult *result) {
    NSLog(@"Action finished!");

// Run an action by name
[UAActionRunner runActionWithName:@"action_name"

// Run an action directly
[UAActionRunner runAction:action

All actions are run on the main queue. If its possible for an action to block the main queue, it should perform its work on a background queue and call the UAActionCompletionHandler when finished.

Actions can be programmatically through the UAActionRunner , by defining actions in a push notification, from JavaScript using a Custom HTML Template, or from an automation schedule.

Available Actions

The landing page action allows showing a Message Center content page in an overlay.
The open external URL action allows launching any URL. The action will attempt to open the URL using Safari. This action is also provides deep linking. See Deep Linking for iOS for more details on implementing deep linking.
The share action shares text using UIActivityViewController.
The add tags action allows adding one or more tags to the device. Note: action is a no-op when channelTagRegistrationEnabled is set to NO on UAPush , which is the default.
The remove tags action allows removing one or more tags from the device.
The custom event action creates and adds a custom event. See Custom Events for more details on Custom Events.
The pasteboard action sets the text of the system pasteboard.
The display inbox action displays message center messages.
The overlay Message Center action displays an inbox message in a landing page controller.
The schedule action schedules an automation action.
The cancel schedules action cancels automation actions.
The fetch device info action gets an updated snapshot of the devices information from the JS bridge.
The enable feature action enables an Urban Airship feature, such as location, background location, or user notifications.

Custom Actions

Custom Action:

let customAction = UAAction(block: { (args: UAActionArguments, handler: UAActionCompletionHandler) -> Void in
    print("Action is performing with UAActionArguments: \(args)")

UAirship.shared().actionRegistry.register(customAction, name:"custom_action")
UAAction *customAction = [UAAction actionWithBlock: ^(UAActionArguments *args, UAActionCompletionHandler handler) {
    NSLog(@"Action is performing with UAActionArguments: %@", args);

    handler([UAActionResult emptyResult]);

[[UAirship shared].actionRegistry registerAction:customAction name:@"custom_action"];

The action framework supports any custom actions. Create an action by extending the base action class or defining an action using blocks. After takeoff, register the action. The action can be triggered the same way as built-in actions.

On-Device Automation

On-device automation allows the Urban Airship SDK to execute actions when certain conditions are met upon the creation of an analytics event. These conditions are defined as triggers and range from app foreground to screen events. Actions can be scheduled either through an action or using the APIs exposed by the SDK.

Using the Automation Actions

Example schedule payload that will display a landing page after a user has either visited a given page ten times or, as reported through a custom event, purchased items beyond a threshold of $30.

   "schedule_actions" :{
      "limit": 1,
      "start": "2015-04-01T1200",
      "end": "2017-05-01T1200",
      "group": "campaign 1",
      "triggers": [
            "type": "screen",
            "goal": 10,
            "predicate": {
               "value": {
                  "equals": "purchase_page"
            "type": "custom_event_count",
            "goal": 1.0,
            "predicate": {
               "and" : [
                  "key": "event_name",
                  "value": {
                     "equals": "purchase"
                  "key": "price",
                  "scope": ["properties"],
                  "value": {
                     "at_least": "30.0"

The "schedule_actions" action enables scheduling through the Push API as an "app defined" action, through the Urban Airship JavaScript bridge, or directly in the SDK by manually running the action. There are several components to this schedule payload.

Schedule Payload

Optional, group identifier. Useful for canceling and retrieving schedules for a specific campaign.
Optional, start time as an ISO 8601 timestamp. The time before the schedule starts listening for events.
Optional, end time as ISO 8601 timestamp. Once the schedule end time is reached, it will automatically be canceled.
Required, an array of triggers. Triggers cause the actions payload to execute.
Optional, a payload of time and/or app conditions that must be met before the actions are able to be executed. The delay occurs after one of the triggers hits its goals.
Optional, integer defaulting to 1. Number of times to trigger the actions payload before canceling the schedule.
Required, map of actions payloads. Run when one or more of the triggers meets its goal.

Trigger Payload

Required, the event type. Must be one of the valid types below. Each trigger type defines how the goal is incremented and the predicate argument.
Required, the trigger's goal. When the trigger's goal is met, it will trigger the schedule's actions to be executed.
Optional, predicate to filter out events.

Trigger Types

Custom event's value will be applied to the trigger's goal. Predicate is applied to the event.
Custom events will be counted towards the trigger's goal. Predicate is applied to the event.
App init counts will be counted towards the trigger's goal. The predicate is ignored.
App foreground counts will be counted towards the trigger's goal. Predicate is ignored.
App background counts will be counted towards the trigger's goal. The predicate is ignored.
Region enter events will be counted towards the trigger's goal. Predicate is applied to the event.
Region exit events will be counted towards the trigger's goal. Predicate is applied to the event.
Screen tracking. Predicate is applied against the screen's name.

Trigger Predicates

Predicate syntax:

<predicate>        := <json_matcher> | <not> | <and> | <or>
<not>              := { "not": { <predicate> } }
<and>              := { "and": [<predicate>, <predicate>, …] }
<or>               := { "or": [<predicate>, <predicate>, …] }
<json_matcher>     := { <selector>, "value": { <value_matcher> }} | { "value": {<value_matcher>}}
<selector>         := <scope>, "key": string | "key": string | <scope>
<scope>            := "scope": string | "scope": [string, string, …]
<value_matcher>    := <numeric_matcher> | <string_matcher> | <presence_matcher>
<numeric_matcher>  := "equals": number | "at_least": number | "at_most": number | "at_least": number, "at_most": number
<string_matcher>   := "equals": string
<presence_matcher> := "is_present": boolean

The predicate is the core logic within the trigger, presenting a set of structured conditions that are applied to the trigger event. It follows the same patterns as in Custom Event Selectors and may be a value matcher or logical expression.

Delay Payload

Example delay payload:

"delay": {

   // Minimum time in seconds that is needed to pass before running the actions
   "seconds": 10.5,

   // Specifies the ID of a region that the device must currently be in before
   // the schedule's actions are able to be executed.
   "region_id": "region id",

   // Specifies the name of an app screen that the user must currently be
   // viewing before the schedule's actions are able to be executed.
   "screen": "screen name",

   // Specifies the app state that is required before the schedule's actions
   // are able to execute. Either foreground or background.
   "app_state": "foreground",

   // These triggers will cancel the pending execution of the actions
   "cancellation_triggers": [ // triggers ],
Optional, minimum time in seconds that is needed to pass before running the actions.
Optional, specifies the ID of a region that the device must currently be in before the schedule's actions are able to be executed.
Optional, specifies the name of an app screen that the user must currently be viewing before the schedule's actions are able to be executed.
Optional, specifies the app state that is required before the schedule's actions are able to execute. Either "foreground" or "background".
Optional, triggers that will cancel the pending execution of the actions.

Cancelling Actions

Example cancel action payload:

// Cancel all scheduled actions
"cancel_scheduled_actions": "all"

// Cancel specific groups and/or ids
"cancel_scheduled_actions": {
   "ids": ["id 1", "id 2"],
   "groups": ["campaign 1", "campaign 2"]

Just like scheduling actions, canceling scheduled actions can be done with the "cancel_scheduled_actions" action.

Optional. Value for canceling all schedules.
Optional. Either a single group or an array of groups
Optional. Either a single ID or an array of IDs

Using the Automation API

The API provided in UAAutomation allows for access to the automation storage.

Scheduling Actions

Scheduling actions example:

// Build the schedule info
let scheduleInfo = UAActionScheduleInfo { (builder) in
    let valueMatcher = UAJSONValueMatcher(whereStringEquals: "name")
    let jsonMatcher = UAJSONMatcher(valueMatcher: valueMatcher, key: UACustomEventNameKey)
    let predicate = UAJSONPredicate(jsonMatcher: jsonMatcher)

    let customEventTrigger = UAScheduleTrigger.customEventTrigger(with: predicate, count: 2)
    let foregroundEventTrigger = UAScheduleTrigger.foregroundTrigger(withCount: 2)

    builder.actions = ["add_tags_action": "my_tag"]
    builder.triggers = [customEventTrigger, foregroundEventTrigger] = "group_name";
    builder.limit = 4;
    builder.start = NSDate(timeIntervalSinceNow: 10) as Date;
    builder.end = NSDate(timeIntervalSinceNow: 1000) as Date;

// Schedule the schedule info
UAirship.automation().scheduleActions(scheduleInfo) { (schedule) in
    print("Unique schedule identifier: \(schedule!.identifier)");
// Build the schedule info
UAActionScheduleInfo *scheduleInfo = [UAActionScheduleInfo actionScheduleInfoWithBuilderBlock:^(UAActionScheduleInfoBuilder *builder) {
    UAJSONValueMatcher *valueMatcher = [UAJSONValueMatcher matcherWhereStringEquals:@"name"];
    UAJSONMatcher *jsonMatcher = [UAJSONMatcher matcherWithValueMatcher:valueMatcher key:UACustomEventNameKey];
    UAJSONPredicate *predicate = [UAJSONPredicate predicateWithJSONMatcher:jsonMatcher];

    UAScheduleTrigger *customEventTrigger = [UAScheduleTrigger customEventTriggerWithPredicate:predicate count:2];
    UAScheduleTrigger *foregroundEventTrigger = [UAScheduleTrigger foregroundTriggerWithCount:2];

    builder.actions = @{@"add_tags_action": @"my_tag"};
    builder.triggers = @[customEventTrigger, foregroundEventTrigger]; = @"group_name";
    builder.limit = 4;
    builder.start = [NSDate dateWithTimeIntervalSinceNow:10];
    builder.end = [NSDate dateWithTimeIntervalSinceNow:1000];

// Schedule the schedule info
[[UAirship automation] scheduleActions:scheduleInfo completionHandler:^(UASchedule *schedule) {
    NSLog(@"Unique schedule identifier: %@", schedule.identifier);

When a UAActionScheduleInfo instance is scheduled, the module will return a UASchedule instance with a unique ID generated for the the schedule.

Retrieving Scheduled Actions

UAirship.automation().getScheduleWithID(identifier) { (schedule) in
    // get schedule

UAirship.automation().getSchedules { (schedule) in
    // get all schedules

UAirship.automation().getSchedulesWithGroup("group_name") { (schedule) in
    // get all schedules of the given group.
[[UAirship automation] getScheduleWithID:identifier completionHandler:^(UASchedule *schedule) {
    // get schedule

[[UAirship automation] getSchedules:^(NSArray<UASchedule *> *result) {
    // get all schedules

[[UAirship automation] getSchedulesWithGroup:@"group_name" completionHandler:^(NSArray<UASchedule *> *result) {
    // get all schedules of the given group.

The API provides methods for retrieving a single schedule, group of schedules, or all schedules.

Cancelling Scheduled Actions

// Cancels a schedule with the given identifier

// Cancels all schedules of the given group
UAirship.automation().cancelSchedules(withGroup: "some_group_name")

// Cancels all schedules
// Cancels a schedule with the given identifier
[[UAirship automation] cancelScheduleWithID:@"some_scheduled_identifier"];

// Cancels all schedules of the given group
[[UAirship automation] cancelSchedulesWithGroup:@"some_group_name"];

// Cancels all schedules
[[UAirship automation] cancelAll];

Lastly, a series of methods are provided for canceling a single schedule, a group or list of schedules, or all schedules.

Analytics and Reporting

Our iOS client library ships with analytics support out of the box, and by default, there are no explicit preferences you need to set in order to enable reporting. The integration is handled automatically unless you set automaticSetupEnabled to NO. If so, verify you followed the steps in Automatic Integration for proper integration.

Analytics Events and Uploading

Our client library stores events in a local database and uploads them periodically in a background thread. We’ve taken great care to make sure that the database won’t grow beyond a small fixed size, so extended periods of lost connectivity are nothing to worry about. The event upload thread is woken up when new events are triggered and goes to sleep when there are no more events to process, so the impact on battery life is negligible.

Custom Events

let event = UACustomEvent(name: "event_name", value: 123.12)

// Set custom event properties
customEvent.setBoolProperty(true, forKey: "boolean_property")
customEvent.setStringProperty("string_value", forKey: "string_property")
customEvent.setNumberProperty(11, forKey: "number_property")
customEvent.setStringArrayProperty(["string_array_value_1", "string_array_value_2"], forKey: "string_array_property")

// Record the event in analytics
UACustomEvent *event = [UACustomEvent eventWithName:@"event_name" value:@123.12];

// Set custom event properties
[customEvent setBoolProperty:true forKey:@"boolean_property"];
[customEvent setStringProperty:@"string_value" forKey:@"string_property"];
[customEvent setNumberProperty:@11 forKey:@"number_property"];
[customEvent setStringArrayProperty:@[@"string_array_value_1", @"string_array_value_2"]

// Record the event in analytics
[event track]

Custom events let you track user activities and key conversions in your application, and tie them back to corresponding push messaging campaigns. Custom events requires analytics to be enabled. If disabled, any event that is added to analytics will be ignored. For a more detailed explanation on custom events and possible use cases, see the Custom Events topic guide.

Convenient templates are provided to create custom events for common account, media or retail related events. For more details see the Custom Event Templates topic guide.

Screen Tracking

Track a screen:

// Record the event
[[UAirship shared].analytics trackScreen:@"MainScreen"];

The Urban Airship SDK gives you the ability to track what screen a user views within the application, as well as how long the user stayed on that screen and the user's previous screen. These events then come through Urban Airship Connect and allow you to see the path that a user takes through an application, or to trigger actions based on a user visiting a particular area of the application.

When a new screen is tracked or when the application backgrounds, a screen tracking event will be generated. Normally, screen tracking should be called in a view controllers viewDidAppear: method, however it can be called anywhere in the application to start tracking a new screen event.

Disabling Analytics

UAirship.shared().analytics.enabled = false
[UAirship shared].analytics.enabled = NO;

If you do not wish to include analytics and reporting in your application, in your AirshipConfig.plist file, simply set the analyticsEnabled to NO.

When analytics is disabled at runtime it will delete any locally stored events and prevent any events from uploading.


Features that depend on analytics being enabled may not work properly if it's disabled (reports, location segmentation, region triggers, push to local time).

Message Center

Displaying the Message Center

[[UAirship messageCenter] display];

The default message center can be displayed at any time by calling display on the UAMessageCenter instance.

Styling the Message Center

let style = UAMessageCenterStyle()

// Customize the style object
style.navigationBarColor = UIColor(red: 0.988, green: 0.694, blue: 0.106, alpha: 1)
style.titleColor = UIColor(red: 0.039, green: 0.341, blue: 0.490, alpha: 1)
style.tintColor = UIColor(red: 0.039, green: 0.341, blue: 0.490, alpha: 1)

style.titleFont = UIFont(name: "Roboto-Regular", size: 17.0)
style.cellTitleFont = UIFont(name: "Roboto-Bold", size: 14.0)
style.cellDateFont = UIFont(name: "Roboto-Light", size: 12.0)

// Set the style
UAirship.messageCenter().style = style
UAMessageCenterStyle *style = [UAMessageCenterStyle style];

// Customize the style object
style.navigationBarColor = [UIColor colorWithRed:0.988 green:0.694 blue:0.106 alpha:1];
style.titleColor = [UIColor colorWithRed:0.039 green:0.341 blue:0.490 alpha:1];
style.tintColor = [UIColor colorWithRed:0.039 green:0.341 blue:0.490 alpha:1];

style.titleFont = [UIFont fontWithName:@"Roboto-Regular" size:17.0];
style.cellTitleFont = [UIFont fontWithName:@"Roboto-Bold" size:13.0];
style.cellDateFont = [UIFont fontWithName:@"Roboto-Light" size:12.0];

// Set the style
[UAirship messageCenter].style = style;

The default message center's look can be customized by creating a UAMessageCenterStyle instance, setting its style properties, and then setting the style property of the Message Center instance to the customized style instance.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

This can also be done without writing code by creating a plist file. Create a plist with the desired message center style. All the keys correspond to properties on the UAMessageCenterStyle class. Save the plist and include it in the application's target. Then, update messageCenterStyleConfig with the name of the plist file.

Message Center Filtering

Filtering message center messages:

UAirship.defaultMessageCenter().filter = NSPredicate { (evaluatedObject, _) in
     let message = evaluatedObject as! UAInboxMessage
     let titleString:NSString = message.title as NSString
     return titleString.contains("Cool")
[UAirship defaultMessageCenter].filter = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
    UAInboxMessage *message = (UAInboxMessage *)evaluatedObject;
    return [message.title containsString:@"Cool"];

Sometimes it can be useful to filter the contents of the message center according to some predetermined pattern. To facilitate this, use the UAMessageCenter filter property to set a predicate. Once set, only messages that match the predicate will be displayed. As a simple example, the filter shown keeps only messages whose titles contain the string "Cool".

Overriding the default Message Center

self.inboxDelegate = CustomInboxDelegate()
UAirship.inbox().delegate = self.inboxDelegate
self.inboxDelegate = [[CustomInboxDelegate alloc] init];
[UAirship inbox].delegate = self.inboxDelegate;

For custom Message Center implementations, initialize the UAInboxDelegate with the custom Message Center implementation's view controller. This is necessary to ensure that the default modal Message Center is not displayed on top of the custom Message Center when a message is received.

Badge Updates

Updating badge value to message center unread count:

func applicationWillResignActive(application: UIApplication) {
    if (UAirship.inbox().messageList.unreadCount >= 0) {
        application.applicationIconBadgeNumber = UAirship.inbox().messageList.unreadCount
- (void)applicationWillResignActive:(UIApplication *)application {
    if ([UAirship inbox].messageList.unreadCount >= 0) {
        application.applicationIconBadgeNumber = [UAirship inbox].messageList.unreadCount;

The value of the badge can be set in a number of ways. Most often, the number corresponds with some notion of unread or unviewed content, e.g., email messages or friend requests. The most common way to update the badge is directly through APNS, either by passing along the badge integer in the payload of a push notification, or by telling the app to adjust the value using our autobadge feature.

For applications implementing the Message Center, you may want the badge value to represent the actual state of unread messages in the Message Center. If so, then you need to set this behavior in the application delegate.

If you use this method then you should never include badge values in the payload of push notifications, because Message Center will override them.

In-app Messaging

In-App Messages are messages that appear inside of your app, regardless of the opt-in/opt-out status of a user notifications. For more information, please read the iOS In-App Messaging Guide.


Urban Airship UALocation exposes a very simple, high-level API for requesting location.

Enabling location

Enable location:

UAirship.location().isLocationUpdatesEnabled = true
[UAirship location].locationUpdatesEnabled = YES;

Urban Airship's location framework relies on Apple's significant-change location service, which lessens battery impact but requires always-on usage. See Getting the User's Location for details.

Before you can access the user's location, the user must authorize your application via a location authorization prompt. For the authorization prompt to display properly, you must add the NSLocationAlwaysUsageDescription key to your application's info.plist.

When location updates are enabled for the first time it will prompt the user for permission. This behavior can be changed by disabling autoRequestAuthorizationEnabled:

Allow Background Location

Allow background location:

UAirship.location().isBackgroundLocationUpdatesAllowed = true
[UAirship location].backgroundLocationUpdatesAllowed = YES;

Once the app backgrounds, location updates will be suspended by default, then resumed again once the app is foregrounded. To allow location updates to continue in the background, enable backgroundLocationUpdatesAllowed:

SDK Localization

The Urban Airship SDK provides localization for interactive notification buttons and the Message Center for the following languages: English, Chinese (Traditional), Chinese (Simplified), German, Hungarian, Slovak, Russian, Portuguese (Portugal), Portuguese (Brazil), French, Danish, Turkish, Norwegian, Romanian, Polish, Finnish, Dutch, Hindi, Spanish (Latin American), Spanish (Spain), Hebrew, Czech, Italian, Vietnamese, Thai, Japanese, Arabic, Korean, Malay, Indonesian, and Swedish.

The Urban Airship SDK will attempt to look for localized strings in the application's bundle before falling back to a localization provided by the SDK. This allows applications to modify any existing localization files or add other languages. All of SDK strings can be found under the UrbanAirship.strings file.