map-o file-code-o arrow-directionplatform-webreach-project-type-boarding-passreach-project-type-couponreach-project-type-event-ticketreach-project-type-genericreach-project-type-gift-cardreach-project-type-loyalty-cardreach-project-type-member-card pictures more_vert chain keyboard_arrow_down keyboard_arrow_right

iOS

This is a developers’ guide for setting up an Urban Airship for a Native iOS application. 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.

Resources

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.

CocoaPods

Install CocoaPods:

$ gem install cocoapods

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

Update the podfile

Example podfile:

use_frameworks!

# Urban Airship SDK
target "<Your Target Name>" do
  pod 'UrbanAirship-iOS-SDK'
end

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

When targeting tvOS - specify the platform in your podfile:

platform :tvos, '10.0'

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.

Install the pods

Update the installed pods:

$ pod install

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.

Carthage

Before you begin, ensure you have Carthage installed.

Adding the SDK framework to your application

Specify the Urban Airship iOS SDK in your cartfile:

github "urbanairship/ios-library"

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

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.

Manual

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.

To link against the embedded framework, add the AirshipKit.framework file to the Embedded Binaries section in the General tab for your target. This should also add it to the Linked Frameworks and Libraries section. Verify Enable Modules and Link Frameworks Automatically are enabled in the project’s Build Settings.

Make sure AirshipKit.framework shows up in the Linked Frameworks and Libraries section in the General tab for your target.

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" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>developmentAppKey</key>
  <string>Your Development App Key</string>
  <key>developmentAppSecret</key>
  <string>Your Development App Secret</string>
  <key>productionAppKey</key>
  <string>Your Production App Key</string>
  <key>productionAppSecret</key>
  <string>Your Production App Secret</string>
  <key>useWKWebView</key>
  <true/>
</dict>
</plist>

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.

TakeOff

Example app delegate changes:

import AirshipKit

...

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

    UAirship.takeOff(config)

    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:didFinishLaunchingWithOptions: 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

If your app is targeting iOS 9 or higher, Message Center content features such as Landing Pages will only be able to load SSL-encrypted web content out of the box. This change, known as App Transport Security, will not affect content hosted on Urban Airship’s servers, which is SSL-encrypted. 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 |
                                              UNNotificationPresentationOptionSound);

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.

tvOS

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
        completionHandler(.noData)
    }

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

        // Let system handle it
        completionHandler()
    }

    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.

Analytics

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

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);

Adding an NSNotificationCenter observer for UAChannelCreatedEvent:

NotificationCenter.default.addObserver(self,
                              selector:#selector(myClass.mySelector),
                                  name:NSNotification.Name(UAChannelCreatedEvent),
                                object:nil);
// Add observer to the UAChannelCreatedEvent
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(mySelector)
                                             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;

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.

The Channel ID will be logged for all apps. You can always 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.

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 .

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
UAirship.takeOff(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, didRegister notificationSettings: UIUserNotificationSettings) {
     UAAppIntegration.application(application, didRegister: notificationSettings)
}

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

func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [AnyHashable : Any], completionHandler: @escaping () -> Void) {
    if let actionIdentifier = identifier {
        UAAppIntegration.application(application, handleActionWithIdentifier: actionIdentifier, forRemoteNotification: userInfo, completionHandler: completionHandler)
    }
}

func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [AnyHashable : Any], withResponseInfo responseInfo: [AnyHashable : Any], completionHandler: @escaping () -> Void) {
    if let actionIdentifier = identifier {
        UAAppIntegration.application(application, handleActionWithIdentifier: actionIdentifier, forRemoteNotification: userInfo, withResponseInfo: responseInfo, completionHandler: completionHandler)
    }
}

// UNUserNotificationCenterDelegate methods

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

