Reputation: 213
The NSWindowRestoration
protocol has two methods, it is actually one but you must choose either a synchronous method using a completion handler or an asynchronous method.
Synchronous
@MainActor static func restoreWindow(withIdentifier identifier: NSUserInterfaceItemIdentifier, state: NSCoder, completionHandler: @escaping (NSWindow?, Error?) -> Void)
Asynchronous
@MainActor static func restoreWindow(withIdentifier identifier: NSUserInterfaceItemIdentifier, state: NSCoder) async throws -> NSWindow
I wanted to use the asynchronous method because I have adopted Swift concurrency in the rest of my app and it is a modern API. I also want to be consistent and avoid completion handlers or synchronous methods. I've been having many problems getting it to work correctly, especially the timing.
What I found out is that this method is called after applicationDidFinishLaunching(_:)
whereas the synchronous method is called before applicationDidFinishLaunching(_:)
. So this explains why I was getting duplicated windows.
What I do at the end of applicationDidFinishLaunching(_:)
is check if my windows array is empty and if it is then make a window.
Is this a normal expected behaviour?
I noticed in Xcode Version 15.2 (15C500b), the compiler produces a warning about the asynchronous method:
Non-sendable type 'NSCoder' in parameter of the protocol requirement satisfied by main actor-isolated static method 'restoreWindow(withIdentifier:state:)' cannot cross actor boundary
I thought maybe this explains why the asynchronous method is called late? I tried making it compliant by doing this:
extension NSCoder: Sendable {}
Then the warning said:
Conformance to 'Sendable' must occur in the same source file as class 'NSCoder'; use '@unchecked Sendable' for retroactive conformance
So I did this:
extension NSCoder: @unchecked Sendable {}
And that didn't help.
Is this something that Apple needs to address (should I file a feedback?) or is it working as expected?
Why would you want restoreWindow(withIdentifier:state:)
to be called late, especially after applicationDidFinishLaunching(_:)
, where you are supposed to setup a window? How are you supposed to know if you are to create a new window or let the system restore windows?
Upvotes: 0
Views: 50