如何在swift 2命令行工具中创建最小守护进程?

Mar*_*kov 6 macos xcode cocoa swift swift2

我想做什么

我想运行一个可以监听OSX系统事件的守护进程,就像NSWorkspaceWillLaunchApplicationNotificationcommand line toolxcode项目中一样?那可能吗?如果没有,为什么不,有没有任何工作或黑客?

一些代码示例

以下来自swift 2 cocoa application项目的示例代码设置了一个系统事件侦听器,WillLaunchApp每次启动OSX应用程序时都会调用该事件侦听器.(这很好用)

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(aNotification: NSNotification) {
        NSWorkspace.sharedWorkspace()
            .notificationCenter.addObserver(self,
                selector: "WillLaunchApp:",
                name: NSWorkspaceWillLaunchApplicationNotification, object: nil)
    }

    func WillLaunchApp(notification: NSNotification!) {
        print(notification)
    }
}
Run Code Online (Sandbox Code Playgroud)

相比之下,这个类似的swift 2 command line tool项目不会打电话 WillLaunchApp.

import Cocoa

class MyObserver: NSObject
{
    override init() {
        super.init()
        NSWorkspace.sharedWorkspace()
            .notificationCenter.addObserver(self,
                selector: "WillLaunchApp:",
                name: NSWorkspaceWillLaunchApplicationNotification, object: nil)
    }

    func WillLaunchApp(notification: NSNotification!) {
        // is never called
        print(notification)
    }
}

let observer = MyObserver()

while true {
    // simply to keep the command line tool alive - as a daemon process
    sleep(1)
}
Run Code Online (Sandbox Code Playgroud)

我猜我在这里缺少一些cocoa和/或xcode基础知识,但我无法弄清楚哪些.也许它与while-true循环有关,可能会阻塞事件.如果是这样,是否有正确的方法来运行守护程序进程?

Mar*_*kov 7

事实证明,使用while true循环会阻止主线程.只需用你的守护进程替换while true循环即可NSRunLoop.mainRunLoop().run().

我读了swifter(一个基于swift的服务器)的来源,它正在做同样的事情.


rsf*_*inn 5

在Swift 3和更高版本中,等效代码为:

RunLoop.main.run()
Run Code Online (Sandbox Code Playgroud)