Skip to main content
Zixflow tracks push notification delivery and engagement so you can measure campaign performance.

Lifecycle events

MetricWhen
Delivered (.delivered)Notification arrives (typically tracked in the Notification Service Extension)
Opened (.opened)User taps the notification
Converted (.converted)Available via trackMetric for custom conversion flows
With autoTrackPushEvents(true) (default) and a Notification Service Extension, delivery and opens are handled for you. Use ZixflowAppDelegateWrapper (APNs) for automatic open handling in the main app.

Payload fields the SDK reads

FieldPurpose
ZIXFLOW-Delivery-IDUnique delivery ID for the campaign send
ZIXFLOW-Delivery-TokenDevice token the notification was sent to
ZIXFLOW.push.linkDeep link URL (optional)
ZIXFLOW.push.imageRich push image URL (optional)
Example payload:
{
  "aps": {
    "alert": {
      "title": "Flash Sale",
      "body": "Limited time only"
    },
    "mutable-content": 1
  },
  "ZIXFLOW-Delivery-ID": "626533406292836846",
  "ZIXFLOW-Delivery-Token": "dcFRlDhiRbehM1vg...",
  "ZIXFLOW": {
    "push": {
      "link": "https://yourapp.com/sale",
      "image": "https://cdn.yourapp.com/banner.png"
    }
  }
}

Delivery tracking (Notification Service Extension)

Initialize the push module for the extension, then call MessagingPush.shared.didReceive:
import UserNotifications
import ZixflowMessagingPushAPN

class NotificationService: UNNotificationServiceExtension {
    override func didReceive(
        _ request: UNNotificationRequest,
        withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
    ) {
        MessagingPushAPN.initializeForExtension(
            withConfig: MessagingPushConfigBuilder(apiKey: "YOUR_API_KEY")
                .appGroupId("group.com.yourcompany.app.zixflow")
                .build()
        )

        MessagingPush.shared.didReceive(request, withContentHandler: contentHandler)
    }

    override func serviceExtensionTimeWillExpire() {
        MessagingPush.shared.serviceExtensionTimeWillExpire()
    }
}
For FCM, call MessagingPushFCM.initializeForExtension instead, then the same MessagingPush.shared methods.
Important: Share an App Group between the main app and the extension, and pass the same .appGroupId(...) (or rely on group.{bundleId}.zixflow inference).

Open tracking

Recommended: Use ZixflowAppDelegateWrapper so opens are tracked automatically. Manual: Forward the notification response to the SDK:
import UserNotifications
import ZixflowMessagingPushAPN

func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void
) {
    _ = MessagingPush.shared.userNotificationCenter(
        center,
        didReceive: response,
        withCompletionHandler: completionHandler
    )
}
Or call metrics yourself:
let userInfo = response.notification.request.content.userInfo
guard
    let deliveryId = userInfo["ZIXFLOW-Delivery-ID"] as? String,
    let deliveryToken = userInfo["ZIXFLOW-Delivery-Token"] as? String
else {
    completionHandler()
    return
}

MessagingPush.shared.trackMetric(
    deliveryID: deliveryId,
    event: .opened,
    deviceToken: deliveryToken
)
completionHandler()
You can also use Zixflow.shared.trackMetric(deliveryID:event:deviceToken:).

App Groups checklist

  1. Enable App Groups on the main app and Notification Service Extension targets
  2. Use the same group ID (for example group.com.yourcompany.app.zixflow)
  3. Pass it to both main-app and extension push config via .appGroupId(...)
MessagingPushAPN.initialize(
    withConfig: MessagingPushConfigBuilder()
        .autoTrackPushEvents(true)
        .appGroupId("group.com.yourcompany.app.zixflow")
        .build()
)

Non-Zixflow pushes

If a notification is not from Zixflow (ZIXFLOW-Delivery-ID is missing), the SDK does not track delivery/open metrics for it. You can still record your own events:
Zixflow.shared.track(
    name: "custom_push_opened",
    properties: ["payload": userInfo]
)

Verify in the dashboard

  1. Enable .logLevel(.debug) while testing
  2. Send a test push to a physical device
  3. Confirm delivery and open metrics under Messaging → Push Notifications in Zixflow
For full setup (capabilities, FCM, deep links), see Push Notifications.