我正在关注cocoa documentation以确定OSX中当前的最前面的应用程序 - 也就是接收关键事件的应用程序。
但是,当我执行以下swift时,API总是返回相同的值 - XCode
,但是当我切换到它时,它永远不会更改为chrome
或任何其他应用程序。我也尝试执行已编译的程序,但它不再显示XCode
,而是显示我正在运行的终端应用程序。
确定从OSX接收关键事件的应用程序的正确方法是什么?我这方面的代码是否破了?
import Cocoa
func getActiveApplication() -> String{
// Return the localized name of the currently active application
let ws = NSWorkspace.sharedWorkspace()
let frontApp = ws.frontmostApplication
return frontApp.localizedName
}
var frontMostApp : String
while true {
frontMostApp = getActiveApplication();
NSLog("front app: %@", frontMostApp)
sleep(1);
}
答案 0 :(得分:5)
这个帖子有点旧,但非常有帮助。我根据Marco的帖子和uchuugaka的回答做了一些研究。以下是结果。
// swift 3.0
// compile: xcrun -sdk macosx swiftc -framework Cocoa foo.swift -o foo
// run: ./foo
import Cocoa
class MyObserver: NSObject {
override init() {
super.init()
NSWorkspace.shared().notificationCenter.addObserver(self,
selector: #selector(printMe(_:)),
name: NSNotification.Name.NSWorkspaceDidActivateApplication,
object:nil)
}
dynamic private func printMe(_ notification: NSNotification) {
let app = notification.userInfo!["NSWorkspaceApplicationKey"] as! NSRunningApplication
print(app.localizedName!)
}
}
let observer = MyObserver()
RunLoop.main.run()
我是Cocoa和Swift的新手。我不知道上述内容是否有效,但它对我有用。我得到了How to create a minimal daemon process in a swift 2 command line tool?和Swift 3 NSNotificationCenter Keyboardwillshow/hide等众多其他人的帮助。
Swift 4:
NSWorkspace.shared.notificationCenter.addObserver(self, // HERE, shared
selector: #selector(printMe(_:)),
name: NSWorkspace.didActivateApplicationNotification, // HERE
object:nil)
编辑(Swift 4)
编译器说printMe
函数必须是@objc
。 (我不知道其含义,但是当我在行的开头添加@objc
时,它就有效。这是完整的代码,便于复制粘贴。
// swift 4.0
// compile: xcrun -sdk macosx swiftc -framework Cocoa foo.swift -o foo
// run: ./foo
import Cocoa
class MyObserver: NSObject {
override init() {
super.init()
NSWorkspace.shared.notificationCenter.addObserver(self,
selector: #selector(printMe(_:)),
name: NSWorkspace.didActivateApplicationNotification,
object:nil)
}
@objc dynamic private func printMe(_ notification: NSNotification) {
let app = notification.userInfo!["NSWorkspaceApplicationKey"] as! NSRunningApplication
print(app.localizedName!)
}
}
let observer = MyObserver()
RunLoop.main.run()
答案 1 :(得分:4)
您应该采用不同的方式做一件事,即遵循NSWorkSpace通知,告知您应用程序已重新启动或已变为活动状态。 这是关键,特别是当您在调试模式下运行时。 在调试模式下,Xcode将您的应用程序作为子进程生成。 在发布模式下,它基本上与在终端中调用open命令相同。 在调试模式下,如果过早地调用此代码并且只调用一次,则表示您没有捕获更改。记住它是动态的。