[英]Swift macOS: How to paste into another application
我正在使用swift为Mac OS 10.10+编写一个辅助应用程序。 我需要能够将通用NSPasteboard中的内容粘贴到之前处于活动状态的应用程序中。
只是为了说清楚:我需要粘贴到另一个应用程序中。
它应该像这样工作:
用户正在使用一些随机应用程序
因为用户因残疾而无法按下cmd + v,所以他们会做出一个手势来激活我的应用程序(此部分已完成并且超出了此问题的范围)
我的应用程序变为活动状态,现在我需要在用户预先使用的应用程序中模拟粘贴操作。 这是我不知道怎么做的。
最后,以前活跃的应用程序需要再次激活。
请记住,该应用程序将提交给AppStore。
最简单的是你需要做两件事:
订阅当前应用程序更改的通知,以便您知道应将事件发送到哪个应用程序。
使用系统事件模拟Cmd + V按键 。
然而,坏消息是,正如您所说,您需要在App Store提交的应用程序中执行此操作,您的应用程序需要位于沙箱内,并且需要临时授权com.apple.security.temporary-exception.apple-events
来发送系统事件直接引用Apple文档的事件:
在应用程序审核过程中,为Finder和系统事件请求必要的Apple事件临时例外权利可能会导致拒绝,因为授予对这些进程的访问权限可以让您的应用程序免费控制大部分操作系统。 对于系统级任务,请使用其他方法,如上所述。
还有一种方法可以使用辅助技术执行第2步,但这也不适用于沙箱。 从根本上说,你要做的事情(激活一个外部的任意应用程序,并控制它)几乎就是沙箱的设计目的是阻止你做什么。
幸运的是,由于macOS 10.8现在有NSUserAppleScriptTask ,它在沙箱之外执行。
NSUserAppleScriptTask
有一个NSUserAppleScriptTask
:使用NSUserAppleScriptTask
执行的脚本需要放在应用程序的脚本目录中,并且您的应用程序无法写入它,只能从中读取。
这篇objc.io文章展示了一个示例,说明如何请求对脚本目录进行安全范围写入访问,以便能够将脚本编写到脚本目录中; 对于你自己和你的用户来说,你需要第一次打开一个打开的对话框,因此,你需要存储安全范围的书签,这样你就不需要重复练习,但这是你能做到的最好的在沙箱内做。
根据我的知识跳过NSUserAppleScriptTask
唯一其他途径是说服Apple,这是一个非常好的主意,接受你的应用程序的临时权利,允许它编写系统事件脚本(我不会屏住呼吸)。
我发现这些命令可以使用Foundation模拟剪切/复制/粘贴:
func pastematchstyle () {
let event1 = CGEvent(keyboardEventSource: nil, virtualKey: 0x09, keyDown: true); // opt-shft-cmd-v down
event1?.flags = [CGEventFlags.maskCommand, CGEventFlags.maskShift, CGEventFlags.maskAlternate]
event1?.post(tap: CGEventTapLocation.cghidEventTap);
let event2 = CGEvent(keyboardEventSource: nil, virtualKey: 0x09, keyDown: false); // opt-shf-cmd-v up
// event2?.flags = [CGEventFlags.maskCommand, CGEventFlags.maskShift, CGEventFlags.maskAlternate]
event2?.post(tap: CGEventTapLocation.cghidEventTap);
}
func paste () {
let event1 = CGEvent(keyboardEventSource: nil, virtualKey: 0x09, keyDown: true); // cmd-v down
event1?.flags = CGEventFlags.maskCommand;
event1?.post(tap: CGEventTapLocation.cghidEventTap);
let event2 = CGEvent(keyboardEventSource: nil, virtualKey: 0x09, keyDown: false) // cmd-v up
// event2?.flags = CGEventFlags.maskCommand
event2?.post(tap: CGEventTapLocation.cghidEventTap)
}
func pasteresults () {
let event1 = CGEvent(keyboardEventSource: nil, virtualKey: 0x09, keyDown: true); // shft-cmd-v down
event1?.flags = [CGEventFlags.maskCommand, CGEventFlags.maskShift]
event1?.post(tap: CGEventTapLocation.cghidEventTap);
let event2 = CGEvent(keyboardEventSource: nil, virtualKey: 0x09, keyDown: false); // shf-cmd-v up
// event2?.flags = [CGEventFlags.maskCommand, CGEventFlags.maskShift];
event2?.post(tap: CGEventTapLocation.cghidEventTap);
}
func cut() {
let event1 = CGEvent(keyboardEventSource: nil, virtualKey: 0x07, keyDown: true); // cmd-x down
event1?.flags = CGEventFlags.maskCommand;
event1?.post(tap: CGEventTapLocation.cghidEventTap);
let event2 = CGEvent(keyboardEventSource: nil, virtualKey: 0x07, keyDown: false); // cmd-x up
// event2?.flags = CGEventFlags.maskCommand;
event2?.post(tap: CGEventTapLocation.cghidEventTap);
}
func copy() {
let event1 = CGEvent(keyboardEventSource: nil, virtualKey: 0x08, keyDown: true); // cmd-c down
event1?.flags = CGEventFlags.maskCommand;
event1?.post(tap: CGEventTapLocation.cghidEventTap);
let event2 = CGEvent(keyboardEventSource: nil, virtualKey: 0x08, keyDown: false); // cmd-c up
// event2?.flags = CGEventFlags.maskCommand;
event2?.post(tap: CGEventTapLocation.cghidEventTap);
}
func copystyle() {
let event1 = CGEvent(keyboardEventSource: nil, virtualKey: 0x08, keyDown: true); // opt-cmd-c down
event1?.flags = [CGEventFlags.maskCommand, CGEventFlags.maskAlternate];
event1?.post(tap: CGEventTapLocation.cghidEventTap);
let event2 = CGEvent(keyboardEventSource: nil, virtualKey: 0x08, keyDown: false); // opt-cmd-c up
// event2?.flags = CGEventFlags.maskCommand;
event2?.post(tap: CGEventTapLocation.cghidEventTap);
}
func pastestyle() {
let event1 = CGEvent(keyboardEventSource: nil, virtualKey: 0x07, keyDown: true); // opt-cmd-v down
event1?.flags = [CGEventFlags.maskCommand, CGEventFlags.maskAlternate];
event1?.post(tap: CGEventTapLocation.cghidEventTap);
let event2 = CGEvent(keyboardEventSource: nil, virtualKey: 0x07, keyDown: false); // opt-cmd-v up
// event2?.flags = CGEventFlags.maskCommand;
event2?.post(tap: CGEventTapLocation.cghidEventTap);
}
我很确定你可以用Apple Events做到这一点,但不要忘记设置一个临时的例外权利,以便能够发送另一个应用程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.