Appearance
Push & Notifications
About 1332 wordsAbout 4 min
Swift SDK - Feeds API
Table of Contents
- Push Configuration - APN
- Push Configuration - Firebase
- Push Configuration - Multi Bundle
- AppDelegate Setup
- Register Device
- Remove Device
- List Devices
- Reading Notification Feed
- Notification Status
- Mark Notifications as Read
- Mark Notifications as Seen
- Follow with Push Preference
- Creating Notification Activities
- Deleting Notification Activities
- Skip Push on Activity
Push Configuration - APN
Configure push notifications using Apple Push Notification service (APN). Create a PushNotificationsConfig with APN provider info and pass it to the FeedsConfig when initializing the client.
Example
import StreamCore
import StreamFeeds
let notificationsConfig = PushNotificationsConfig(
pushProviderInfo: PushProviderInfo(
name: "my-apn-provider",
pushProvider: .apn
)
)
let feedsConfig = FeedsConfig(
pushNotificationsConfig: notificationsConfig
)
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "john"),
token: "<user_token>",
feedsConfig: feedsConfig
)
try await client.connect()Push Configuration - Firebase
Configure push notifications using Firebase Cloud Messaging (FCM). Create a PushNotificationsConfig with Firebase provider info and pass it to the FeedsConfig.
Example
import StreamCore
import StreamFeeds
let notificationsConfig = PushNotificationsConfig(
pushProviderInfo: PushProviderInfo(
name: "my-firebase-provider",
pushProvider: .firebase
)
)
let feedsConfig = FeedsConfig(
pushNotificationsConfig: notificationsConfig
)
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "john"),
token: "<user_token>",
feedsConfig: feedsConfig
)
try await client.connect()Push Configuration - Multi Bundle
Configure push notifications for multiple app bundles. This is useful when you have separate bundle identifiers for development and production, or for app extensions.
Example
import StreamCore
import StreamFeeds
// Use a different provider based on the current environment
#if DEBUG
let providerName = "my-apn-provider-dev"
#else
let providerName = "my-apn-provider-prod"
#endif
let notificationsConfig = PushNotificationsConfig(
pushProviderInfo: PushProviderInfo(
name: providerName,
pushProvider: .apn
)
)
let feedsConfig = FeedsConfig(
pushNotificationsConfig: notificationsConfig
)
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "john"),
token: "<user_token>",
feedsConfig: feedsConfig
)
try await client.connect()AppDelegate Setup
Set up your AppDelegate to handle push notification registration and forward the device token to the Stream SDK.
Example
import UIKit
import StreamCore
import StreamFeeds
class AppDelegate: UIResponder, UIApplicationDelegate {
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "john"),
token: "<user_token>"
)
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
UNUserNotificationCenter.current().requestAuthorization(
options: [.alert, .badge, .sound]
) { granted, error in
if granted {
DispatchQueue.main.async {
application.registerForRemoteNotifications()
}
}
}
return true
}
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
let pushToken = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
Task {
try await client.connect()
try await client.createDevice(id: pushToken)
}
}
func application(
_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error
) {
print("Failed to register for push notifications: \(error)")
}
}Register Device
Register a device for push notifications. Call createDevice(id:) with the push token received from APNs to enable the device to receive push notifications.
Example
import StreamCore
import StreamFeeds
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "john"),
token: "<user_token>"
)
try await client.connect()
// Register the device with the push token
let pushToken = "<device_push_token>"
try await client.createDevice(id: pushToken)
print("Device registered for push notifications")Remove Device
Remove a registered device to stop receiving push notifications. Call deleteDevice(deviceId:) with the previously registered push token.
Example
import StreamCore
import StreamFeeds
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "john"),
token: "<user_token>"
)
try await client.connect()
// Remove the device using the saved push token
let savedToken = "<device_push_token>"
try await client.deleteDevice(deviceId: savedToken)
print("Device removed from push notifications")List Devices
List all registered devices for the current user. Use this to manage device registrations and clean up stale tokens.
Example
import StreamCore
import StreamFeeds
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "john"),
token: "<user_token>"
)
try await client.connect()
let response = try await client.listDevices()
for device in response.devices {
print("Device ID: \(device.id)")
print("Push provider: \(device.pushProvider)")
print("Created at: \(device.createdAt)")
}Reading Notification Feed
Read activities from a notification feed. Notification feeds return aggregated activities grouped by type and verb.
Example
import StreamCore
import StreamFeeds
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "jane"),
token: "<user_token>"
)
try await client.connect()
let feed = client.feed(for: FeedId(group: "notification", id: "jane"))
try await feed.getOrCreate()
// Access the aggregated activities from state
let activities = feed.state.activities
for activity in activities {
print("Activity type: \(activity.type)")
print("Actor: \(activity.actor)")
}Notification Status
Observe the notification status for a notification feed. The notificationStatus property provides unread count, unseen count, and timestamps for when notifications were last read or seen.
Example
import SwiftUI
import StreamCore
import StreamFeeds
struct NotificationBadgeView: View {
@ObservedObject var feedState: FeedState
var body: some View {
if let status = feedState.notificationStatus {
VStack {
HStack {
Text("Unread:")
Text("\(status.unread)")
.foregroundColor(.red)
}
HStack {
Text("Unseen:")
Text("\(status.unseen)")
.foregroundColor(.orange)
}
if let lastReadAt = status.lastReadAt {
Text("Last read: \(lastReadAt.formatted())")
.font(.caption)
}
if let lastSeenAt = status.lastSeenAt {
Text("Last seen: \(lastSeenAt.formatted())")
.font(.caption)
}
}
}
}
}
// Setup
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "jane"),
token: "<user_token>"
)
try await client.connect()
let feed = client.feed(for: FeedId(group: "notification", id: "jane"))
try await feed.getOrCreate()
// feed.state.notificationStatus is now observableMark Notifications as Read
Mark all or specific notifications as read. This resets the unread counter and updates the lastReadAt timestamp on the notification status.
Example
import StreamCore
import StreamFeeds
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "jane"),
token: "<user_token>"
)
try await client.connect()
let feed = client.feed(for: FeedId(group: "notification", id: "jane"))
try await feed.getOrCreate()
// Mark all notifications as read
try await feed.markActivity(request: .init(markAllRead: true))
// Or mark specific activities as read
try await feed.markActivity(request: .init(
markRead: ["<activity_id_1>", "<activity_id_2>"]
))Mark Notifications as Seen
Mark all or specific notifications as seen. This resets the unseen counter and updates the lastSeenAt timestamp on the notification status.
Example
import StreamCore
import StreamFeeds
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "jane"),
token: "<user_token>"
)
try await client.connect()
let feed = client.feed(for: FeedId(group: "notification", id: "jane"))
try await feed.getOrCreate()
// Mark all notifications as seen
try await feed.markActivity(request: .init(markAllSeen: true))
// Or mark specific activities as seen
try await feed.markActivity(request: .init(
markSeen: ["<activity_id_1>", "<activity_id_2>"]
))Follow with Push Preference
Follow a feed with a specific push notification preference. Set the push preference to .all to receive pushes for all activities, or .none to follow silently.
Example
import StreamCore
import StreamFeeds
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "jane"),
token: "<user_token>"
)
try await client.connect()
let feed = client.feed(for: FeedId(group: "notification", id: "jane"))
// Follow with push notifications enabled for all activities
try await feed.follow(
FeedId(group: "user", id: "john"),
pushPreference: .all
)
// Follow silently without push notifications
try await feed.follow(
FeedId(group: "user", id: "bob"),
pushPreference: .none
)Creating Notification Activities
Create activities that trigger notifications. Add activities to a feed that is followed by notification feeds to generate notification entries.
Example
import StreamCore
import StreamFeeds
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "john"),
token: "<user_token>"
)
try await client.connect()
// Add an activity that will appear in followers' notification feeds
let response = try await client.addActivity(
request: .init(
feeds: ["user:john"],
type: "post",
attachments: [],
text: "Hello from John!"
)
)
print("Activity created: \(response.id)")
// This activity will show up in notification feeds
// of users following "user:john"Deleting Notification Activities
Delete activities from notification feeds. When you delete an activity, it is removed from all feeds that contain it, including notification feeds.
Example
import StreamCore
import StreamFeeds
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "john"),
token: "<user_token>"
)
try await client.connect()
// Delete an activity by ID
try await client.deleteActivities(
request: .init(ids: ["<activity_id>"])
)
print("Activity deleted from all feeds including notification feeds")Skip Push on Activity
Add an activity while skipping push notification delivery. This is useful for bulk operations or low-priority updates that should not trigger a push notification.
Example
import StreamCore
import StreamFeeds
let client = FeedsClient(
apiKey: APIKey("<your_api_key>"),
user: User(id: "john"),
token: "<user_token>"
)
try await client.connect()
// Add an activity with push notifications disabled
let response = try await client.addActivity(
request: .init(
feeds: ["user:john"],
type: "status_update",
attachments: [],
text: "Minor update",
skipPush: true
)
)
print("Activity created without triggering push: \(response.id)")