2016-10-17 2 views
5

Я пишу вспомогательное приложение для Mac OS 10.10+, используя swift. Мне нужно иметь возможность вставлять содержимое из общего NSPasteboard в приложение, которое ранее было активным.Swift macOS: как вставить в другое приложение

Просто чтобы сделать его более ясным: мне нужно вставить в еще одно приложение.

Он должен работать так:

  1. Пользователь использует некоторые случайные приложения

  2. Поскольку пользователь не может нажать Cmd + V в связи с инвалидностью, они делают жест, который активирует мой приложение (эта часть выполнена, и это выходит за рамки этого вопроса)

  3. Мое приложение становится активным, и теперь мне нужно смоделировать действие Paste в приложении, которое пользователь использовал заранее. Это тот бит, который я не знаю, как это сделать.

  4. Наконец, активное активное приложение должно снова активироваться.

Пожалуйста, обратите внимание, что приложение должно быть отправлено в AppStore.

+0

Не делайте ваше приложение активно, вы не можете вставить неактивное приложение и другое приложение будет мигать. – Willeke

+0

@Willeke и как я могу вставить в активное приложение? – Neovibrant

+0

[Как вставлять текст из одного приложения в другое с помощью Cocoa?] (Http://stackoverflow.com/questions/2680760/how-to-paste-text-from-one-app-to-another-using-cocoa) – Willeke

ответ

4

В простейшем случае вам нужно сделать две вещи:

  1. Subscribe to notifications of the current application changing так что вы знаете, что приложение, которое вы должны отправить события.

  2. Simulate a Cmd+V keypress Использование системных событий.

Однако плохая новость заключается в том, как вы говорите, что вам нужно сделать это в представленном приложении в App Store, ваше приложение должно быть внутри песочницы и требует временного права com.apple.security.temporary-exception.apple-events для отправки события Системных событий directly quoting the Apple documentation :

с просьбой о необходимых яблоня событий временных пособий исключений для Finder и системных событий, вероятно, приведет к отказу в процессе рассмотрения приложения, так как предоставление доступа к этим процессам дает ваше приложение полную свободу действий в течение большей части операционной системы , Для задач системного уровня используйте другие методы, как обсуждалось выше.

Существует также способ сделать шаг № 2 с использованием вспомогательных технологий, но это тоже не будет работать внутри песочницы. По сути, то, что вы пытаетесь сделать (активировать внешнее произвольное приложение и контролировать его), в значительной степени сказывается на том, что изолированная программа предназначена для того, чтобы вы не делали.

К счастью, поскольку macOS 10.8 теперь существует NSUserAppleScriptTask, который выполняется вне песочницы.

Существует скручивание до NSUserAppleScriptTask: скрипты, выполненные с NSUserAppleScriptTask, должны быть помещены в каталог сценария приложения, и ваше приложение не может писать на него, только читать с него.

This objc.io article показывает пример того, как вы можете запросить доступ к записи с защитой для доступа к каталогу сценариев, чтобы иметь возможность писать свой скрипт; Раздражающе перед собой и с вашим пользователем, вы должны открыть открытое диалоговое окно в первый раз, поэтому вам нужно сохранить закладку с областью безопасности, поэтому вам не нужно повторять упражнение, но это лучшее, что вы сможете для выполнения внутри песочницы.

Ваш единственный маршрут, помимо прыжков NSUserAppleScriptTask Обручи, насколько мне известно, убеждают Apple в том, что это действительно хорошая идея принять ваше приложение с временным правом, которое позволяет ему сценариев системных событий (я бы не задерживал дыхание).

0

Я уверен, что вы можете сделать это с помощью Apple Events, но не забудьте установить временное исключение исключения, чтобы иметь возможность отправлять сообщения другому приложению.

+0

Что такое «События Apple»? Я был бы признателен за немного подробностей, если это возможно, пожалуйста. Кроме того, мне нужно отправить приложение в AppStore, если эта деталь имеет какое-либо значение. – Neovibrant

0

Я нашел эти команды, чтобы имитировать вырезать/копировать/вставить с помощью основания:?

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 пасты() {

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? (Водопроводная: 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 разреза() {

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 копия() {

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);

}

функ 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); 

}

функ 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); 

}

+0

Когда вы даете ответ, предпочтительнее дать [некоторое объяснение относительно ПОЧЕМУ ваш ответ] (http://stackoverflow.com/help/how-to-answer). –

Смежные вопросы