Attentive iOS SDK

Who this guide is for

This page is for the people responsible for planning, scoping, and overseeing Attentive mobile SDK integration.

It explains what the SDK enables, the decisions teams need to make, the implementation order, and how to confirm that each phase is working. It is not a step-by-step coding reference. Engineers implementing the SDK should use the iOS SDK README for installation details, API signatures, and code samples.

What the iOS SDK does

The Attentive iOS SDK connects activity in your app to Attentive. It can:

  • Collect email and SMS subscribers through in-app sign-up experiences.
  • Identify users and associate their activity across sessions.
  • Record commerce and custom events for journeys, personalization, and attribution.
  • Register devices for push notifications when Attentive is the push provider.
  • Handle notification opens and deep links so users land on the right screen.

Your engineering team adds the SDK to the app, initializes it at launch, and instruments the relevant authentication, event, message, and creative flows. Those signals then become available in Attentive for activation and reporting.

If your app is built by a mobile app vendor or on a platform that limits third-party SDKs, confirm the supported integration path with your vendor and Attentive contact before scoping the work.

Decisions to make before implementation

  • Dependency manager: Swift Package Manager is recommended; CocoaPods is supported. Manual XCFramework integration is for teams that cannot use either option. It requires Xcode 26.1.1 or later, correct Embed & Sign configuration, and archive validation because incorrect embedding can cause App Store rejection. See Appendix C.
  • SDK version: plan to stay on the current minor release. Attentive publishes SDK updates regularly, each release is backwards-compatible with the previous one unless we say otherwise, and upgrading as new minor versions ship keeps the app on the latest fixes and features. See the Updating Your Mobile SDK Version guide for the release process.
  • Account configuration: obtain the Attentive domain string used to initialize the SDK. Ask your Attentive contact if you do not have it. See the Swift example below.
  • Push ownership: decide whether Attentive will be the app’s push provider. This changes initialization and whether the push phase is required.
  • Identity strategy: decide which identifiers the app can provide at login and how logout should behave. Common values include email, E.164 phone, a stable clientUserId such as a database ID, Shopify, and custom key/value identifiers.
  • Event plan: agree on the commerce and custom events the business needs, including any deep links used by journeys.
  • App architecture: flag webview-based browse, cart, or checkout flows early; those flows may require web tagging rather than native SDK events. See the example below.
  • Launch ownership: name the engineering owner, product owner, Attentive contact, and the evidence required for sign-off. Use the sample launch sign-off checklist below.

Configuration examples

Domain initialization (Swift)

ATTNSDK.initialize(domain: "myCompanyDomain", mode: .production) { result in
  // On success, retain the SDK instance and set up ATTNEventTracker.
}

Identifier examples

  • Email: [email protected]
  • Phone: +15551234567 in E.164 format
  • clientUserId: a stable internal database ID such as customer_12345
  • Shopify: the corresponding platform’s stable customer ID
  • Custom identifier: a stable key/value pair unique to the user

Webview example

The SDK uses a webview only to render Attentive sign-up creatives; it does not render product, cart, checkout, or other app screens. If checkout runs inside a WKWebView, the preferred approach is to bridge the completed-purchase data back to the native app and record the purchase through the SDK. If that is not possible, make sure the web checkout includes a stable identifier—such as email, phone, or clientUserId—so the purchase can be associated with the same Attentive profile. Do not send the same purchase from both the web and native integrations.

Below is a screenshot of the creative that lives inside a WKWebView.

Attentive sign-up creative in the Bonni demo app

(from our demo app Bonni)

For launch evidence, use the sample sign-off checklist below.

How the integration is sequenced

Complete the phases in this order. Each phase depends on the one before it and ends with a practical verification step.

1. Install the SDK

Engineering adds the SDK with Swift Package Manager or CocoaPods. If neither is available, manual XCFramework integration is supported but requires specific embedding and archive validation. See Appendix C.

Verify: the app builds and can import ATTNSDKFramework without an error.

Xcode project with the Attentive iOS SDK installed

2. Initialize at app launch

Initialize ATTNSDK as early as possible in the app launch flow, then set up ATTNEventTracker. Use the production or debug mode appropriate for the build. If Attentive is not the push provider, pass pushEnabled: false during initialization and skip the push phase; the other SDK capabilities remain available.

Verify: launch the app and filter Console.app for attentive-ios-sdk. Initialization logs should appear shortly after launch.

