An in-app notification center list you can use to notify your users. Allows you to build high quality, flexible notification feeds very quickly.
Requirement | Reason |
---|---|
Courier Inbox Provider
|
Needed to link your Courier Inbox to the SDK |
Authentication
|
Needed to view inbox messages that belong to a user. |
CourierInbox
works with all native iOS UI frameworks.
UI Framework | Support |
---|---|
UIKit |
✅ |
XIB |
|
SwiftUI |
✅ |
The default CourierInbox
styles.
import Courier_iOS
// Create the view
let courierInbox = CourierInbox(
didClickInboxMessageAtIndex: { message, index in
message.isRead ? message.markAsUnread() : message.markAsRead()
print(index, message)
},
didClickInboxActionForMessageAtIndex: { action, message, index in
print(action, message, index)
},
didScrollInbox: { scrollView in
print(scrollView.contentOffset.y)
}
)
// Add the view to your UI
courierInbox.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(courierInbox)
// Constrain the view how you'd like
NSLayoutConstraint.activate([
courierInbox.topAnchor.constraint(equalTo: view.topAnchor),
courierInbox.bottomAnchor.constraint(equalTo: view.bottomAnchor),
courierInbox.leadingAnchor.constraint(equalTo: view.leadingAnchor),
courierInbox.trailingAnchor.constraint(equalTo: view.trailingAnchor),
])
The styles you can use to quickly customize the CourierInbox
.
import Courier_iOS
let textColor = UIColor(red: 42 / 255, green: 21 / 255, blue: 55 / 255, alpha: 100)
let primaryColor = UIColor(red: 136 / 255, green: 45 / 255, blue: 185 / 255, alpha: 100)
let secondaryColor = UIColor(red: 234 / 255, green: 104 / 255, blue: 102 / 255, alpha: 100)
// Theme object containing all the styles you want to apply
let inboxTheme = CourierInboxTheme(
brandId: "7S9R...3Q1M", // Optional. Theme colors will override this brand.
messageAnimationStyle: .fade,
unreadIndicatorStyle: CourierStyles.Inbox.UnreadIndicatorStyle(
indicator: .dot,
color: secondaryColor
),
titleStyle: CourierStyles.Inbox.TextStyle(
unread: CourierStyles.Font(
font: UIFont(name: "Avenir Black", size: 20)!,
color: textColor
),
read: CourierStyles.Font(
font: UIFont(name: "Avenir Black", size: 20)!,
color: textColor
)
),
timeStyle: CourierStyles.Inbox.TextStyle(
unread: CourierStyles.Font(
font: UIFont(name: "Avenir Medium", size: 18)!,
color: textColor
),
read: CourierStyles.Font(
font: UIFont(name: "Avenir Medium", size: 18)!,
color: textColor
)
),
bodyStyle: CourierStyles.Inbox.TextStyle(
unread: CourierStyles.Font(
font: UIFont(name: "Avenir Medium", size: 18)!,
color: textColor
),
read: CourierStyles.Font(
font: UIFont(name: "Avenir Medium", size: 18)!,
color: textColor
)
),
buttonStyle: CourierStyles.Inbox.ButtonStyle(
unread: CourierStyles.Button(
font: CourierStyles.Font(
font: UIFont(name: "Avenir Black", size: 16)!,
color: .white
),
backgroundColor: primaryColor,
cornerRadius: 100
),
read: CourierStyles.Button(
font: CourierStyles.Font(
font: UIFont(name: "Avenir Black", size: 16)!,
color: .white
),
backgroundColor: primaryColor,
cornerRadius: 100
)
),
cellStyle: CourierStyles.Cell(
separatorStyle: .singleLine,
separatorInsets: .zero
),
infoViewStyle: CourierStyles.Inbox.InfoViewStyle(
font: CourierStyles.Font(
font: UIFont(name: "Avenir Medium", size: 20)!,
color: textColor
),
button: CourierStyles.Button(
font: CourierStyles.Font(
font: UIFont(name: "Avenir Black", size: 16)!,
color: .white
),
backgroundColor: primaryColor,
cornerRadius: 100
)
)
)
// Pass the theme to the view
let courierInbox = CourierInbox(
lightTheme: inboxTheme,
darkTheme: inboxTheme,
didClickInboxMessageAtIndex: { message, index in
message.isRead ? message.markAsUnread() : message.markAsRead()
print(index, message)
},
didClickInboxActionForMessageAtIndex: { action, message, index in
print(action, message, index)
},
didScrollInbox: { scrollView in
print(scrollView.contentOffset.y)
}
)
view.addSubview(courierInbox)
...
If you are interested in using a Courier "Brand", here is where you can adjust that: Courier Studio
.
Supported Brand Styles | Support |
---|---|
Primary Color |
✅ |
Show/Hide Courier Footer |
✅ |
The raw data you can use to build whatever UI you'd like.
import UIKit
import Courier_iOS
class CustomInboxViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
private var inboxListener: CourierInboxListener? = nil
...
override func viewDidLoad() {
super.viewDidLoad()
...
// Allows you to listen to all inbox changes and build whatever you'd like
self.inboxListener = Courier.shared.addInboxListener(
onInitialLoad: {
...
},
onError: { error in
...
},
onMessagesChanged: { messages, unreadMessageCount, totalMessageCount, canPaginate in
...
self.tableView.reloadData()
}
)
}
...
private var messages: [InboxMessage] {
get {
return Courier.shared.inboxMessages ?? []
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let message = messages[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: YourCustomTableViewCell.id, for: indexPath) as! YourCustomTableViewCell
cell.message = message
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let message = messages[indexPath.row]
message.isRead ? message.markAsUnread() : message.markAsRead()
}
deinit {
self.inboxListener?.remove()
}
}
...
Link | Style |
---|---|
Default Example
|
Default
|
Styled Example
|
Styled
|
Custom Example
|
Custom
|
SwiftUI Example
|
Styled
|
import Courier_iOS
// Listen to all inbox events
// Only one "pipe" of data is created behind the scenes for network / performance reasons
let inboxListener = Courier.shared.addInboxListener(
onInitialLoad: {
// Called when the inbox starts up
},
onError: { error in
// Called if an error occurs
},
onMessagesChanged: { messages, unreadMessageCount, totalMessageCount, canPaginate in
// Called when messages update
}
)
// Stop the current listener
inboxListener.remove()
// Remove all listeners
// This will also remove the listener of the prebuilt UI
Courier.shared.removeAllInboxListeners()
// The amount of inbox messages to fetch at a time
// Will affect prebuilt UI
Courier.shared.inboxPaginationLimit = 123
// The available messages the inbox has
let inboxMessages = Courier.shared.inboxMessages
Task {
// Fetches the next page of messages
try await Courier.shared.fetchNextPageOfMessages()
// Reloads the inbox
// Commonly used with pull to refresh
try await Courier.shared.refreshInbox()
// Reads / Unreads a message
// Writes the update instantly and performs request in background
try await Courier.shared.readMessage(messageId: "1-321...")
try await Courier.shared.unreadMessage(messageId: "1-321...")
// Click a message
try await Courier.shared.clickMessage(messageId: "1-321...")
// Reads all the messages
// Writes the update instantly and performs request in background
try await Courier.shared.readAllInboxMessages()
}
// Mark message as read/unread
let message = InboxMessage(...)
// Calls Courier.shared.un/readMessage(messageId...) under the hood
// Has optional callbacks
message.markAsRead()
message.markAsUnread()