MacApp (using Swift) does not terminate launched sub-process if terminated

Viewed 661

I've a very simple MacOS Swift application which is used as a launcher to provide a dock icon. The application launches the main script. But if the application is terminated (e.g. by clicking on it and selecting "Close" in the context menu) the subprocess with the script continues to run.

How to change this behaviour to kill the child process if the application is killed. Using pgrep I checked and the script is executed in a subprocess:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        print("App started!\n");

        DispatchQueue.global(qos: .background).async {

            let process = Process()
            process.executableURL = URL(fileURLWithPath:"/usr/local/bin/node")
            process.arguments = ["./build/index.js"]
            process.currentDirectoryPath = "/Users/myaccount/basedir"
            process.terminationHandler = { (process) in
            print("didFinish")
            }
            do {
            try process.run()
            } catch {}

        }

    }

    func applicationWillTerminate(_ aNotification: Notification) {
        print("I'll never show up\n")
    }

}
1 Answers

Until now I found two possible solutions, also with the help of the comments for my question:

1.) "The proper way" - using the application quit callback

The Process object can be made global/instance scope to kill it in the applicationWillTerminate callback. But I encountered the problem, that this function is never called. With the help of this forum question I found that you need to set the following two options to "NO" in Info.plist:

XCode Info.plist

Then it works perfectly.

2.) Let the child process watch the parent

One can get the pid of the parent very easily (ProcessInfo().processIdentifier) give it as a parameter when launching the child and let the child watch the parent process id - when it is no longer alive, the child can kill itself. One can watch a process by running kill -0 PID which will raise an error if no process exists.

Related