Show In-App Notifications
It is often important to display an alert to the user indicating a success or an error. For this, we include a convenient way to call in-app notifications that are displayed at the top of the screen and in-front of every view.
Basic Usage
To show an in-app notification, all you have to do is call the global showInAppNotification()
function:
import SharedKit
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Button("Show Success Notification") {
showInAppNotification(
.success,
content: .init(
title: "Success",
message: "Additional Success Text"
)
)
}
Button("Show Error Notification") {
showInAppNotification(
.error,
content: .init(
title: "Error",
message: "Additional Error Text"
)
)
}
}
}
}
This will display a compact in-app notification at the top of the screen, with a title and a message. The notification will automatically disappear after a few seconds.
Because of the way we are able to show in-app notifications infront of all other views, in-app notifications will not show up in SwiftUI previews, but only on a real device or simulator. You can learn more about how we implement them in the deep dive below.
The showInAppNotification()
functions
SwiftyLaunch includes two different, globally accessible showInAppNotification()
functions out of the box,
one that includes a predefined style that you can easily pick with an enum, and a customizable version,
where you can set the style of the in-app notification when calling the function.
With predefined styles
The predefined version is what you're going to be using in most cases. It includes five different pre-defined notification types: .error
, .warning
, .info
, .success
, and .failure
.
Function Definition
public func showInAppNotification(
_ type: InAppNotificationType,
content: InAppNotificationContent,
size: InAppNotificationStyle.NotificationSize? = nil,
onTapAction: (() -> Void)? = nil
) { }
type
: The type of the in-app notification. You can choose between.error
,.warning
,.info
,.success
, and.failure
.content
: The content of the in-app notification. This includes the title and the message.size
(Optional): The size of the in-app notification. You can choose between.normal
and.compact
. The default is.compact
.onTapAction
(Optional): A closure that will be executed when the user taps on the in-app notification.
Usage Example
import SharedKit
func enableBetaFeature() {
// ... enable the beta feature
showInAppNotification(
.warning,
content: .init(
title: "This Feature is in Beta",
message: "Please report any issues you encounter"
)
)
}
With a customizable style
If you want to include a custom SFSymbol (opens in a new tab) or set a custom color, you can use a custom style. This is useful if you want to show a notification that doesn't fit into the predefined styles.
Function Definition
public func showInAppNotification(
content: InAppNotificationContent,
style: InAppNotificationStyle,
onTapAction: (() -> Void)? = nil
) { }
content
: The content of the in-app notification. This includes the title and the message.style
: Style of the in-app notification, seeInAppNotificationStyle
definition below for more information.onTapAction
(Optional): A closure that will be executed when the user taps on the in-app notification.
InAppNotificationStyle
Definition
public struct InAppNotificationStyle: Equatable {
public enum NotificationSize {
case normal, compact
}
let sfSymbol: String
let symbolColor: Color
let size: NotificationSize
let hapticsOnAppear: UINotificationFeedbackGenerator.FeedbackType
public init(
sfSymbol: String,
symbolColor: Color,
size: NotificationSize,
hapticsOnAppear: UINotificationFeedbackGenerator.FeedbackType = .warning
) {
self.sfSymbol = sfSymbol
self.symbolColor = symbolColor
self.size = size
self.hapticsOnAppear = hapticsOnAppear
}
}
sfSymbol
: The name of the SFSymbol to display in the in-app notification.symbolColor
: The color of the SFSymbol.size
: The size of the in-app notification. You can choose between.normal
and.compact
.hapticsOnAppear
(Optional): The haptic feedback to generate when the in-app notification appears. Defaults to.warning
. Read more in the Haptics documentation.
Usage Example
import SharedKit
func greetingMessage() {
showInAppNotification(
content: .init(
title: "Hello World!",
message: "This is a regular notification size."
),
style: .init(
sfSymbol: "bell.badge.fill",
symbolColor: .red,
size: .normal
)
)
}
Customizing Appearance Settings
You can always customize the appearance of the in-app notifications by changing the InAppNotificationView
directly.
Additionally, by default, up to three in-app notifications can be shown on the screen at the same time, and their
appearance duration is set to 6 seconds. you can change these parameters in Constants.swift
:
public struct Constants {
/// Constants regarding In-App-Notifications
public struct InAppNotifications {
/// How many notifications can be shown at once (if max is reached, the oldest notification will be removed)
/// Note: duplicate notifications will not show up stacked
public static let maxShownAtOnce: Int = 3
/// The duration that the in-app notification appears on screen (in seconds)
public static let showingDuration: Int = 6
}
}
Read more about constants in App-Wide Constants.
Route Push Notifcations to In-App Notifications
When you send a push notification, you can optionally make them show up as in-app notification. Refer to Routing to In-App Notifications in NotifKit for more information.
Deep Dive
When you call the showInAppNotification()
function, it will send a notification to the NotificationCenter (opens in a new tab)
with the provided data and style. Then the ShowInAppNotificationsWhenCalledModifier
view modifier that is attached to the hierarchy root listens to
these notifications and displays the in-app notification on the screen. The view modifier also manages the appearance and disappearance of the in-app notifications.
App-wide In-App Notifications Overlay
To show in-app notifications above every single view in the app, we couldn't simply put an overlay on top of the root view, because then it wouldn't work well with sheets and similar "overlaying" elements.
For this, we have created an additional transparent window that is attached to the UIScene in the app in App.swift
. We have also created
a blog post going over the details of how we implemented this: App-Wide Overlays in SwiftUI (opens in a new tab).