macOS下Swift编写launchd daemon捕获关机事件失败求助
问题描述
我知道这个问题之前有人提过,但一直没找到有效的解决办法。我用Swift写了一个launchd守护进程,目的是捕获系统关机通知并执行脚本或其他操作。
目前这个守护进程能正常启动,日志显示已经完成观察者注册(但没法确认是不是真的注册成功),但就是捕获不到关机通知。
注:我已经更新过代码,现在没有选择器错误,能正常捕获应用激活/隐藏通知,但关机通知还是抓不到。
Swift代码
import AppKit import os public class ShutdownHandlerDelegate : NSObject, NSApplicationDelegate { static let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "LoggingTest") var shutdownObserver: NSObjectProtocol? @objc func handleShutdown() { ShutdownHandlerDelegate.logger.notice("System is about to shut down. This is us logging that for debug...") NSWorkspace.shared.notificationCenter.removeObserver(shutdownObserver!) shutdownObserver = nil // Perform your pre-shutdown tasks here } @objc func handleActivate(_ notification: Notification) { if let app = (notification.userInfo?[NSWorkspace.applicationUserInfoKey] as? NSRunningApplication)?.bundleIdentifier { ShutdownHandlerDelegate.logger.notice("\(app, privacy: .public) will now be activated!") // Perform your pre-shutdown tasks here } } @objc func handleHide(_ notification: Notification) { if let app = (notification.userInfo?[NSWorkspace.applicationUserInfoKey] as? NSRunningApplication)?.bundleIdentifier { ShutdownHandlerDelegate.logger.notice("\(app, privacy: .public) will now be hidden!") // Perform your pre-shutdown tasks here } } func setUpObservers() { self.shutdownObserver = NSWorkspace.shared.notificationCenter.addObserver(forName: NSWorkspace.willPowerOffNotification, object: nil, queue: OperationQueue.main, using: { (_ note) in self.handleShutdown() }) // NSWorkspace.shared.notificationCenter.addObserver( // self, // selector: #selector(handleShutdown(_:)), // name: NSWorkspace.willPowerOffNotification, // object: nil // ) NSWorkspace.shared.notificationCenter.addObserver( self, selector: #selector(handleActivate(_:)), name: NSWorkspace.didActivateApplicationNotification, object: nil ) NSWorkspace.shared.notificationCenter.addObserver( self, selector: #selector(handleHide(_:)), name: NSWorkspace.didHideApplicationNotification, object: nil ) } override init() { super.init() } deinit { if let observer = shutdownObserver { NSWorkspace.shared.notificationCenter.removeObserver(observer) } } } @main public class ShutdownHandler : NSObject { let _app : NSApplication? static let _delegate : ShutdownHandlerDelegate = ShutdownHandlerDelegate() static public func main() { // _app.delegate = ShutdownHandlerDelegate _delegate.setUpObservers() ShutdownHandlerDelegate.logger.notice("We're registering the shutdown observer. bundle-id is: \(Bundle.main.bundleIdentifier!, privacy: .public)") NSApplication.shared.run() // This keeps the app running & makes sure events are received } override init () { _app = NSApplication.shared _app!.delegate = ShutdownHandler._delegate super.init() } }
launchd配置文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.lord-kamina.shutdownHandler</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/shutdown-daemon</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> </dict> </plist>
内容的提问来源于stack exchange,提问作者Gregorio Litenstein
相关产品推荐
相关产品推荐

