activateSceneSession (or requestSceneSessionActivation) always creates new Scene

I'm trying to implement a Help Window from Help Menu in macOS (Mac Catalyst). I have SceneConfiguration in Info.plist and multi-window enabled. Tapping Help menu opens a new Help Window on macOS. I thought it was working great!

Unfortunately, tapping Help menu again opens a new Help Window. I only want one Help window to be shown.

I expected UIApplication.shared.activateSceneSession(for: request) to use an existing UIScene if one was already present. In my experience I always get a new Scene and thus a new Window. What am I missing?

AppDelegate.swift

func application(_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// It's important that each UISceneConfiguration have a unique configuration name.
var configurationName: String!
switch options.userActivities.first?.activityType {
case UserActivity.HelpMenuActivityType:
configurationName = SceneConfiguration.helpWindowConfiguration
default:
configurationName = SceneConfiguration.defaultConfiguration
}
return UISceneConfiguration(name: configurationName, sessionRole: connectingSceneSession.role)
}
override func buildMenu(with builder: UIMenuBuilder) {
super.buildMenu(with: builder)
...
builder.remove(menu: .help)
builder.insertSibling(helpMenu(), afterMenu: .window)
}
func helpMenu() -> UIMenu {
let children: [UIAction] = [
UIAction(...
) { [weak self] action in
self?.helpMenuTappedHandler(action)
}
]
....
}
func helpMenuTappedHandler(_ action: UIAction) {
let userActivity: NSUserActivity = ...
userActivity.targetContentIdentifier = ...
let options: UIScene.ActivationRequestOptions = .init()
options.requestingScene = ...
let request: UISceneSessionActivationRequest = .init(role: .windowApplication, userActivity: userActivity, options: options)
UIApplication.shared.activateSceneSession(for: request, errorHandler: handleHelpError)
}
Answered by dferrero in 817885022

I modified the above func to add code to detect if the Help Session already exists:

func helpMenuTappedHandler(_ action: UIAction) {
// check if Help Window already exists before requesting one
if let helpScene = UIApplication.shared.connectedScenes.first(where: { $0.session.configuration.name == SceneConfiguration.helpWindowConfiguration }),
let helpWindowScene = helpScene as? UIWindowScene
{
let window = helpWindowScene.keyWindow ?? helpWindowScene.windows.first
window?.makeKeyAndVisible()
return
}
....
}

This does seem to work, except that if the Help Window is behind the Main Window, the call window?.makeKeyAndVisible() does not bring that Window in front of the other Main window as expected...

I'm starting to wonder if I should just create the Help window as another window inside the Main UIScene instead of in its own Scene. Thoughts?

Accepted Answer

I modified the above func to add code to detect if the Help Session already exists:

func helpMenuTappedHandler(_ action: UIAction) {
// check if Help Window already exists before requesting one
if let helpScene = UIApplication.shared.connectedScenes.first(where: { $0.session.configuration.name == SceneConfiguration.helpWindowConfiguration }),
let helpWindowScene = helpScene as? UIWindowScene
{
let window = helpWindowScene.keyWindow ?? helpWindowScene.windows.first
window?.makeKeyAndVisible()
return
}
....
}

This does seem to work, except that if the Help Window is behind the Main Window, the call window?.makeKeyAndVisible() does not bring that Window in front of the other Main window as expected...

I'm starting to wonder if I should just create the Help window as another window inside the Main UIScene instead of in its own Scene. Thoughts?

Not directly related but it's close :D

I see my help Help Window shows up under the Window menu, but it has the same name as the Main Window (the app name). How can I edit the name of the window used in the Window Menu?

activateSceneSession (or requestSceneSessionActivation) always creates new Scene
 
 
Q