This guide shows you how to use the ProjectorKit
SDK for iOS and implement its features in your own application code.
TODO - decide how to provision ProjectorKit - binary or open source repo
Follow these steps to get up and running using the API defined by the Projector
class.
In order to use the ProjectorKit
in your application, you’ll need an application token.
This is provisioned through the Projector Dashboard
. TODO - get screenshots etc
It is referred to in ProjectorKit
as the variable or function argument appToken
.
In all of the following sections you’ll need to ensure that you have the Projector
class in scope by importing ProjectorKit
.
Find the list of imports near the top of your *.swift
files and be sure to add the following line in that section.
import ProjectorKit
You’ll need to modify or create two implementations of delegate interfaces from UIKit
.
In the next subsections you’ll find detailed instructions on exactly what to add and where to put it.
If you already have your UIApplicationDelegate
implementation class defined, adding the necessary Projector
class hooks is easy.
If you need to create your UIApplicationDelegate
class, please see the documentation here from Apple.
We recommend that you also implement your UNUserNotificationCenterDelegate
in the same class. Please see the documentation here.
Add the following lines to your UIApplicationDelegate
class:
First find, or create, the method application(_:didFinishLaunchingWithOptions:)
Inside this method add the following line anywhere before your return statement, replacing the appToken
argument $MyApplicationToken
with the application token you retrieved from the Projector Dashboard
:
Projector.shared.initUserNotifications(appToken: $MyApplicationToken, delegate: self)
An example implementation might look like this if your class implementing UIApplicationDelegate
also implements the UNUserNotificationCenterDelegate
protocol:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// note below: self refers to this class as its implementing UNUserNotificationCenterDelegate as well
Projector.shared.initUserNotifications(appToken: "OurApplication-2222224848000", delegate: self)
return true
}
If you’re implementing your UNUserNotificationCenterDelegate
in another place, you’ll need to pass in that object into this method as the delegate.
Then you need to add in application user notification registration handlers as follows.
Find, or create, the method application(_:didRegisterForRemoteNotificationsWithDeviceToken:)
Inside this method we need to pass the device token to Projector
. Add the following line anywhere you like inside this method:
Projector.shared.deviceToken = deviceToken
An example implementation might look like this:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Projector.shared.deviceToken = deviceToken
NSLog("\(#function) - Device Token - \(Projector.shared.pushToken)")
}
Then, find or create, the method application(_:didFailToRegisterForRemoteNotificationsWithError:)
Inside this method we handle the case that the application failed to register with APNS. We simply assign an empty string to the Projector
pushToken
variable.
For example:
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
NSLog("\(#function) - Error - \(error.localizedDescription)")
#if (arch(i386) || arch(x86_64)) && os(iOS)
Projector.shared.pushToken = ""
#endif
}
Then you need to wire up the various application lifecycle callback methods from UIApplicationDelegate
.
Find, or create, the method applicationDidEnterBackground(_:)
Inside this method add the following line anywhere you like:
Projector.shared.applicationDidEnterBackground()
An example implementation might look like:
func applicationDidEnterBackground(_ application: UIApplication) {
Projector.shared.applicationDidEnterBackground()
}
Find, or create, the method applicationWillEnterForeground(_:)
Inside this method add the following line anywhere you like:
Projector.shared.applicationWillEnterForeground()
An example implementation might look like:
func applicationWillEnterForeground(_ application: UIApplication) {
Projector.shared.applicationWillEnterForeground()
}
Find, or create, the method applicationDidBecomeActive(_:)
Inside this method add the following line anywhere you like:
Projector.shared.applicationDidBecomeActive()
An example implementation might look like:
func applicationDidBecomeActive(_ application: UIApplication) {
Projector.shared.applicationDidBecomeActive()
}
Find, or create, the method applicationWillTerminate(_:)
Inside this method add the following line anywhere you like:
Projector.shared.applicationWillTerminate()
An example implementation might look like:
func applicationWillTerminate(_ application: UIApplication) {
Projector.shared.applicationWillTerminate()
}
Now we need to add a means to intercept background (content-available
) remote notifications.
In the case that you’ve already implemented content-available
style background notification handling in your application, find the method application(_:didReceiveRemoteNotification:)
If you haven’t implemented this or don’t wish to use content-available
notifications, enabling many powerful Projector
features, skip this step.
If you want to implement the method, an example Projector
integration merely involves adding the following lines anywhere inside your method:
guard let request = UNNotificationRequest(withRemoteNotification: userInfo) else {
completionHandler(.noData)
return
}
Projector.shared.didReceiveRemoteNotification(request: request)
where the most basic implementation - with no other special support inside your application, might look like this:
@nonobjc func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
guard let request = UNNotificationRequest(withRemoteNotification: userInfo) else {
completionHandler(.noData)
return
}
NSLog("Intercepting background push")
Projector.shared.didReceiveRemoteNotification(request: request)
completionHandler(.noData)
}
If your application supports user notification categories (as in UNNotificationCategory
), you must pass these to the Projector
object in order to support Projector
features.
If your application doesn’t define any such categories, you don’t need to do anything outside of the initUserNotifications
hook call.
It is recommended that you pass your user notification categories to the Projector
object in the applicationDidBecomeActive(application:)
method inside your UIApplicationDelegate
class.
However, you are free to call the setNotificationCategories(_:)
method whenever you desire.
Add the following lines of code inside that method, where $aReferenceToMyAppNotificationCategorySet
is a reference to your set of categories object:
let appNotificationCategories: Set<UNNotificationCategory> = $aReferenceToMyAppNotificationCategorySet
Projector.shared.setNotificationCategories(appNotificationCategories)
An example implementation might look like this:
func applicationDidBecomeActive(_ application: UIApplication) {
Projector.shared.setNotificationCategories(appNotificationCategories) // example: appNotificationCategories here is referenced from a field in your class
Projector.shared.applicationDidBecomeActive()
}
If you with to identity your users in Projector
with your unique application user identification string, the logic is similar to setting the user notification categories section above.
It is recommended that you pass your unique user id to the Projector
object in the applicationDidBecomeActive(application:)
method inside your UIApplicationDelegate
class.
However, you are free to call the setUserId(id:)
method whenever you desire.
Add the following lines of code inside that method, where $aReferenceToTheUserId
is a reference to your set of categories object:
let userId: String = $aReferenceToTheUserId
Projector.shared.setUserId(id: userId)
An example implementation might look like this:
func applicationDidBecomeActive(_ application: UIApplication) {
Projector.shared.setUserId(id: userId) // example: userId here is referenced from a field in your class
Projector.shared.applicationDidBecomeActive()
}
ProjectorKit
enables the capture of metadata surrounding custom application events. For example, your application might have logic wherein a user performs a transaction that you’d like to measure in relation to other application lifecycle behaviors, such as opening an application or receiving a push notification.
In order to achieve this measurement using ProjectorKit
all you need to do is add the following method to the appropriate place in your application:
let name: String = $nameOfMyCustomAction
let metadata: [String: String] = $customActionMetadataDictionary
Projector.shared.customAction(name: name, metadata: metadata)
For example, imagine you had a method called in your application when a shopping cart was purchased:
func shoppingCartPurchased(withCount itemCount: Int, forPrice price: Dollars, serverNotification callback: () -> Void) -> Void {
Projector.shared.customAction(name: "shoppingCartPurchased", metadata: ["itemCount": "\(itemCount)", "price": "\(price)"])
callback
}
The metadata dictionary can be empty.
You are free to add this in as many places as you’d like in your application code.