[英]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.