I am building custom long-look notifications in an Apple Watch app, but for some reason the title
defined in the notification's UNMutableNotificationContent
is not showing on the long-look notification, and the custom sashColor
I’m defining is not used.
In the “Transition to the Long-Look Interface” section of Presenting Notifications on Apple Watch, there is a screenshot that shows what I would expect to see: a title for the notification in the sash, and a custom sash color.
I built an example app (code below) to isolate the issue.
Here is a screenshot of the notification in my app:
I expect to see the title
(“Take Action!”) where the line is, and the sashColor
as the background color for the circled region, based on my code.
The short-look of the notification does show the title
briefly before it transitions to the long-look (it was hard to get a good screenshot, but here is one as it was animating into the long-look):
Showing or hiding the notification title
is not mentioned anywhere that I can find in the documentation, so I expect that to show up automatically since it’s part of the notification.
For the sashColor
override, I referred to Customizing Your Long-Look Interface.
Is there something else specific I need to do to show the title
on my customized long-look notification, and get sashColor
to work?
Example App
To recreate the issue, create a watchOS app with companion iOS app in Xcode. I called it CustomWatchNotifications.
I updated the main iOS app file to this, with a simple class to request notification permission and send a test notification, which gets passed into the view:
import SwiftUI
import UserNotifications
@main
struct CustomWatchNotificationsApp: App
{
let notifications = NotificationController()
var body: some Scene
{
WindowGroup
{
ContentView(notifications: notifications)
}
}
}
class NotificationController
{
func requestPermissions()
{
Task {
try await UNUserNotificationCenter.current()
.requestAuthorization(
options: [.alert, .sound])
}
}
func scheduleNotification()
{
let content = UNMutableNotificationContent()
content.title = "Take Action!"
content.categoryIdentifier = "takeActionCategory"
content.sound = .default
// Schedule a new notification 5 seconds from now,
// so there is enough time to lock the phone screen
// to deliver notification to Apple Watch.
let trigger = UNTimeIntervalNotificationTrigger(
timeInterval: 5,
repeats: false)
let request = UNNotificationRequest(
identifier: "takeAction",
content: content,
trigger: trigger)
UNUserNotificationCenter.current()
.add(request)
}
}
This is the ContentView for the iOS app, which just includes the two buttons:
import SwiftUI
struct ContentView: View
{
let notifications: NotificationController
var body: some View
{
NavigationView
{
Form
{
// Request notification permissions
Button
{
notifications.requestPermissions()
} label: {
Text("Request Notification Permissions")
}
// Schedule notification
Button
{
notifications.scheduleNotification()
} label: {
Text("Schedule Notification")
}
}
}
}
}
On the watchOS side, I updated the main app file to include a custom View
for the notification, inside a WKUserNotificationHostingController
for this specific notification category:
import SwiftUI
import UserNotifications
@main
struct CustomWatchNotifications_Watch_AppApp: App
{
var body: some Scene
{
WindowGroup
{
ContentView()
}
WKNotificationScene(
controller: TakeActionNotificationController.self,
category: "takeActionCategory"
)
}
}
struct TakeActionNotificationView: View
{
var body: some View
{
Text("This is a test.")
}
}
class TakeActionNotificationController:
WKUserNotificationHostingController<TakeActionNotificationView>
{
// This does not seem to have an effect on sashColor.
override class var sashColor: Color?
{
return .red
}
override var body: TakeActionNotificationView
{
return TakeActionNotificationView()
}
// This has to be here for custom notification to show up.
override func didReceive(_ notification: UNNotification)
{}
}
When you build and run on real devices, make sure the watchOS app is installed before schedule the test notification. Once you schedule the test notification, lock the iPhone screen immediately so the notification gets delivered to Apple Watch.