设置 iOS 卸载跟踪

文档

iOS 卸载跟踪设置

使用与 Singular SDK 集成的 Apple Push Notification 服务 (APNs) 跟踪 iOS 上的应用程序卸载情况,以衡量用户保留率、识别低质量流量来源并优化营销活动性能。


概述

卸载跟踪如何工作

Singular通过苹果推送通知服务发送静默推送通知,并监测推送响应以确定设备上是否仍安装有应用程序,从而检测iOS应用程序的卸载情况。

技术流程

  1. 令牌注册:Singular SDK向Singular服务器注册APNs设备令牌。
  2. 用户选择加入:用户在 iOS 提示下授予推送通知权限
  3. 静默通知:Singular定期向注册设备发送静默推送通知
  4. 发送反馈:APN 报告推送成功或失败
  5. 卸载检测:发送失败表明应用程序已卸载
  6. 事件记录:卸载事件归因于原始安装源

要求

  • SDK 版本:卸载跟踪需要 iOS SDK 8.0 以上版本
  • APNs 证书:来自 Apple Developer 账户的生产 SSL 证书
  • 支持推送通知:应用程序必须实现 APNs 注册和令牌处理
  • 用户同意:用户必须选择接受推送通知,跟踪才能正常工作
  • 应用程序更新:用户必须安装启用卸载跟踪功能的更新版应用程序

重要注意事项

用户选择加入要求:根据苹果公司的政策,用户必须明确选择接收推送通知。 Singular 只能跟踪已授予通知权限的用户的卸载情况。

关键点

  • 静默通知:Singular的卸载跟踪使用静默推送通知,不会向用户显示任何可见提醒。
  • 保留归属:卸载作为事件跟踪,不会删除原始归属链接。用户可能会多次卸载和重新安装,可能导致卸载率超过 100%。
  • 批量处理:卸载检测基于批处理,依赖于 APN 的响应反馈。预计卸载数据将在 24 小时内出现在 Singular 面板中
  • 权限依赖性:跟踪覆盖率与推送通知选择加入率直接相关。选择加入率低的应用程序将有不完整的卸载数据
  • 网络依赖性:静默推送通知需要活跃的网络连接。设备长时间离线可能会延迟卸载检测

设置说明

通过集成 Singular SDK、实施 Apple Push Notifications 并将 APNs 证书上传到 Singular 来配置 iOS 卸载跟踪。

步骤 1:集成 iOS SDK 8.x+

更新 SDK 版本

升级到 iOS SDK 8.0 或更高版本,以启用卸载跟踪功能。

安装 CocoaPods

Podfile
platform :ios, '12.0'
use_frameworks!

target 'YourApp' do
  # Singular iOS SDK
  pod 'Singular-SDK', '~> 12.6.2'
end

Swift 软件包管理器

Xcode
// File > Add Package Dependencies
// Enter repository URL:
https://github.com/singular-labs/Singular-iOS-SDK

// Select version: 12.6.2 or later

完整集成指南:iOS SDK 集成指南


步骤 2:配置苹果推送通知

启用推送通知功能

在您的 Xcode 项目中添加推送通知功能,并在应用程序中实施 APN 注册。

Xcode 配置

  1. 打开项目设置:在 Xcode 导航器中选择您的项目
  2. 选择目标:选择您的应用程序目标
  3. 添加能力:转到 "签名和功能 "选项卡
  4. 启用推送:单击 "+ 能力 "并添加 "推送通知
  5. 后台模式:在后台模式功能下启用 "远程通知

首次设置:如果这是您第一次为 iOS 实施推送通知,请参阅全面的《苹果推送通知服务 (APN) 设置指南》


实施 APNs 注册

添加代码以注册推送通知,并将 APNs 设备令牌传递给 Singular SDK。

Swift
import UIKit
import UserNotifications
import Singular

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    func application(_ application: UIApplication, 
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        // Request push notification permissions
        requestPushNotificationPermissions()
        
        // Initialize Singular SDK
        let config = SingularConfig(apiKey: "SDK KEY", secret: "YOUR_SECRET")
        Singular.start(config)
        
        return true
    }
    
    func requestPushNotificationPermissions() {
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            if granted {
                print("Push notification permission granted")
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            } else {
                print("Push notification permission denied")
            }
        }
    }
    
    // Called when APNs successfully registers device
    func application(_ application: UIApplication, 
                     didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        
        // Pass token to Singular for uninstall tracking
        Singular.registerDeviceToken(forUninstall: deviceToken)
        
        // Convert token to hex string for logging
        let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
        print("APNs device token registered: \(tokenString)")
    }
    
    // Called if APNs registration fails
    func application(_ application: UIApplication, 
                     didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register for remote notifications: \(error.localizedDescription)")
    }
    
    // Handle incoming push notifications
    func application(_ application: UIApplication,
                     didReceiveRemoteNotification userInfo: [AnyHashable : Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        
        // Pass notification data to Singular
        Singular.handleNotification(userInfo)
        
        completionHandler(.newData)
    }
}

