支持推送通知
通过将苹果推送通知服务(APN)与 Singular SDK 集成,跟踪用户与推送通知的互动,以衡量再参与活动并准确归因转化。
请遵循以下实施指南,以确保通知数据正确传递到 Singular SDK,从而实现正确的归因。
为什么要跟踪推送通知?推送通知能促进用户重新参与,但跟踪需要正确的集成。Singular 可确保与通知互动的用户得到正确归因,从而优化营销活动和参与策略。
实施指南
注册推送通知
请求用户授权接收推送通知,并使用 odedeUNUserNotificationCenter 注册应用程序的 APN。
import UserNotifications
// Set the current instance as the delegate for UNUserNotificationCenter
UNUserNotificationCenter.current().delegate = self
// Define the notification authorization options (alert, badge, sound)
let pushAuthOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
// Request notification authorization from the user
UNUserNotificationCenter.current().requestAuthorization(options: pushAuthOptions) { granted, error in
// If an error occurs during authorization, print the error description
if let error = error {
print("registerForPushNotifications : failure - \(error.localizedDescription)")
}
// If the user granted permission, register for remote notifications
if granted {
// Ensure registration is done on the main thread
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
- (void)registerForPushNotifications:(UIApplication *)application {
// Set delegate to self
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
// Define the push notification options
UNAuthorizationOptions pushAuthOptions = UNAuthorizationOptionAlert |
UNAuthorizationOptionBadge |
UNAuthorizationOptionSound;
// Request push notification authorization
[[UNUserNotificationCenter currentNotificationCenter]
requestAuthorizationWithOptions:pushAuthOptions
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (error) {
NSLog(@"registerForPushNotifications : failure - %@", error.localizedDescription);
}
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
[application registerForRemoteNotifications];
});
}
}];
}
最佳实践:在应用程序生命周期的早期请求通知授权,最好是在向用户展示价值后,以提高选择加入率。
处理通知回复
在用户点击推送通知时处理通知响应,并将有效载荷数据转发给 Singular 进行跟踪。
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
// Extract the notification payload
let userInfo = response.notification.request.content.userInfo
// Pass the notification data to Singular for tracking
Singular.handlePushNotification(userInfo)
// Call the completion handler to indicate processing is complete
completionHandler()
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler {
// Extract the push notification payload (user info)
NSDictionary *userInfo = response.notification.request.content.userInfo;
// Log the userInfo dictionary for debugging purposes
NSLog(@"didReceiveNotificationResponse userInfo = %@", userInfo);
// Pass the notification data to Singular for tracking
[Singular handlePushNotification:userInfo];
// Call the completion handler to indicate processing is complete
completionHandler();
}
最佳实践:始终及时调用完成处理程序,确保系统知道通知处理已完成。 延迟完成可能会导致系统警告或节流。
为推送有效载荷配置 SDK
在 SDK 配置中添加推送通知有效载荷选择器,以指定 Singular 链接在通知数据结构中的位置。
func getConfig() -> SingularConfig? {
guard let config = SingularConfig(apiKey: "SDK_KEY", andSecret: "SDK_SECRET") else {
return nil
}
// Configure push notification link paths
config.pushNotificationLinkPath = [
["sng_link"],
["rootObj", "nestedObj", "anotherNested", "singularLink"]
]
return config
}
// Start the Singular SDK with the configuration
if let config = getConfig() {
Singular.start(config)
}
- (SingularConfig *)getConfig {
SingularConfig *config = [[SingularConfig alloc] initWithApiKey:@"SDK_KEY"
andSecret:@"SDK_SECRET"];
// Configure push notification link paths
config.pushNotificationLinkPath = @[
@[@"sng_link"],
@[@"rootObj", @"nestedObj", @"anotherNested", @"singularLink"]
];
return config;
}
// Start the Singular SDK with the configuration
SingularConfig *config = [self getConfig];
[Singular start:config];
选择器配置:
-
简单键:对有效载荷中的顶级键使用
["sng_link"] - 嵌套键:使用 odede["rootObj", "nestedObj", "key"]遍历嵌套的 JSON 结构
- 多路径:定义多个选择器数组,以检查奇异链接的不同可能位置
验证指南
验证启动会话中的有效载荷
通过检查启动会话 API 调用,确认推送通知链接已正确传递给 Singular。
当用户点击通知时,Singular SDK 会在开始会话请求的singular_link 参数下包含推送通知有效载荷。
启动会话请求示例:
https://skan.singular.net:443/api/v1/start?
dnt=-1
&update_time=0
&singular_link=https://sl.sng.link/Cclbu/2a7n?_dl=com.singular.app&_smtype=3
&i=com.singular.SwiftScene
&sdk=Singular/12.7.1
&p=iOS
&v=18.2.1
替代验证:使用 Singular SDK 控制台验证推送通知跟踪。检查Deeplink URL字段,确认跟踪链接已正确捕获。
高级配置
ESP 域配置
如果您在电子邮件服务提供商(ESP)或其他第三方域中封装 Singular 链接,请配置外部域。
func getConfig() -> SingularConfig? {
guard let config = SingularConfig(apiKey: "SDK_KEY", andSecret: "SDK_SECRET") else {
return nil
}
// Configure ESP domains for wrapped links
config.espDomains = ["sl.esp.link", "custom.domain.com"]
return config
}
- (SingularConfig *)getConfig {
SingularConfig *config = [[SingularConfig alloc] initWithApiKey:@"SDK_KEY"
andSecret:@"SDK_SECRET"];
// Configure ESP domains for wrapped links
config.espDomains = @[@"sl.esp.link", @"custom.domain.com"];
return config;
}
安全提示:默认情况下,只允许在 "Singular 管理链接 "页面中预定义sng.link域。 如果使用封装链接,请明确配置 ESP 域。
动态深度链接路由
通过配置一个具有动态重定向重写功能的 Singular 跟踪链接,从单个通知中实现多个深度链接目的地。
用例示例:具有多个操作选项的突发新闻通知
-
阅读最新新闻:
newsapp://article?id=12345 -
热门话题
newsapp://trending -
体育:
newsapp://sports
与其创建多个跟踪链接,不如使用一个单一链接,并根据用户选择动态覆盖重定向。有关实施详情,请参阅在奇异跟踪链接中覆盖重定向。
重要注意事项
实施注意事项
-
无回调处理程序:与
singularLinksHandler不同,推送通知功能不提供有效载荷回调。请实施您自己的深度链接逻辑,将用户引导至您应用中的特定内容。 -
归属流:当用户点击通知时,Singular 会检索有效载荷并将其包含在由
Singular.start()触发的启动会话事件中。后台会处理这些数据,对推送通知接触点进行归属,并注册重新参与跟踪 -
域限制:默认情况下,只允许使用 "管理链接 "页面上的 Singular 链接域 (
sng.link)。请使用espDomains为封装链接明确配置 ESP 域。
成功:通过这些步骤,您的应用程序现在可以通过 Singular 跟踪推送通知互动,从而提高活动绩效洞察力,并确保准确的再参与归因。