如何在 swift 2 命令行工具中创建最小守护进程?
How to create a minimal daemon process in a swift 2 command line tool?
我想做什么
我想要 运行 一个可以监听 OSX 系统事件的守护进程,例如 command line tool
xcode 项目中的 NSWorkspaceWillLaunchApplicationNotification
?那可能吗?如果没有,为什么不,是否有任何解决方法或黑客攻击?
一些代码示例
来自 swift 2
cocoa application
项目的以下示例代码设置了一个系统事件侦听器,它会在每次 OSX 应用程序启动时调用 WillLaunchApp
。 (这很好用)
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)
}
}
相比之下,这个类似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)
}
我想我在这里遗漏了一些 cocoa
and/or xcode
基础知识,但我不知道是哪些。也许它与 while-true 循环有关,它可能会阻止事件。如果是这样,是否有 正确 方法 运行 守护程序 进程?
原来使用 while true
循环确实阻塞了主线程。
只需将 while true
循环替换为 NSRunLoop.mainRunLoop().run()
即可获得守护进程。
我阅读了 swifter(一个基于 swift 的服务器)的源代码,它也是这样做的。
在Swift3及以后的版本中,等效代码为:
RunLoop.main.run()
我想做什么
我想要 运行 一个可以监听 OSX 系统事件的守护进程,例如 command line tool
xcode 项目中的 NSWorkspaceWillLaunchApplicationNotification
?那可能吗?如果没有,为什么不,是否有任何解决方法或黑客攻击?
一些代码示例
来自 swift 2
cocoa application
项目的以下示例代码设置了一个系统事件侦听器,它会在每次 OSX 应用程序启动时调用 WillLaunchApp
。 (这很好用)
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)
}
}
相比之下,这个类似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)
}
我想我在这里遗漏了一些 cocoa
and/or xcode
基础知识,但我不知道是哪些。也许它与 while-true 循环有关,它可能会阻止事件。如果是这样,是否有 正确 方法 运行 守护程序 进程?
原来使用 while true
循环确实阻塞了主线程。
只需将 while true
循环替换为 NSRunLoop.mainRunLoop().run()
即可获得守护进程。
我阅读了 swifter(一个基于 swift 的服务器)的源代码,它也是这样做的。
在Swift3及以后的版本中,等效代码为:
RunLoop.main.run()