Title and sashColor not showing up on customized long-look notification with WKUserNotificationHostingController

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.

Title and sashColor not showing up on customized long-look notification with WKUserNotificationHostingController
 
 
Q