Notification Content Extension
A notification content extension can provide a custom interface when a user previews your notification in the notification center. Content extensions provide a great user experience because they’re integrated with the notification center and run in a process independent of the main application. Sometimes,however, it’s necessary for the main application to receive feedback when a content extension is displayed. This guide demonstrates how tocreate a content extension that can pass data into a custom analytics event to be uploaded by the main application.
Create a Content Extension
Add a Notification Content Extension target to your application by selecting File -> New -> Target… and then selecting the Notification Content Extension
icon in the Application Extension
section:

Typically extensions are named with a suffix on the main application’s bundle identifier. For example, the
extension’s bundle identifier for the com.airship.sample
app might be com.airship.sample.ExampleContentExtension
.
Check that the the “Embed App Extensions” build phase for your app’s target contains your newly created extension.
Install Airship Notification Content Extension Dependencies
CocoaPods
Content extensions depend on the NotificationContent subspec of the AirshipExtensions pod.
Example podfile:
target "<Your Content Extension Target Name>" do
pod 'AirshipExtensions/NotificationContent'
end
Install using the following command:
$ pod install
Carthage
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 AirshipNotificationContentExtension.framework to your content extension target.
If you are also using the Airship SDK, follow the instructions in the iOS SDK Guide.
Specify the Airship iOS SDK in your cartfile:
github "urbanairship/ios-library"
Verify Enable Modules
and Link Frameworks Automatically
are enabled in the project’s Build Settings.
Manual
Follow the same manual process to install AirshipNotificationContentExtension.xcframework using the same method that you followed to install Airship.xcframework, except add AirshipNotificationContentExtension.xcframework to your content extension target.
Customize Your Content Extension View
When the content extension target is created, a view controller and storyboard are generated. These can be edited to display a custom interface when your push notification is opened in the system notification center.
Add Extension Attributes
A separate Info.plist file will be generated for your extension when you add your Content Extension target. For your extension to work properly, there are a couple keys that are important to have in your content extension’s Info.plist
:
UNNotificationExtensionCategory
set to <Your Category>
: The category allows the system to select you extension for display.
UNNotificationExtensionUserInteractionEnabled
set to true
: This allows your extension to receive touch events from the user. Note: This functionality is only available in iOS 12 and above.
When you are finished adding attribute keys - your extension’s Info.plist should look something like this:
Create and Set Your Category
In your AppDelegate’s application:didFinishLaunchingWithOptions:
callback, initialize and set a category that matches the category you set under the UNNotificationExtensionCategory
key in your extension’s Info.plist:
// Define your category
let category = UANotificationCategory(identifier: "<Your Category>",
actions: [],
intentIdentifiers: [],
hiddenPreviewsBodyPlaceholder: "Sensitive Content Hidden",
options: [])
// Set your custom categories
UAirship.push().customCategories = [category]
Pass Custom Event Data To Main Application
Custom events can only be created and added to analytics inside the main application. This means any custom event data originating in the content extension must be passed to the main application before being initialized into a custom event and added to analytics. This can be accomplished by using user defaults and an app group. An app group allows sharing a user defaults directory between two or more targets. This allows the content extension to save custom event data as it is generated and for the main application to retrieve and send it when it launches.
Add an App Group
An app group can be added by following these steps:
- Visit the Apple Developer portal in a web browser.
- Navigate to the
Certificates, Identifiers & Profiles
section. - Select
App Groups
under theIdentifiers
sidebar menu. - Select the add (+) button and add your app group i.e. “group.com.yourdomain.yourapp”.
Once your app group is added you’ll need to repeat the following steps inside Xcode for both your main application and your content extension target:
- Select your target
- Open the Capabilities tab
- Flip the App Groups switch to the
ON
position - Check the corresponding app group
Save Custom Event Data
When your content extension is opened, the UNNotificationContentExtension
protocol’s application:didReceive
callback will be called in your content extension’s generated view controller. In this callback, custom event data can be generated and saved to the group user defaults directory. In your content extension’s application:didReceive
callback, add the following:
let customEventsKey = "com.urbanairship.content-extension-events"
...
// Create dictionary with custom event data
let customEventDict:[String:Any] = [customEventNameKey:"ConentExtensionEventName", customEventTimestampKey:NSNumber(value:Date.timeIntervalSinceReferenceDate)]
let groupDefaults = UserDefaults(suiteName: "group.com.yourdomain.yourapp") ?? UserDefaults.init(suiteName: "group.com.yourdomain.yourapp")
// Parse custom events array from user defaults
var customEventsArray = groupDefaults!.array(forKey: customEventsKey) ?? []
customEventsArray.append(customEventDict)
// Store custom events array in user defaults
groupDefaults!.set(customEventsArray, forKey: customEventsKey);
Retrieve Event Data and Send Custom Event
Inside your main application’s AppDelegate
, add the following method and call it within the didFinishLaunchingWithOptions
callback:
// Retrieves custom event data from UserDefaults if one exists and sends it
func sendContentExtensionCustomEvents() {
let customEventsKey = "com.urbanairship.content-extension-events"
let customEventNameKey = "com.urbanairship.content-extension-event-name"
let customEventTimestampKey = "com.urbanairship.content-extension-event-timestamp"
let groupDefaults = UserDefaults(suiteName: "group.com.yourdomain.yourapp") ?? UserDefaults.init(suiteName: "group.com.yourdomain.yourapp")
// Parse custom event dictionaries from user defaults
if let customEvents = groupDefaults!.array(forKey: customEventsKey) {
for customEventDict in customEvents {
guard let normalized = customEventDict as? Dictionary<String, Any> else { continue }
guard let customEventName = normalized[customEventNameKey] as? String else { continue }
guard let customEventTimestamp = normalized[customEventTimestampKey] as? NSNumber else { continue }
// Generate and add custom event to analytics
UAirship.analytics()?.add(UACustomEvent(name: customEventName, value:customEventTimestamp))
}
// Overwrite custom events with empty array
groupDefaults!.set([], forKey: customEventsKey);
}
}
Debugging
Debugger feedback and console messages from the extension will not be forwarded to the debugging process of your application. To debug a content extension, you need to follow these steps:
Testing with Push
The easiest way to test your content extension is to send a push that includes your category and mutable_content
set to true
inside the ios
payload dictionary.
{
"audience": {"tag":"<Your Audience>"},
"device_types" : ["ios"],
"notification" : {
"ios": {
"category": "<Your Category>",
"alert": "Content extension alert with custom event",
"mutable_content": true
}
}
}
Categories