func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
    UAAppIntegration.userNotificationCenter(center,
    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 didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [UAAppIntegration application:application didRegisterUserNotificationSettings:notificationSettings];
}

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

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())handler {
    [UAAppIntegration application:application handleActionWithIdentifier:identifier forRemoteNotification:userInfo completionHandler:handler];
}

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())handler {
    [UAAppIntegration application:application handleActionWithIdentifier:identifier forRemoteNotification:userInfo withResponseInfo:responseInfo completionHandler:handler];
}

// 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.

Logging

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 to 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.

Disabling Notifications (iOS 8 & 9)

Link to application settings:

// Open the system settings app directly to this application (on iOS 8+)
if let url = URL(string: UIApplicationOpenSettingsURLString) {
     UIApplication.shared.openURL(url)
}
// Open the system settings app directly to this application (on iOS 8+)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];

The SDK prevents disabling userPushNotificationsEnabled by default on iOS 8 and 9 due to iOS bugs. For those versions, we recommend that the application link directly to the application’s system push settings with the UIApplicationOpenSettingsURLString URL constant.

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 the notificationOptions on the UAPush instance.

Foreground Presentation Options

Setting default presentation options:

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

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
        completionHandler(.noData)
    }

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

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

    @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
        completionHandler(UIBackgroundFetchResultNoData);
    }

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

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

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

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.

Badges

Setting the badge value:

UAirship.push().setBadgeNumber(20)
[[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()
[[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
UAirship.push().updateRegistration()
// 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.

Tags

Modifying tags:

// Set 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()
// 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 it 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 20 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
UAirship.push().updateRegistration()
// 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
UAirship.namedUser().updateTags()
// 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 Tag Group Walkthrough will guide you through the creation of your first Tag Group.

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
UAirship.shared().analytics.associateDeviceIdentifiers(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
UAirship.push().updateRegistration()
// Define an action for the category
UANotificationAction *categoryAction = [UANotificationAction actionWithIdentifier: @"category_action"
                                                                            title:@"Action!"
                                                                          options:(UNNotificationActionOptionForeground |
                                                                                  UNNotificationActionOptionDestructive |
                                                                                  UNNotificationActionOptionAuthenticationRequired)];

// Define the category
UANotificationCategory *category = [UANotificationCategory categoryWithIdentifier:@"custom_category"
                                                                          actions:@[categoryAction]
                                                                intentIdentifiers:@[]
                                                                          options:UNNotificationCategoryOptionNone];

// 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 .

Actions

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.

UASituationManualInvocation
Action was invoked manually.
UASituationLaunchedFromPush
Action was invoked from a launched push notification.
UASituationForegroundPush
Action was invoked from a received push notification in the foreground.
UASituationBackgroundPush
Action was invoked from a received push notification in the background.
UASituationWebViewInvocation
Action was invoked from JavaScript or a URL.
UASituationForegroundInteractiveButton
Action was invoked from a foreground interactive notification button.
UASituationBackgroundInteractiveButton
Action was invoked from a background interactive notification button.
UASituationAutomation
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"
                            value:@"actionValue"
                        situation:UASituationManualInvocation
                completionHandler:completionHandler];

// Run an action directly
[UAActionRunner runAction:action
                    value:@"actionValue"
                situation:UASituationManualInvocation
        completionHandler:completionHandler];

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 Templates, or from an automation schedule.

Available Actions

UALandingPageAction
The landing page action allows showing a Message Center content page in an overlay.
UAOpenExternalURLAction
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 iOS Deep Linking for more details on implementing deep linking.
UAShareAction
The share action shares text using UIActivityViewController.
UAAddTagsAction
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.
UARemoveTagsAction
The remove tags action allows removing one or more tags from the device.
UAAddCustomEventAction
The custom event action creates and adds a custom event. See Custom Events for more details on Custom Events.
UAPasteboardAction
The pasteboard action sets the text of the system pasteboard.
UADisplayInboxAction
The display inbox action displays message center messages.
UAOverlayInboxMessageAction
The overlay Message Center action displays an inbox message in a landing page controller.
UAScheduleAction
The schedule action schedules an automation action.
UACancelSchedulesAction
The cancel schedules action cancels automation actions.
UAFetchDeviceInfoAction
The fetch device info action gets an updated snapshot of the devices information from the JS bridge.
UAEnableFeatureAction
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)")
    handler(UAActionResult.empty())
})

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" :{
      "actions":{
         "landing_page_action":"https://www.urbanairship.com"
      },
      "limit": 1,
      "start": "2015-04-01T12:00:00",
      "end": "2017-05-01T12:00:00",
      "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

group
Optional, group identifier. Useful for canceling and retrieving schedules for a specific campaign.
start
Optional, start time as an ISO 8601 timestamp. The time before the schedule starts listening for events.
end
Optional, end time as ISO 8601 timestamp. Once the schedule end time is reached, it will automatically be canceled.
triggers
Required, an array of triggers. Triggers cause the actions payload to execute.
delay
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.
limit
Optional, integer defaulting to 1. Number of times to trigger the actions payload before canceling the schedule.
actions
Required, map of actions payloads. Run when one or more of the triggers meets its goal.

Trigger Payload

type
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.
goal
Required, the trigger’s goal. When the trigger’s goal is met, it will trigger the schedule’s actions to be executed.
predicate
Optional, predicate to filter out events.

Trigger Types

custom_event_value
Custom event’s value will be applied to the trigger’s goal. Predicate is applied to the event.
custom_event_count
Custom events will be counted towards the trigger’s goal. Predicate is applied to the event.
app_init
App init counts will be counted towards the trigger’s goal. The predicate is ignored.
foreground
App foreground counts will be counted towards the trigger’s goal. Predicate is ignored.
background
App background counts will be counted towards the trigger’s goal. The predicate is ignored.
region_enter
Region enter events will be counted towards the trigger’s goal. Predicate is applied to the event.
region_exit
Region exit events will be counted towards the trigger’s goal. Predicate is applied to the event.
screen
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 ],
}
seconds
Optional, minimum time in seconds that is needed to pass before running the actions.
region_id
Optional, specifies the ID of a region that the device must currently be in before the schedule’s actions are able to be executed.
screen
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.
app_state
Optional, specifies the app state that is required before the schedule’s actions are able to execute. Either “foreground” or “background”.
cancellation_triggers
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.

