This PR is to add a new target that is exported independently using SPM and Cocoapods to users and will be integrated into the notification service extension that users will create on their mobile apps to handle rich push notifications.
Some considerations that we considered are -
We decided against including the logic to download and attach image into the core SDK mainly because
The notification service extensions that users create on their apps are granted limited memory by app and hence bundling our SDK into the extension will unnecessarily bloat up the extension size.
There are some application methods that are used in our SDK that are not available to access from an extension such as UIApplication.shared which is used to open deep links.
We decided to move the logic to download image and attach it into the SDK vs. leaving it to our users for the below reasons -
Lesser code for our users to maintain
Easily to debug user issues when reported.
How would our users include this in their SDK -
SPM -
Since the package is already pulled into user's apps that use Klaviyo, they only need to include this in their NotificationServiceExtension frameworks and targets section of this target -
Cocoapods -
Unfortunately, Cocoapods doesn't support sub specs for extensions - GH issue. Because of this we export the extension logic as a separate pod which user can import in their notification service extension target as below -
target 'NotificationServiceExtension' do
pod 'KlaviyoSwiftExtension'
end
^ is separate from the KlaviyoSwift that the main app target imports
The full pod file would look something like -
platform :ios, '13.0'
use_frameworks!
target 'CocoapodsExample' do
pod 'KlaviyoSwift'
end
target 'NotificationServiceExtension' do
pod 'KlaviyoSwiftExtension'
end
Once included in the SDK below is how it would be imported and used in the notification service extension -
import UIKit
import UserNotifications
import KlaviyoSwiftExtension
// MARK: notification service extension implementation.
/// When push payload is marked as there being mutable-content this service
/// (more specifically the `didReceiveNotificationRequest` ) is called to perform
/// tasks such as downloading images and attaching it to the notification before it's displayed to the user.
///
/// There is a limited time before which `didReceiveNotificationRequest` needs to wrap up it's operations
/// else the notification is displayed as received.
///
/// Any property from `UNMutableNotificationContent` can be mutated here before presenting the notification.
class NotificationService: UNNotificationServiceExtension {
var request: UNNotificationRequest!
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(
_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.request = request
self.contentHandler = contentHandler
self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
KlaviyoExtensionSDK().handleNotificationServiceDidReceivedRequest(
request: self.request,
bestAttemptContent: bestAttemptContent,
contentHandler: contentHandler
)
}
}
override func serviceExtensionTimeWillExpire() {
/// Called just before the extension will be terminated by the system.
/// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
if let contentHandler = contentHandler,
let bestAttemptContent = bestAttemptContent {
KlaviyoExtensionSDK().handleNotificationServiceExtensionTimeWillExpireRequest(
request: self.request,
bestAttemptContent: bestAttemptContent,
contentHandler: contentHandler
)
}
}
}
Description
This PR is to add a new target that is exported independently using SPM and Cocoapods to users and will be integrated into the notification service extension that users will create on their mobile apps to handle rich push notifications.
Some considerations that we considered are -
UIApplication.shared
which is used to open deep links.How would our users include this in their SDK -
SPM -
Since the package is already pulled into user's apps that use Klaviyo, they only need to include this in their
NotificationServiceExtension
frameworks and targets section of this target -Cocoapods -
Unfortunately, Cocoapods doesn't support sub specs for extensions - GH issue. Because of this we export the extension logic as a separate pod which user can import in their notification service extension target as below -
^ is separate from the KlaviyoSwift that the main app target imports
The full pod file would look something like -
Once included in the SDK below is how it would be imported and used in the notification service extension -