Carillon docs

Swift SDK

Install and configure the iOS SDK, forward callbacks, and handle notification taps.

For text, number, boolean and date attributes, SDK methods and audience operators, see Tags.

Requirements: iOS 15+ and Swift 5.9+. Configure the SDK with your app's mobile key.

Samples on this page show placeholders. Sign in to the dashboard in this browser and they fill in with your own organization, app and mobile key.

Install

In Xcode, choose File, then Add Package Dependencies, and add:

https://github.com/exostack/carillon-swift

Select the latest tagged release with the Up to Next Major Version rule. See the published versions.

Or in a Package.swift:

.package(url: "https://github.com/exostack/carillon-swift.git", .upToNextMajor(from: "0.5.0"))

Add the Push Notifications capability to your target, which is what puts the aps-environment entitlement in the binary.

Configure

import CarillonCarillon.configure(key: "carillon_mk_live_your_mobile_key", debug: true)// Call when your app should request notification permission.await Carillon.requestPermission()   // .allowed | .denied | .provisional

configure takes an optional endpoint: too, which is how a build points at a different environment.

Forward three callbacks

Forward registration results and notification taps from your app delegate. The SDK does not install these callbacks automatically.

func application(_ app: UIApplication,
                 didRegisterForRemoteNotificationsWithDeviceToken token: Data) {
  Carillon.didRegister(token: token)
}

func application(_ app: UIApplication,
                 didFailToRegisterForRemoteNotificationsWithError error: Error) {
  Carillon.didFailToRegister(error)
}

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completion: @escaping () -> Void) {
  Carillon.didOpen(response)
  completion()
}

Set UNUserNotificationCenter.current().delegate as the first thing in didFinishLaunching, so an app launched by a tap has somewhere to deliver its open to.

Identity, tags, and open callbacks

Carillon.identify("user-42")
Carillon.clearIdentity()

Carillon.setTag("plan", "pro")
Carillon.setTagNumber("seats", 5)
Carillon.setTagBoolean("beta", true)

Carillon.optOut()
Carillon.optIn()

Carillon.onOpened = { notification in
  // notification.deliveryId, notification.userInfo, notification.openedAt
}

let info = Carillon.debugInfo()

setTags merges keys; pass nil to remove a key. setTag("plan", "pro") changes one key and removeTag("plan") removes it. Omitted keys remain unchanged. See tags.

Environment detection

The SDK reads aps-environment from the embedded provisioning profile at runtime.

SigningEnvironment
development profilesandbox
Simulatorsandbox
No profile: TestFlight, App Storeproduction

It is re-derived on every launch and never persisted, so a rebuild with different signing reports the new environment immediately.

Registration is also attempted on the simulator. Actual sandbox token support depends on the host and simulator runtime. If token acquisition fails, inspect didFailToRegister and debugInfo(), or use a physical device.

Foreground notifications

Forward presentation to the SDK, then choose whether to show the banner:

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            willPresent notification: UNNotification,
                            withCompletionHandler completion: @escaping (UNNotificationPresentationOptions) -> Void) {
  Carillon.willPresent(notification, completionHandler: completion)
}

Carillon.onReceived = { notification in
  // Read notification.data and return .suppress for your own in-app UI.
  return .show
}

Carillon.clearNotifications()

Without a handler, the SDK requests banner, list, sound and badge presentation. Notifications without a Carillon stamp have a nil deliveryId. Clearing removes delivered notifications from Notification Center; it does not change subscription or permission.

Images

Add a Notification Service Extension target named CarillonNotificationExtension in Xcode. Use bundle ID <your bundle ID>.CarillonNotificationExtension, and add the Swift package's CarillonNotificationExtension product to this target.

import UserNotifications
import CarillonNotificationExtension

final class NotificationService: UNNotificationServiceExtension {
  private var helper: CarillonNotificationExtension?

  override func didReceive(_ request: UNNotificationRequest,
    withContentHandler handler: @escaping (UNNotificationContent) -> Void) {
    helper = CarillonNotificationExtension.didReceive(request, withContentHandler: handler)
  }

  override func serviceExtensionTimeWillExpire() {
    CarillonNotificationExtension.serviceExtensionTimeWillExpire(helper)
  }
}

The helper reads carillon.image. It downloads over HTTPS within 20 seconds, limits the file to 10 MiB, and keeps the original notification if the download or attachment fails. No App Group is needed. Add the extension bundle ID to your signing profiles, including Fastlane match. Send a notification with payload.image to verify the attachment on a device.

Device ID

Carillon.deviceId is nil before registration succeeds. Carillon.onDeviceIdChanged fires on first registration and when the server returns a different ID. Token rotation preserves the ID when the SDK's stored installation proof matches. See device identity.

Where state lives

UserDefaults in the app container: the last registered state hash, the server device id, installation proof and any queued events. The OS may restore this state from a backup; the device ID is not an authentication credential.

Track opens · Devices · Troubleshooting

Receipt tracking

To record notifications before the app launches, install the notification service extension above and enable the same App Group on both app and extension targets. Add CarillonAppGroup to both Info.plist files with the shared group identifier (for example group.com.example.app.carillon). Include it in both provisioning profiles and rebuild the app. The extension saves receipts locally; the host app reports them on its next launch or activation.

SDK 0.5.0 reports observed receipts from its receive callback and recovers notifications still present when the app starts or resumes. It does not report an open for these notifications. See receipt tracking for platform limits, offline reporting, and reading the timestamps in a trace.

On this page