Push opt-out example (Swift)

ATTNSDK.initialize(domain: "myCompanyDomain", mode: .production, pushEnabled: false) { result in
  // On success, retain the SDK instance and set up ATTNEventTracker.
}

3. Wire identity

Most integrations identify users with email. Phone is also supported. If the app needs a durable identifier beyond email or SMS, clientUserId is the recommended choice.

The SDK maintains a single “who is this device currently associated with?” record, and three methods manage it: identify(), clearUser(), and updateUser().

Standard lifecycle: identify() on login, clearUser() on logout. This is the right pattern for most apps. identify() writes the user’s identifiers into the device record so their product views, cart adds, and purchases are attributed to their subscriber profile in Attentive. clearUser() detaches those identifiers and the push token from the person who just signed out, then creates a fresh push-only identity on the device so brand-level campaigns and anonymous browsing can continue without being attributed to the previous account holder.

Example: A shopper signs into a retail app with their email, so the app calls identify() and their activity flows to their profile. They tap “sign out,” so the app calls clearUser(), their email and push token are detached server-side, and they stop receiving push targeted at their logged-in identity. The device keeps a fresh push-only identity so campaign and journey pushes can still reach it. When a different shopper signs in later, the app calls identify() again with the new email.

Alternative lifecycle: use identify() with updateUser() instead of clearUser(). Use updateUser() only when the product intentionally keeps the push token and events attached to the previously signed-in user until another user logs in. At that moment, updateUser() switches the device directly from the old identity to the new one, skipping any anonymous middle state.

Example: On a shared family device, a parent signs in and the app calls identify() with their email. The parent closes the app without signing out, so clearUser() is never called and push continues reaching them, which is intended because they are still the primary account holder. Later, a family member signs in with their own account and the app calls updateUser(), transferring the device cleanly to the new person.

Identity flow at a glance

Standard lifecycle

Anonymous or push-only device
  ↓ identify(email and/or clientUserId)
Signed-in shopper A
  ↓ clearUser() on logout
New anonymous or push-only identity
  ↓ identify(email and/or clientUserId)
Signed-in shopper B

Alternative (shopper A never logs out)

Signed-in shopper A  →  updateUser(email and/or phone)  →  Signed-in shopper B
⚠️

Common mistakes to avoid

  • Avoid calling clearUser() outside a true logout — such as on app open, before every identify(), or in test harnesses. Every call detaches and re-attaches the push token server-side, so call it only when a user genuinely signs out.
  • Avoid mixing clearUser() and updateUser() in the same flow. Pick one pattern per app.
  • Never hard-code a test email or phone. Doing so collapses multiple testers into one subscriber profile and makes the results unreliable.

Verify: The expected subscriber record appears in Attentive with the identifiers the app sent. Test login, logout, account switching, and a fresh install, not only the happy path.

4. Record events

Instrument the SDK’s standard e-commerce event types at the same business-logic points that feed the app’s analytics or order systems: ATTNProductViewEvent, ATTNAddToCartEvent, and ATTNPurchaseEvent. Use ATTNCustomEvent only when an action falls outside those cases. See Appendix A for required fields, examples, and custom-event guidance.

Include deep links when a journey should return the user to a product, cart, or another specific screen. The app—not the SDK—owns the final routing behavior. See Appendix B for configuration patterns and test criteria. If part of the customer journey runs in a webview, coordinate the native and web implementations so events are not missed or counted twice.

Verify: ask your Attentive contact to confirm that test events and payloads are arriving under the correct company domain. A successful on-device request alone does not prove the event is available to the intended account.

5. Set up push, if applicable

Skip this phase when Attentive is not the push provider. Otherwise, request notification permission, pass the APNs device token to Attentive, forward registration failures, handle notifications in foreground and background states, and route notification deep links.

Verify: the device token is associated with the expected subscriber, a test notification appears in foreground, background, and terminated app states, and tapping it opens the intended screen.

6. Show sign-up creatives

Trigger the in-app sign-up experience from an intentional screen and pass the correct host view. In debug or staging builds, bypass creative fatigue rules when repeatable testing is needed; keep normal eligibility behavior in production.

Treat both success and failure statuses as expected outcomes. The app should remain usable when a creative is ineligible, does not open, or closes unexpectedly.

Verify: an eligible test creative opens on a fresh test state, the completion handler reports the outcome, and non-opening outcomes do not block the app UI.

