[macOS] AppleEventサポート

# macOSにおけるAppleEventサポート方法
アプリケーションから、他のアプリケーションを制御するために、[Scripting Support](https://developer.apple.com/documentation/foundation/scripting_support)が準備されているのですが、ここ数年資料の更新が行われていません。本稿では最近のmacOS(10.15)でのサポート状況、方法についてまとめていきます。

なお、本稿で説明するのは、AppleEventの送出側の実装です。受信側については、別記事
[\[macOS\] Cocoa Scripting Support](https://qiita.com/wheel/items/c8d65bf042dda750d13a)をご覧下さい。

資料作成日: 2020.08.11
更新日: 2020.09.06

# 実行環境
下記を想定しています:

* OS: macOS 10.15
* Xcode: 11.6
* 言語: Swift

# AppleEvent
自アプリから他のアプリへのイベントの送信/受診に際して、イベントの実行は[NSAppleEventDescriptorクラス](https://developer.apple.com/documentation/foundation/nsappleeventdescriptor)で実装します。

* AppleScriptと、それから生成される`NSAppleEventDescriptor`の対応例については、[AppleEventDescriptor given by source AppleScript](https://github.com/steelwheels/Coconut/blob/master/CoconutData/Document/AppleEvent/applescript_to_eventdescriptor.md)を参照して下さい。
* `NSAppleEventDescriptor`の処理実装例については、拙作の実装を見てみて下さい。
  * [CNAppleEvent.swift](https://github.com/steelwheels/Coconut/blob/master/CoconutData/Source/Event/CNAppleEvent.swift)
  * [CNAppleEventDescriptor.swift](https://github.com/steelwheels/Coconut/blob/master/CoconutData/Source/Event/CNAppleEventDescriptor.swift)
 
# Sandbox対応
Sandbox下のアプケーションにて、AppleEventの送受信をサポートするためには、次の設定が必要です。下記の例では、`TextEdit.app`を制御する場合について記述しています。

## .plistファイルの設定

````
<?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>NSAppleScriptEnabled</key>
        <true/>
        <key>OSAScriptingDefinition</key>
        <string>CoconutScript.sdef</string>
        <key>NSAppleEventsUsageDescription</key>
        <string>Please permit to use AppleEvent</string>
        ....
</dict>
</plist>
````

3番目の項目については、Apple Developer Forumの[Not authorized to send Apple events to Mail](https://developer.apple.com/forums/thread/108815)を参照しています。この項目を定義しなければ、macOSの「システム環境設定」の「セキュリティとプライバシー」の「オートメーション」にアプリケーションが登録されない様です。

## .entitlementsファイルの設定
````
<?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>com.apple.security.temporary-exception.apple-events</key>
        <array>
                <string>com.apple.TextEdit</string>
        </array>
        <key>com.apple.security.scripting-targets</key>
        <dict>
                <key>com.apple.TextEdit</key>
                <array>
                        <string>com.apple.TextEdit</string>
                </array>
        </dict>
....
</dict>
````

2番目の項目、`com.apple.security.scripting-targets`については、[Hardened Runtime and Sandboxing](https://lapcatsoftware.com/articles/hardened-runtime-sandboxing.html)を参照しました。

# アプリケーションソフトウェアのbundle identifierの取得
macOS付属の[lsappinfo](https://www.manpagez.com/man/8/lsappinfo/)にて取得可能。
対象となるアプリが起動した状態で実行する必要がある。また、「テキストエディット」については、TextEditでは指定できない。

````
% lsappinfo info -only bundleid テキストエディット
"CFBundleIdentifier"="com.apple.TextEdit"
````

# 参考文献
* [Hardened Runtime and Sandboxing](https://lapcatsoftware.com/articles/hardened-runtime-sandboxing.html)
* [Not authorized to send Apple events to Mail](https://developer.apple.com/forums/thread/108815): Apple Developer ForumでのQ&A
* [\[OSX\]利用しているアプリケーションのBundle Identifierを調べる](https://qiita.com/miyasakura_/items/51e367b13d2fba545698): バンドルIDを知る方法