PAYATHON 2026

如何使用 MixPanel 配置 In App Notification?

支付小周

结论

showNotification() 只会展示当前用户符合投放条件,并且 Mixpanel SDK 已经获取到的 In App Notification。它不会创建通知,也不能强制下发通知。

要在 Payment 页面显示 promo code,需要满足以下条件:

  • Mixpanel 后台已经创建并启用了 In App Notification campaign。
  • Campaign 关联的 Mixpanel project/token 与应用当前使用的一致。
  • 当前用户符合 campaign 设置的受众、时间和触发条件。
  • 应用已经调用 identify,且 distinct_id 与 Mixpanel 后台的目标用户一致。
  • SDK 已经获取到 notification 数据。
  • 页面显示完成后,在主线程调用展示方法。

因此,通常应该在 viewDidAppear(_:) 中调用,而不是在 viewWillAppear(_:) 中调用。

推荐调用方式

先确认 Mixpanel 实例不是 nil,完成用户识别,再等 Payment 页面显示后调用:

import Mixpanel

final class PaymentViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        let mixpanel = Mixpanel.sharedInstance()

        DispatchQueue.main.async {
            mixpanel.showNotification()
        }
    }
}

Mixpanel iOS SDK 版本不同,单例 API 也可能不同。如果项目采用较新的初始化方式,应使用应用初始化时保存的同一个实例,不要重新创建。例如:

final class PaymentViewController: UIViewController {

    private let mixpanel: MixpanelInstance

    init(mixpanel: MixpanelInstance) {
        self.mixpanel = mixpanel
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        DispatchQueue.main.async {
            self.mixpanel.showNotification()
        }
    }
}

排查问题时,不要依赖下面这种写法:

mixpanel?.showNotification()

如果 mixpanel 为 nil,可选链会直接跳过调用,也不会报错,表面上很像 Mixpanel 没有返回通知。调试时应明确检查实例:

guard let mixpanel = mixpanel else {
    assertionFailure("Mixpanel instance is nil")
    return
}

mixpanel.showNotification()

确认用户身份

如果 campaign 按用户属性、分群或指定测试用户投放,需要先识别用户,再尝试展示:

let mixpanel = Mixpanel.sharedInstance()

mixpanel.identify(user.id)

mixpanel.people.set([
    "$email": user.email,
    "plan": user.plan
])

这里要重点检查 distinct_id。如果应用使用的 distinct_id 与 Mixpanel 后台用户资料中的 ID 不一致,即使后台配置了目标用户,SDK 也不会判断当前设备符合投放条件。

登录状态变化时,还要注意调用顺序:

mixpanel.identify(user.id)
// 更新用户属性
// 等待 SDK 获取到对应用户可用的 campaign
// 再进入或展示 Payment 页面

不要等通知展示后才调用 identify。

检查 Campaign 配置

在 Mixpanel 后台逐项检查:

  1. Campaign 已经发布,不是草稿,也没有暂停。
  2. Campaign 使用的 project token 与应用初始化 Mixpanel 时的 token 完全一致。
  3. 当前测试用户符合受众条件。
  4. Campaign 的开始时间、结束时间和用户时区没有排除测试用户。
  5. 用户没有因为展示次数、频率限制或已经完成 campaign 而失去资格。
  6. 如果 campaign 由事件触发,应用确实上报了对应事件,事件名的大小写也完全一致。
  7. 测试设备没有被项目的开发、测试或过滤规则排除。

如果想在用户进入 Payment 页面时触发,可以先记录一个明确的事件:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    let mixpanel = Mixpanel.sharedInstance()

    mixpanel.track("Payment Page Viewed", properties: [
        "source": "checkout"
    ])

    DispatchQueue.main.async {
        mixpanel.showNotification()
    }
}

是否需要显式调用 showNotification(),要看项目使用的 Mixpanel SDK 版本和 campaign 的触发方式。有些旧版本会在事件匹配后自动尝试展示,有些集成方式则需要手动调用。应以项目实际安装版本对应的 SDK 文档为准,不要混用不同版本的示例。

为什么建议使用 viewDidAppear

执行 viewWillAppear(_:) 时,Payment 页面可能还没有进入完整的视图层级。In App Notification 通常需要找到当前可见的 UIViewController,再以模态方式展示。调用过早可能遇到以下情况:

  • 页面还没有可用的 presentation context;
  • 导航转场仍在进行;
  • 另一个控制器正在展示;
  • 系统出现 “view is not in the window hierarchy” 一类警告;
  • 通知已经匹配,但展示失败。

改在 viewDidAppear(_:) 中调用,可以减少这类问题:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    guard presentedViewController == nil else {
        return
    }

    Mixpanel.sharedInstance().showNotification()
}

还要避免页面反复出现时重复调用。可以增加一次性保护:

private var hasRequestedNotification = false

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    guard !hasRequestedNotification else {
        return
    }

    hasRequestedNotification = true
    Mixpanel.sharedInstance().showNotification()
}

排查顺序

如果通知仍未显示,可以按下面的顺序排查:

  1. 确认 Mixpanel 实例不是 nil。
  2. 打印当前 distinct_id,并与后台测试用户对照。
  3. 确认 project token 和运行环境正确。
  4. 暂时将 campaign 缩小到只投放给一个明确的测试用户。
  5. 先去掉复杂的分群、频率和时间条件,验证最简单的投放是否正常。
  6. 确认触发事件已经出现在 Mixpanel 中。
  7. 将调用移到 viewDidAppear(_:),并确保它在主线程执行。
  8. 查看 Xcode 控制台中的 Mixpanel 网络请求和视图展示错误。
  9. 检查当前 SDK 版本是否仍支持该 In App Notification API。

Mixpanel 的 In App Notification/Messages 功能及相关 iOS API 在不同历史版本中变化较大,部分旧功能可能已经停止提供。如果后台已经没有对应的 campaign 创建入口,或者当前 SDK 中不存在 showNotification(),就不能继续照搬旧文档。此时应改用 Mixpanel 当前提供的消息能力,或者由应用根据 Remote Config、实验分组或后端接口自行展示 promo code。

备注:内容仅供参考。