Sample launch sign-off checklist

For a lightweight sign-off, copy this checklist into the launch ticket and add an owner, evidence link or screenshot, status, and approval date to each line.

  • Initialization happens early and uses the correct Attentive domain and environment.
  • Identity behavior is tested across login, logout, account switching, and reinstall scenarios.
  • Commerce events match the app’s source-of-truth analytics or order paths.
  • Custom event names and payloads are agreed before production data begins flowing.
  • Push behavior is tested only if Attentive is the push provider.
  • Creative eligibility, failure handling, and deep-link routing are tested on real devices.
  • Privacy disclosures, permissions, and App Store requirements are reviewed by the appropriate internal owners.
  • SDK upgrades follow the team’s normal release process: review the changelog, test in staging, and validate on a real device.

Appendix A: Event APIs and examples

The iOS integration records events through SDK event types and ATTNEventTracker.sharedInstance().record(event:); the app does not need to call raw Attentive HTTP endpoints.

Standard e-commerce event types

  • ATTNProductViewEvent — a product detail view; provide one or more ATTNItem values and, optionally, a deep link.
  • ATTNAddToCartEvent — an item added to cart; provide ATTNItem values and, optionally, a deep link.
  • ATTNPurchaseEvent — a completed order; provide ATTNItem values and an ATTNOrder with a unique orderId. ATTNCart is optional.

Each ATTNItem requires productId, productVariantId, and an ATTNPrice containing a decimal price and currency code. Optional fields include product image, name, quantity, and category.

Standard event example (Swift)

let price = ATTNPrice(price: NSDecimalNumber(string: "49.00"), currency: "USD")
let item = ATTNItem(productId: "sku-123", productVariantId: "blue-medium", price: price)
let event = ATTNProductViewEvent(items: [item], deeplink: "https://brand.example/products/sku-123")
ATTNEventTracker.sharedInstance()?.record(event: event)

Custom events

Use ATTNCustomEvent when an action is meaningful to the business but is not a product view, cart addition, or purchase. Examples include loyalty enrollment, appointment booking, store-locator use, quiz completion, or content viewed. Keep names stable and agree on the schema with your Attentive contact before launch.

Custom event example (Swift)

guard let event = ATTNCustomEvent(
  type: "Loyalty Enrolled",
  properties: ["tier": "gold", "source": "checkout"]
) else { return }
ATTNEventTracker.sharedInstance()?.record(event: event)

Event names and property keys are case-sensitive. The event type cannot contain special characters.

Appendix B: What well-configured deep links look like

A deep link should be a stable URL that your app can map to one specific destination, such as a product detail page or cart. The SDK passes the URL to the app; the app remains responsible for navigation and for deciding what to do when authentication is required.

Commerce-event example

let event = ATTNAddToCartEvent(
  items: [item],
  deeplink: "https://brand.example/products/sku-123"
)

Push deep-link handling

Option 1: observe .ATTNSDKDeepLinkReceived and read attentivePushDeeplinkUrl from the notification.

Option 2: call consumeDeepLink() when the app is ready to navigate. This consumes and removes the stored URL.

Deep-link sign-off checklist

  • The URL opens the intended screen on a fresh install.
  • The route works when the app is foregrounded, backgrounded, and terminated.
  • Logged-out users follow the intended authentication path before navigation.
  • The link is consumed only once.
  • Product and cart URLs use stable identifiers rather than temporary session state.

Appendix C: Manual XCFramework integration

Use this path only when Swift Package Manager and CocoaPods are not available. The repository requires Xcode 26.1.1 or later for manual XCFramework consumers.

  1. Download and unzip ATTNSDKFramework.xcframework from the selected GitHub release.
  2. Drag the XCFramework folder into the Xcode project navigator.
  3. Under the app target, open General > Frameworks, Libraries, and Embedded Content.
  4. Set ATTNSDKFramework.xcframework to Embed & Sign. Do not add it manually through a Copy Files build phase.
  5. Archive the app and verify that Headers and Modules directories are not embedded inside the distributed framework. Incorrect embedding can cause App Store rejection for disallowed nested bundles.

For implementation details and maintained code samples, use the repository README.

Step 1XCFramework integration Step 1
Step 2aXCFramework integration Step 2a
Step 2bXCFramework integration Step 2b
Step 3XCFramework integration Step 3
Step 4XCFramework integration Step 4

Helpful links


Did this page help you?