We’ve made the strategic case elsewhere: the blast era is over, and behavior-triggered notifications are what platforms reward and subscribers tolerate. This guide is the other half — how to actually trigger push notifications from app events on iOS, from instrumentation to the marketing handoff. It’s written for the developer doing the wiring, with the code you’ll ship and the conventions that keep it maintainable.
The architecture in one paragraph
Your app fires named events with typed properties. PushEngage matches those events against trigger rules configured in the dashboard, and campaigns send — immediately, on a delay, or as a multi-step sequence with exit conditions. The division of labor is the point: engineering instruments each event once; marketing creates, edits, and kills campaigns against those events forever after, without another build. Your instrumentation is an API for your marketing team.
trackEvent: the general-purpose signal
The iOS SDK 1.0 introduced trackEvent, the workhorse for custom behavioral signals:
PushEngage.trackEvent(name: "product_viewed",
properties: [
"sku": "WCJ-1042",
"category": "outerwear",
"price": 189.00,
"in_stock": true
],
profileId: currentUserId, // ties the event to an identified subscriber
provider: nil,
eventType: nil) { success, error in
if !success { log(error) }
}
Three rules the SDK enforces, so design for them up front:
- Property values must be strings, numbers, or booleans. Arrays, dictionaries, and dates are rejected client-side — flatten before you send.
- Event names and property keys must be non-empty. The completion handler tells you when validation fails; log it in debug builds.
- Completion handlers arrive on a background queue. Dispatch to main before touching UI.
Pass profileId whenever the user is identified — it’s what lets a campaign follow a customer across devices instead of following a device.
sendTriggerEvent: wiring classic trigger campaigns
For campaigns built in the dashboard’s trigger builder — cart abandonment, browse abandonment, custom journeys — the app fires sendTriggerEvent with the campaign and event names the marketer configured, plus the data tokens the notification template will render:
let trigger = TriggerCampaign(campaignName: "cart_abandonment",
eventName: "add_to_cart",
data: [
"productname": "Waxed Canvas Jacket",
"price": "$189",
"cartlink": "myapp://cart"
])
PushEngage.sendTriggerEvent(triggerCampaign: trigger) { success, error in
// background queue — dispatch before UI work
}
The data tokens flow into the notification copy — that’s how “Your Waxed Canvas Jacket is waiting” gets personalized without the marketer touching code. We walked the full cart recovery sequence in the mobile app cart abandonment playbook; this call is its engine.
addAlert: price drop and back-in-stock, built in
The two highest-intent commerce triggers don’t even need custom campaigns — they’re first-class SDK citizens. When a user watches a product, register the alert:
let alert = TriggerAlert(type: .priceDrop, // or .inventory
productId: "WCJ-1042",
link: "myapp://product/WCJ-1042",
price: 189.00,
data: ["size": "M"])
PushEngage.addAlert(triggerAlert: alert) { success, error in }
PushEngage handles the watching, the matching, and the send when the price falls or stock returns. If you’ve read our price drop notification guide, this is the app-side registration that makes those campaigns fire.
An event taxonomy that scales
Instrumentation debt is real: six months in, nobody remembers whether the event is addToCart, cart_add, or CartUpdated. Pick conventions on day one — snake_case names, object_action ordering, singular property keys — and cover the core commerce set:
| Event | Key properties | Campaigns it powers |
|---|---|---|
product_viewed | sku, category, price | Browse abandonment, personalization |
product_saved | sku, price | Price drop, back-in-stock, win-back hooks |
cart_updated | cart_value, item_count, top_item | Abandono de carrinho |
purchase_completed | order_value, item_count | Exit conditions, post-purchase, goals |
search_performed | query, results_count | Zero-results recovery, interest segments |
onboarding_step | step, completed | Onboarding series branching |
Six events, instrumented once, power the onboarding series, cart recovery, win-back hooks, and every segment your marketing team will ask for this year.
Test the loop before you hand it off
Set PushEngage.enableLogging = true in debug builds and watch events leave the device. Fire each event from a test build, confirm it arrives in the dashboard’s event view, and send one end-to-end test campaign per trigger. The SDK repo’s example apps include a working trigger screen you can crib the flow from. Fifteen minutes of verification here saves the “why didn’t the campaign fire” investigation later — which is usually a typo’d event name on one side of the contract.
The handoff: what marketing owns from here
Once events flow, your part is done. Marketing builds trigger rules, writes copy, sets delays and exit conditions, A/B tests variants, and attaches goal tracking for revenue attribution — all in the dashboard, all without a ticket. Publish the event taxonomy table in your team wiki as the contract between the two sides. Then watch the request queue for “can you send a push” tickets quietly go to zero — which was the point all along. For the strategy those campaigns should follow, hand your marketing team the app push marketing guide.