iOS 13+ 要求:从 iOS 13 开始,收到授权后必须在主线程中调用registerForRemoteNotifications() 。如上所示,使用DispatchQueue.main.async

完整实施指南:Singular iOS SDK 实施指南


第 3 步:创建苹果推送通知证书

生成 APN SSL 证书

在苹果开发者账户中创建生产 SSL 证书,以便 Singular 发送推送通知,进行卸载跟踪。

  1. 打开 Apple Developer Portal:导航至苹果开发者
  2. 访问证书:转到证书、标识符和配置文件
  3. 选择标识符:单击左侧边栏中的标识符
  4. 选择应用程序 ID:从列表中选择应用程序的标识符
  5. 配置推送通知:滚动到应用程序服务并找到推送通知
  6. 创建证书:单击推送通知旁边的 "配置
  7. 选择类型:为生产证书选择 "Apple Push Notification service SSL (Sandbox & Production)"(苹果推送通知服务 SSL(沙盒和生产))。

证书类型要求:单个卸载跟踪要求实时应用程序使用生产 SSL 证书。开发证书只能用于内部测试。


创建证书签名请求(CSR)

在 Mac 上生成 CSR 以创建 APNs 证书。

  1. 打开钥匙串访问在 Mac 上启动钥匙串访问应用程序
  2. 请求证书:钥匙串访问菜单 → 证书助手 → 向证书颁发机构申请证书
  3. 输入电子邮件:提供电子邮件地址
  4. 通用名称:输入描述性名称(例如,"YourApp Push Notifications
  5. 保存到磁盘:选择 "保存到磁盘 "选项
  6. 继续:单击 "继续 "保存 CSR 文件

上传 CSR 和下载证书

将 CSR 上传到 Apple Developer 门户,生成 APN SSL 证书。

  1. 上传 CSR:在苹果开发者门户网站,上传你创建的 CSR 文件
  2. 生成证书:单击继续生成证书
  3. 下载证书:下载生成的 .cer 文件
  4. 安装证书:双击 .cer 文件,将其添加到 Mac 钥匙串中

第 4 步:将证书导出为 .p12 文件

从钥匙串生成 P12

从钥匙串中导出 APNs 证书和私钥作为 .p12 文件上传到 Singular。

  1. 打开钥匙串访问启动钥匙串访问应用程序
  2. 选择证书:在 "我的证书 "类别中,找到您的 APNs 证书
  3. 展开证书:单击披露三角形,显示与证书配对的私钥
  4. 选择两个项目:按住 Command 键并同时点击证书和私人密钥以选择它们
  5. 导出:右键单击并选择 "导出 2 项..."
  6. 另存为 P12:选择 .p12 格式并以有意义的文件名保存(如 "YourApp_APNs_Production.p12")。
  7. 设置密码:输入密码以保护 .p12 文件(上传到 Singular 时需要此密码
  8. 确认:单击 "确定 "导出文件

安全提示:妥善保存 .p12 文件并记住密码。将证书上传到 Singular 时需要这两个密码。请勿公开共享这些证书。


步骤 5:将证书上传到 Singular

配置 Singular 应用程序设置

将 .p12 证书文件上传到 Singular 的应用程序配置,以启用卸载跟踪。

  1. 打开 Singular 应用程序:导航至Singular 应用程序页面
  2. 选择应用程序:从列表中选择您的 iOS 应用程序
  3. 高级设置:滚动到高级设置部分
  4. 卸载跟踪:找到 "卸载跟踪 "配置
  5. 上传证书:单击 "Choose File(选择文件)"并选择 .p12 文件
  6. 输入密码: 输入导出 .p12 文件时创建的密码
  7. 保存配置:单击 "保存 "应用设置

iOS Uninstall Tracking Configuration

验证:上传后,Singular 将验证证书。如果验证失败,请确认您使用的是生产证书,且密码正确。


测试卸载跟踪

在将更新后的应用程序发布到生产环境之前,验证卸载跟踪配置是否正确。

测试步骤

验证步骤

  1. 安装测试版本:在测试设备上部署启用卸载跟踪功能的应用程序
  2. 授予权限:启动应用程序并在出现提示时接受推送通知权限
  3. 验证注册:检查 Xcode 控制台是否有 APNs 设备令牌注册信息
  4. 确认 SDK 注册:验证 SDK 日志是否显示与 Singular 的令牌注册成功
  5. 等待批处理:等待 24-48 小时,让 Singular 发送第一个无声通知
  6. 卸载应用程序:从测试设备中删除应用程序
  7. 监控仪表板:24-48 小时后检查 Singular 面板,查看卸载事件

测试时间表:卸载跟踪基于批处理,可能需要 48 小时才能检测和报告卸载。这种延迟是预期行为。


Xcode 控制台验证

检查 Xcode 控制台输出的 Singular SDK 消息,确认配置正确。

预期日志信息

[Singular] APNs device token registered successfully
[Singular] Uninstall tracking enabled
[Singular] Device token sent to Singular servers

常见问题

问题 原因 解决方法
推送权限对话框未出现 权限已被拒绝或未申请 重置权限:设置 → 通用 → 传输或重置 iPhone → 重置 → 重置位置和隐私
未生成设备令牌 推送通知功能未启用 验证 "推送通知 "功能是否已在 Xcode 中启用 签名和功能
注册失败并显示错误 缺少或不正确的配置文件 确保供应配置文件包括推送通知权限
证书验证在 Singular 中失败 证书类型错误或证书过期 验证您使用的是生产型 SSL 证书,且未过期
令牌未到达 Singular SDK 未初始化或网络连接问题 确保在registerDeviceToken()之前调用Singular.start()
卸载未出现在仪表板中 用户未授予推送权限 卸载跟踪仅对选择接收通知的用户有效

模拟器限制

需要物理设备:APNs 设备令牌生成在 iOS 模拟器中不起作用。您必须在物理 iOS 设备上测试卸载跟踪。


优化推送通知选择加入率

通过提高授予推送通知权限的用户比例,最大限度地扩大卸载跟踪覆盖范围。

最佳实践

授权前提示

在显示 iOS 系统权限对话框之前,显示自定义应用内说明,以提高接受率。

  • 解释价值:明确传达用户从启用通知中获得的益处
  • 时机:在用户了解其价值时,在与上下文相关的时刻请求权限
  • 自定义 UI:在系统提示前显示带有 "允许 "和 "现在不行 "按钮的自定义对话框
  • 重试逻辑:如果用户拒绝,则在他们体验过应用价值后再次提示

实施示例

Swift
class NotificationManager {
    
    func showPrePermissionPrompt() {
        // Check if permission already requested
        UNUserNotificationCenter.current().getNotificationSettings { settings in
            if settings.authorizationStatus == .notDetermined {
                DispatchQueue.main.async {
                    self.displayCustomPrompt()
                }
            }
        }
    }
    
    private func displayCustomPrompt() {
        let alert = UIAlertController(
            title: "Stay Updated",
            message: "Enable notifications to receive important updates about your orders and exclusive offers.",
            preferredStyle: .alert
        )
        
        alert.addAction(UIAlertAction(title: "Enable Notifications", style: .default) { _ in
            self.requestSystemPermission()
        })
        
        alert.addAction(UIAlertAction(title: "Not Now", style: .cancel) { _ in
            // User declined - mark for retry later
            UserDefaults.standard.set(Date(), forKey: "last_notification_prompt")
        })
        
        // Present from root view controller
        UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true)
    }
    
    private func requestSystemPermission() {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            if granted {
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
    }
}

上下文权限请求

有效的时间策略

  • 首次交易后:在用户完成首次购买或有意义的操作后提出请求
  • 功能介绍:在介绍依赖通知的功能时提示
  • 价值展示:在用户体验到应用程序的价值后请求
  • 避免首次启动:在用户了解应用价值之前,不要在首次打开应用时提出请求

分析卸载数据

在 Singular 报告中使用 iOS 卸载数据来优化营销活动效果并识别流量质量问题。

可用指标

卸载跟踪指标

  • 卸载次数:检测到的卸载应用程序总数
  • 卸载率:导致卸载的安装百分比
  • 可跟踪用户率:选择推送通知的用户百分比
  • 卸载天数:安装与卸载事件之间的平均时间
  • 按来源分类的卸载:按活动、发布者和创意分列的卸载情况
  • 群组分析:不同用户群的卸载模式

覆盖范围注意事项

跟踪覆盖范围:iOS 卸载跟踪仅覆盖授予推送通知权限的用户。监控您应用的通知选择加入率,以了解卸载跟踪的覆盖率。

覆盖率计算

Tracking Coverage % = (Users with Push Enabled / Total Installs) × 100

使用案例

营销活动优化

  • 识别低质量流量和高卸载率的营销活动
  • 比较不同流量来源的卸载率
  • 根据预测的用户保留率优化竞价策略
  • 调整创意信息以吸引更高质量的用户

欺诈检测

  • 检测显示安装欺诈的异常卸载模式
  • 标记卸载率可疑较高的发布商
  • 监控卸载时间,查找僵尸流量迹象
  • 通过快速卸载识别点击注入模式

用户保留分析

  • 跟踪一段时间内的应用粘性和参与度
  • 将卸载与应用程序更新或功能发布联系起来
  • 识别导致用户流失的因素
  • 根据用户人口统计和行为细分卸载率

最佳实践

优化策略

  • 设定基准:为不同类型的营销活动设定可接受的卸载率阈值
  • 监控趋势:跟踪一段时间内的卸载率,以识别季节性模式或异常情况
  • 细分分析:比较不同用户人口、地域和设备的卸载率
  • 归因窗口:在评估营销活动绩效时考虑卸载时机
  • 质量评分:将卸载率纳入流量质量评分模型
  • 覆盖范围跟踪:监控通知选择加入率,了解数据完整性
  • 比较分析:比较 iOS 和 Android 卸载模式,了解特定平台的情况