Documentation Index
Fetch the complete documentation index at: https://docs.suprsend.com/llms.txt
Use this file to discover all available pages before exploring further.
The SDK provides the data layer only — no built-in UI. Bind to its data and
events and render your own.
Prerequisites
Integration of iOS SDK.
Initialize Feed Client
// create feed instance
let feed: Feed = SuprSend.shared.feeds.initialize(options: IFeedOptions?)
Options
| Parameter | Type | Description |
|---|
tenantId | String? | Tenant to read from. Defaults to “default” tenant |
pageSize | UInt? | Notifications per page. Defaults to 20 |
stores | [IStore]? | Filtered views inside feed (see Stores) |
host | FeedHost? | Override API/socket host via FeedHost(socketHost:apiHost:) |
If you are passing tenant_id in feed, make sure to pass the scope key while creating userToken passed during identifying user, else a 403 error will be thrown due to scope mismatch.
Feed Client
Get Feed Data Store
Returns the current notification store — the list of notifications plus metadata
like page info and badge counts. You can call this anytime to get updated store data.
let feedData: IFeedData = feed.data
feedData.notifications // [IRemoteNotification] — list of notifications
feedData.store // IStore — active store
feedData.pageInfo // IPageInfo — .total, .hasMore, .pageSize
feedData.meta // "badge" — latest notifs count since last opened, per-store unread counts
feedData.apiStatus // .initial / .loading / .success / .error / .fetchingMore
Initialize Socket for Realtime Updates
feed.initializeSocketConnection()
Keep exactly one active socket per feed. Multiple live sockets cause
duplicated events, doubled badge increments, and inflated counts. Avoid:
- Recreating the feed without teardown.
removeAll() (or
removeInstance(_:)) the old feed before calling feeds.initialize(...) again.
- Owning the feed somewhere short-lived. A feed re-created with its view
opens a socket each time; own it in a single, stable place and reuse it.
- Skipping cleanup on dismiss/logout. An unclosed socket keeps running in
the background — tear down in
deinit or on logout.
Fetch Notification Data
Gets the first page of notifications from the SuprSend server and sets it in the
notification store (it also fetches badge counts on the first call).
Fetch More Notifications
Gets the next page and appends it to the notification store. Call this only when
pageInfo.hasMore == true.
await feed.fetchNextPage()
Listening for Updates
Subscribe to feed.emitter to keep your UI in sync. It fires two events:
.storeUpdate — the notification store changed (new notification, state
update, pagination, mutations, socket events). Listen to this and update your local state so that the UI is refreshed.
.newNotification — use this listener to show a toast notification when a new notification is received.
public enum InboxEmitterEvents {
case storeUpdate(IFeedData) // store changed — re-render UI
case newNotification(IRemoteNotification) // new notification arrived
}
feed.emitter
.receive(on: RunLoop.main)
.sink { [weak self] event in
switch event {
case .storeUpdate(let data): self?.render(data)
case .newNotification(let notification): self?.showToast(for: notification)
}
}
.store(in: &cancellables)
Removing Feed
Removes the feed client and aborts its socket connection.
SuprSend.shared.feeds.removeInstance(feed) // one instance
SuprSend.shared.feeds.removeAll() // all active inbox instances
deinit { SuprSend.shared.feeds.removeAll() }
Reconnecting: In background mode iOS suspends app activity. When the app comes from background to foreground, remove existing feed instances and reconnect the socket and emitters, then refetch data.
Action Methods
// Change active store (when using multi-tab stores)
await feed.changeActiveStore(storeId: String)
// Reset the bell-icon badge count
await feed.resetBadgeCount()
// Mark notifications as seen
await feed.markBulkAsSeen(notificationIds: [String])
// Mark all notifications as read
await feed.markAllAsRead()
// Mark notification as read
await feed.markAsRead(notificationId: String)
// Mark notification as unread
await feed.markAsUnread(notificationId: String)
// Mark notification as interacted
await feed.markAsInteracted(notificationId: String)
// Archive notification
await feed.markAsArchived(notificationId: String)
Read more about seen, read, and interacted.
Response returned by the action methods (markAsRead, changeActiveStore, etc.):
public class APIResponse: NSObject, Response {
public let status: ResponseStatus // .success or .error
public let statusCode: StatusCode? // HTTP status code (Int)
public let body: ResponseBody? // [String: String]
public let error: ResponseError? // type and message, when status == .error
}
Notification Structure
public class IRemoteNotification: NSObject, Codable {
public let n_id: String // unique notif id
public let message: IRemoteNotificationMessage // actual notif message content
public let created_on: TimeInterval // notif creation timestamp
public let seen_on: TimeInterval? // notif seen timestamp
public let read_on: TimeInterval? // notif read timestamp
public let interacted_on: TimeInterval? // notif interacted timestamp
public let archived: Bool? // if notif is archived
public let is_pinned: Bool // if notif is pinned
public let expiry: TimeInterval? // milliseconds since epoch to expiry
public let is_expiry_visible: Bool // show timer to user till expiry
}
public class IRemoteNotificationMessage: NSObject, Codable {
public let header: String? // title
public let text: String // body
public let subtext: ISubTextObject? // subtext
public let avatar: IAvatarObject? // avatar img and click url
public let url: String? // action url
public let actions: [IActionObject]? // action buttons
public let extra_data: String? // arbitrary JSON string
}
Notification States
- Seen:
seen_on flag is used to check if the notification has been seen in SuprSend analytics. If it’s null, the notification has not been seen yet — call markBulkAsSeen when the notification enters the viewport and seen_on is null.
- Read:
read_on flag is used to check if the notification has been read. This doesn’t update SuprSend analytics and is only for visual purposes. If read_on is null, show a dot on the notification indicating it’s unread. Call markAsRead when read_on is null, or markAsUnread when read_on has a timestamp. Marking as read will also set seen_on if not already set.
- Interacted:
interacted_on flag is used to set the notification as clicked in SuprSend analytics. If interacted_on is null and the user clicks on the notification, call markAsInteracted. This will also set read_on and seen_on if not already set.