Push Message
Supported SDK Version
This feature is supported in iOS SDK version 2.28.0 and above.
Set up APNs
To use push messages in an iOS app, you need to integrate the Hackle workspace with APNs. For more details, please refer to Apple Push Notification Service Setup.
Integrate with Hackle SDK
Pass APNs Token
Complete the following setup to enable Hackle to deliver push messages to devices where the iOS app is installed.
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
return true
}
}
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return YES;
}
For SwiftUI
, register the AppDelegate
in SwiftUI
as follows:
import SwiftUI
@main
struct sampleApp: App {
...
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
...
}
Add the following function to the AppDelegate
:
import Hackle
class AppDelegate: NSObject, UIApplicationDelegate {
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: { _, _ in }
)
UNUserNotificationCenter.current().delegate = self
application.registerForRemoteNotifications()
Hackle.initialize(sdkKey: YOUR_APP_SDK_KEY)
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Hackle.app()?.setPushToken(deviceToken)
}
...
}
#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>
@import Hackle;
@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>
@end
#import "AppDelegate.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {}];
center.delegate = self;
[[UIApplication sharedApplication] registerForRemoteNotifications];
[Hackle initializeWithSdkKey:@"YOUR_APP_SDK_KEY" config:[HackleConfig DEFAULT]];
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[[Hackle app] setPushToken:deviceToken];
}
Display Push Messages
In the Signing & Capabilities
tab of the Xcode project settings, click + Capability
as shown below.
Add Push Notifications
.
To display push messages sent from Hackle, configure as follows:
import Hackle
extension AppDelegate: UNUserNotificationCenterDelegate {
// Foreground push message
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
if Hackle.userNotificationCenter(center: center, willPresent: notification, withCompletionHandler: completionHandler) {
// Succefully processed notification
// Automatically consumed completion handler
return
} else {
// Received not hackle notification or error
print("Do something")
if #available(iOS 14.0, *) {
completionHandler([.list, .banner])
} else {
completionHandler([.alert])
}
}
}
// Converted push message
public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if Hackle.userNotificationCenter(center: center, didReceive: response, withCompletionHandler: completionHandler) {
// Automatically consumed completion handler
return
} else {
// Received non hackle notification or error
print("Do something")
completionHandler()
}
}
}
// Foreground push message
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
if ([Hackle userNotificationCenterWithCenter:center willPresent:notification withCompletionHandler:completionHandler]) {
// Succefully processed notification
// Automatically consumed completion handler
return;
} else {
// Received not hackle notification or error
NSLog(@"Do something");
completionHandler(UNNotificationPresentationOptionList | UNNotificationPresentationOptionBanner);
}
}
// Converted push message
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler {
if ([Hackle userNotificationCenterWithCenter:center didReceive:response withCompletionHandler:completionHandler]) {
// Automatically consumed completion handler
return;
} else {
// Received non hackle notification or error
NSLog(@"Do something");
completionHandler();
}
}
Test Push Messages
Check Token
Verify the token set on the iOS device by following the User Identifier Verification Guide.
Test
Verify the push message on the iOS device by referring to the Push Message Test Sending Guide.
(Advanced) Deep Link Navigation
Hackle push messages support deep link navigation when clicked. If the app opens through a push message, you can check the opened deep link information with the following setup.
For more details on iOS deep linking, please refer to the iOS Deep Linking Guide.
import SwiftUI
@main
struct sampleApp: App {
...
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL(perform: { url in
// Handle opened url
print("\(url.absoluteString) opened.")
})
}
}
...
}
class AppDelegate: NSObject, UIApplicationDelegate {
...
func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:] ) -> Bool {
// Handle opened url
print("\(url.absoluteString) opened.")
}
...
}
Since deep link handling in
SwiftUI
andStoryboard
is independent, configure it according to your iOS app project.
(Advanced) Display Push Messages with Images (Rich Push Notification)
To display push messages with images in an iOS app, you need to add a Notification Service Extension and complete the following setup.
For more details on iOS Rich Push Notification, check Rich Push Notification.
Xcode Setup
In the Xcode project, select File > New > Target...
tab and choose Notification Service Extension
as shown below.
Enter an appropriate name and click Finish
.
CocoaPods Setup
In the Podfile
, configure the previously added Extension
as follows:
use_frameworks!
target 'sampleapp' do
pod 'Hackle', '~> 2.28.0'
end
target 'NotificationServiceExtension' do
pod 'Hackle', '~> 2.28.0'
end
Swift Package Manager Setup
Add the Hackle
framework to the added Extension
.
Display Push Messages
import UserNotifications
import Hackle
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if (Hackle.populateNotificationContent(request: request, withContentHandler: contentHandler)) {
// Succefully processed notification
// Automatically consumed content handler
return
} else {
// Received non hackle notification or error
if let bestAttemptContent = bestAttemptContent {
// Modify the notification content here...
bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"
contentHandler(bestAttemptContent)
}
}
}
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 = self.contentHandler, let bestAttemptContent = self.bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
}
#import <UserNotifications/UserNotifications.h>
@import Hackle;
@interface NotificationService : UNNotificationServiceExtension
@end
#import "NotificationService.h"
@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@end
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
if ([Hackle populateNotificationContentWithRequest:request withContentHandler:contentHandler]) {
// Succefully processed notification
// Automatically consumed content handler
return;
} else {
// Received non hackle notification or error
self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];
self.contentHandler(self.bestAttemptContent);
}
}
- (void)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.
self.contentHandler(self.bestAttemptContent);
}
@end
Updated 8 months ago