all
Optional. Value for canceling all schedules.
group
Optional. Either a single group or an array of groups
ids
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]
    builder.group = "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];
    builder.group = @"group_name";
    builder.limit = 4;
    builder.start = [NSDate dateWithTimeIntervalSinceNow:10];
    builder.end = [NSDate dateWithTimeIntervalSinceNow:1000];
}];

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

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

Retrieving Scheduled Actions

UAirship.automation().getScheduleWithIdentifier(scheduleIdentifier) { (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] getScheduleWithIdentifier:scheduleIdentifier completionHandler:^(UAActionSchedule *schedule) {
    // get schedule
}];

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

[[UAirship automation] getSchedulesWithGroup:@"group_name" completionHandler:^(NSArray<UAActionSchedule *> *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
UAirship.automation().cancelSchedule(withIdentifier: "some_scheduled_identifier")

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

// Cancels all schedules
UAirship.automation().cancelAll()
// Cancels a schedule with the given identifier
[[UAirship automation] cancelScheduleWithIdentifier:@"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.

Reports

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)

// Record the event
UAirship.shared().analytics.add(event)
UACustomEvent *event = [UACustomEvent eventWithName:@"event_name" value:@123.12];

// Record the event
[[UAirship shared].analytics addEvent:event];

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 iOS Event Templates topic guide.

Screen Tracking

Track a screen:

UAirship.shared().analytics.trackScreen("MainScreen")
// 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.defaultMessageCenter().display()
[[UAirship defaultMessageCenter] display];

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

Styling the Message Center

let style = UADefaultMessageCenterStyle()

// 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.defaultMessageCenter().style = style
UADefaultMessageCenterStyle *style = [UADefaultMessageCenterStyle 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 defaultMessageCenter].style = style;

The default message center’s look can be customized by creating a UADefaultMessageCenterStyle 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" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>titleFont</key>
        <dict>
                <key>fontName</key>
                <string>Roboto-Regular</string>
                <key>fontSize</key>
                <string>17</string>
        </dict>
        <key>titleColor</key>
        <string>#00698f</string>
        <key>tintColor</key>
        <string>#00698f</string>
        <key>navigationBarColor</key>
        <string>#eaaa00</string>
        <key>iconsEnabled</key>
        <false/>
        <key>cellTitleFont</key>
        <dict>
                <key>fontName</key>
                <string>Roboto-Bold</string>
                <key>fontSize</key>
                <string>13</string>
        </dict>
        <key>cellDateFont</key>
        <dict>
                <key>fontName</key>
                <string>Roboto-Light</string>
                <key>fontSize</key>
                <string>17</string>
        </dict>
</dict>
</plist>

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 UADefaultMessageCenterStyle 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 UADefaultMessageCenter 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 messaging requires remote-notification background mode.

In-app messages are banner notifications that appear inside of your app. Aside from giving you the power to engage with users as they browse your app, they also allow you to reach opted out users in iOS 8 and above, a segment of the app audience that has previously been difficult to target.

Display

Adjusting the auto-display delay to five seconds:

UAirship.inAppMessaging().displayDelay = 5
[UAirship inAppMessaging].displayDelay = 5;

By default, in-app messages will only display a single banner on app foreground after a three-second delay. You can change this by setting the displayDelay property on [UAirship inAppMessaging] :

Display ASAP Mode

Enabling display ASAP:

UAirship.inAppMessaging().displayASAPEnabled = true
[UAirship inAppMessaging].displayASAPEnabled = YES;

Exercise caution when using display ASAP mode. The default auto display behavior for in-app messages is designed to offer a balance between immediacy and user experience, by minimizing the chance of accidentally disrupting the user’s activities in your app. Push automation may also occasionally see latencies that result in associated in-app messages being displayed in unexpected contexts.

Enabling display ASAP mode will cause the SDK to display the in-app message on arrival. If the app is currently in the background, the in-app message will be displayed on the next foreground after the auto display delay. If a message is already displaying when a new in-app message is received, the new message will be displayed once the currently displayed message is dismissed, after the autodisplay delay.

Manual Display

Disabling automatic display:

UAirship.inAppMessaging().isAutoDisplayEnabled = false
[UAirship inAppMessaging].isAutoDisplayEnabled = NO;

Manually displaying in-app messages:

UAirship.inAppMessaging().displayPendingMessage()
[[UAirship inAppMessaging] displayPendingMessage];

The automatic display of in-app messages can be disabled, either to block message display in response to user preferences or to manually control when and where messages should be displayed.

In the latter case, message display can be triggered manually so that the most recent pending message is displayed at a time more appropriate for the app:

Styling and Custom UI

Sending in-app message color overrides is supported through the composer and push API. Additional advanced styling can also be achieved by setting optional properties on the UAInAppMessaging class.

UAirship.inAppMessaging().messageControllerDelegate = myMessageControllerDelegate
[UAirship inAppMessaging].messageControllerDelegate = myMessageControllerDelegate;

More comprehensive custom UI is possible by setting an optional UAInAppMessageControllerDelegate on the UAInAppMessaging object, which is used to configure details such as custom message views and animation hooks.

For more information, see: In-App Message Customization.

Location

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.

Never miss out on product updates

Click "Allow" in the browser prompt in the upper left hand corner of your browser.

Next, we'll allow you to choose what sort of notifications you'd like to receive.

Choose your notification topics

Product Subscription Options

    Platform Subscription Options