iOS SDK
activeThe iOS output of the Binoban Native SDK, distributed as a
binary framework — the exhaustive configuration and method reference. For
installing the dependency, initializing in your AppDelegate, and sending a
first event, start with the
Track from iOS tutorial.
Install
The primary distribution path is Swift Package Manager. The Xcode GUI path
(File → Add Package Dependencies…) is covered in the
tutorial. If you manage
dependencies in a Package.swift manifest instead, add:
dependencies: [
.package(url: "https://github.com/binoban/binoban-sdk-swift", from: "1.1.0")
]
CocoaPods is also supported as an alternative:
platform :ios, '12.0'
target 'YourApp' do
use_frameworks!
pod 'binoban', '~> 1.0'
end
pod install
Open the generated .xcworkspace (not the .xcodeproj) from then on. This
step applies only to the CocoaPods path — Swift Package Manager needs no
such step.
Either path resolves to a binary XCFramework hosted at
https://static.binoban.io/sdk/ios/1.1.0/binoban.xcframework.zip — no separate
build step.
Requirements: iOS 12.0+, Xcode 15.0+ / Swift tools 5.9. Check the compatibility matrix for the current version.
BinobanFactory, not Configuration(writeKey:)Always initialize through BinobanFactory.shared.create(apiKey:sourceIdentifier:),
as shown in the tutorial. Some SDK-internal examples construct a Configuration
directly with a writeKey parameter — that path is not part of the public
integration surface. Binoban's public credential model is apiKey +
sourceIdentifier only.
Configuration options
Set these inside the configuration closure:
| Option | Default | Purpose |
|---|---|---|
application | — | UIApplication.shared reference. |
apiHost | none | API endpoint. Required — no default on either platform; a blank host disables the SDK (no-op). |
collectDeviceId | true | Collect a device identifier. |
trackApplicationLifecycleEvents | true | Auto-track app lifecycle. |
flushAt | 20 | Send after this many queued events. |
flushInterval | 30 | …or after this many seconds. |
Track and identify
Properties and traits are [String: Any] dictionaries:
// Record an action
binoban.track(name: "purchase", properties: ["item": "shoes", "price": "49.99"])
// Associate the current person with your user ID + traits
binoban.identify(userId: "user_123", traits: ["email": "test@example.com"])
Flush and reset
binoban.flush() // send queued events immediately
binoban.reset() // clear identity and start a new anonymousId — call on logout
screen, group, alias are not publicThe underlying KMP core marks screen(), group(), and alias() as internal —
they are not part of the public iOS API in this release. The reference iOS app
only exercises track, identify, flush, and reset.
Read the current identity
binoban.anonymousId() // String — always present
userId() and deviceId() exist on the underlying SDK; the reference app
surfaces only anonymousId(). See Identity strategy
for how the identifiers relate across platforms.
Runtime controls
Binoban.companion.debugLogsEnabled = true // verbose console logging
The SDK can also be paused/resumed and its flush thresholds adjusted at runtime
(flushAt, flushInterval) — useful in development and for honoring user
preferences.
Push notifications
Push runs on Firebase Cloud Messaging — Binoban has no direct APNs integration,
so delivery goes Binoban → FCM → APNs. The SDK never registers its own
UNUserNotificationCenterDelegate: your app owns the delegate and forwards to
the SDK. For the step-by-step integration see
App push on iOS.
Entry points
Call these on BinobanNotifications.shared (SDK 1.1.0 and later). They are
Kotlin top-level functions underneath, so Swift also exposes them as static members
of the generated NotificationForwarding_iosKt; that spelling still works but is an
implementation detail. They are not methods on your Binoban instance.
Call on BinobanNotifications.shared | Forward it from | Effect |
|---|---|---|
initializeNotifications(configuration:) | App launch | Configures the notification layer; optionally requests permission. Takes a NotificationPlatformConfigurationIos — spelled flat, not nested. |
onNewToken(token:) | MessagingDelegate.messaging(_:didReceiveRegistrationToken:) | Registers the FCM token. |
onApplicationDidReceiveRemoteNotification(userInfo:) | application(_:didReceiveRemoteNotification:fetchCompletionHandler:) | Displays a Binoban data push. Does not itself report delivered — see the next row. |
onWillPresentForwarded(userInfo:) | userNotificationCenter(_:willPresent:withCompletionHandler:) | Reports delivered for a foreground notification. |
onDidReceiveForwarded(userInfo:actionId:dismissed:) | userNotificationCenter(_:didReceive:withCompletionHandler:) | Reports clicked, or closed when dismissed is true. |
Notification.shared.refreshToken(token:) and binoban.setDeviceToken(token:)
also register a token; onNewToken(token:) is the Firebase-facing name for the
same path. All emit bb_notification_registered — see
Push events.
Pass the FCM registration token from MessagingDelegate. The raw Data from
didRegisterForRemoteNotificationsWithDeviceToken is an APNs device token and
cannot be used to reach the device through Binoban. Your APNs auth key goes to
Firebase — see Firebase setup.
Configuration
NotificationPlatformConfigurationIos (Kotlin nests this type; Swift sees it flat):
| Field | Default | Purpose |
|---|---|---|
askNotificationPermissionOnStart | true | Request notification permission as soon as the SDK initializes. Set false to ask at your own moment. |
notificationSoundName | nil | Name of a sound file in your target's bundle resources; nil uses the system default. |
Interaction handling
NotificationInteraction carries notificationUuid, type (DELIVERED,
CLICKED, CLOSED, FAILED, OPENED), actionId, uri, customData, and
reason. Subclass DefaultNotificationInteractionHandler, call super to keep
the SDK's tracking, and install it with
NotificationInteractionManager.shared.setHandler(handler:).
| Call | Purpose |
|---|---|
NotificationInteractionManager.shared.setHandler(handler:) | Install your handler. |
NotificationInteractionManager.shared.resetToDefault() | Restore the default handler. |
NotificationInteractionManager.shared.drainPendingInteractions() | Consume interactions buffered before your handler was installed. Delivery-only — already tracked, so do not re-track them. |
drainPendingInteractions() covers a cold start from a notification tap, where the
interaction can dispatch before your setHandler(handler:) call has run. Install
the handler as early as you can, and drain once afterwards to catch anything that
fired first.
Behaviour and limits
- The SDK does not open URLs on iOS. iOS delivers the tap to your app; read
interaction.uriand route it. On Android the SDK does open it — this is the one deliberate behavioural difference between the platforms. - Per-button targets are carried in
userInfoand resolved byactionId, so a button tap reports that button's target rather than the main one. - Action buttons are capped at 3.
- Data-only delivery requires the Background Modes → Remote notifications capability. Without it iOS will not wake the app to display a Binoban message.
- Delegates and APNs registration are yours. The SDK sets neither
UNUserNotificationCenter.current().delegatenorMessaging.messaging().delegate, and never callsregisterForRemoteNotifications(). Miss any of the three and the integration fails silently — no token, or nodelivered/clicked. See App push on iOS. - Notification categories are merged, not replaced, so registering a notification with buttons never removes an earlier one's buttons.
Next steps
- Example Apps — binoban-example-ios is a runnable integration of this surface.
- Android SDK — the matching Android setup.
- Native SDK overview — shared concepts and the full method surface.
- Identity strategy · Go-live checklist