Search code examples
swiftmacoscocoaappkit

How do you detect if an AppKit app has been launched with a document?


I am building an NSDocument-based app and I want to be able to detect if my app is being launched because a user is opening a document, or because the user simply clicked on the dock icon. I tried inspecting the Notification that comes with the applicationDidFinishLaunching method, but it seems not to contain a reference to the document. I also tried querying NSDocumentController.shared.documents from this method, but the array is still empty at this point. I have noticed that by the time applicationDidBecomeActive is called, the document has been instantiated, but of course, this method is also called on occasions not related to app launch, so that's not ideal. My best guess at the moment is to do the following, but it feels like a hack.

class AppDelegate: NSObject, NSApplicationDelegate {
    private var hasBecomeActiveOnce = false

    func applicationDidBecomeActive(_ notification: Notification) {
        if !hasBecomeActiveOnce {
            hasBecomeActiveOnce = true
            if !NSDocumentController.shared.documents.isEmpty {
                print("App launched from document!")
            }
        }
    }
}

There must be a better (more idiomatic) way. What am I missing?


Solution

  • Okay, I think I've found the answer to my specific problem, which might not be fully communicated by the question above. Basically, what I want to do is show an open panel when the app is launched, or when the dock icon is clicked and there isn't a document already open. It seems like in both of these cases, the system calls applicationOpenUntitledFile. Answering my own question in case others are running into this same issue.

    class AppDelegate: NSObject, NSApplicationDelegate {
        func applicationOpenUntitledFile(_ sender: NSApplication) -> Bool {
            print("app launched (or dock clicked) without a document!")
            return true
        }
    }