web-dev-qa-db-ja.com

SwiftアプリケーションからApplescriptスクリプトを実行できますか

メールを送信する簡単なAppleScriptを持っています。 Swiftアプリケーション内からどのように呼び出すことができますか?

(Googleで答えを見つけることができませんでした。)

26
codingguy3000

テストされていませんが、(任意のスクリプトパスが追加されました)のようなことができるようです:

import Foundation

let task = NSTask()
task.launchPath = "/usr/bin/osascript"
task.arguments = ["~/Desktop/testscript.scpt"]

task.launch()

[UPDATE 2019年になりました。おそらく過去数年間にいくつかの問題と変更がありました。ここに私のマシンでテストした更新済みコードがあります。これはOSX Mojave 10.14.5上にあります]

ObjC.import('Foundation');

let task = $.NSTask.alloc.init;
task.launchPath = "/usr/bin/osascript";
task.arguments = ["/testing_folder/test.scpt"];

task.launch
23
CRGreen

Kamarosが示唆する のように、 NSApplescript を直接呼び出すことができ、NSTaskを介して別のプロセスを起動する必要はありません( CRGreenが示唆するように 。)

スイフトコード

let myAppleScript = "..."
var error: NSDictionary?
if let scriptObject = NSAppleScript(source: myAppleScript) {
    if let output: NSAppleEventDescriptor = scriptObject.executeAndReturnError(
                                                                       &error) {
        print(output.stringValue)
    } else if (error != nil) {
        print("error: \(error)")
    }
}
55
zekel

以下のSwift 4の警告を受け取っている人のために、 zekelの答え からNSAppleEventDescriptorを作成している間の行

オプションのチェックで使用される「NSAppleEventDescriptor」タイプの非オプションの式

あなたはこの編集された短いバージョンでそれを取り除くことができます:

let myAppleScript = "..."
var error: NSDictionary?
if let scriptObject = NSAppleScript(source: myAppleScript) {
    if let outputString = scriptObject.executeAndReturnError(&error).stringValue {
        print(outputString)
    } else if (error != nil) {
        print("error: ", error!)
    }
}

ただし、あなたも気づいたかもしれません。この方法では、スクリプトを実行するたびに、システムはこのメッセージをコンソールに記録します。

AppleEvents:getMemoryReferenceで期待される複合型ではないmach msgを受け取りました。

どうやらこれはAppleスタッフ開発者によって宣言されたバグであり、「単なる」無害なログスパムと言われ、この非常に長い Apple開発者フォーラムの投稿 とSOの質問で確認できるように、将来のOSアップデートで削除される予定です未満:

AppleEvents:getMemoryReferenceで期待される複合型ではないmach msgを受け取りました

Appleに感謝します。膨大な数のジャンクコンソールログが発生しました。

3
loopbender

2018年3月の時点で、このスレッドで最も強力な答えは、まだ 2011年から受け入れられた回答 だと思います。 NSAppleScriptまたはOSAScriptの使用に関連する実装には、実際には追加の利点を提供せずに、軽微ではあるが非常に不愉快なメモリリークという欠点がありました。 (Swift 4で)その答えを正しく実行するのに苦労している人はこれを試してみたいかもしれません:

let manager = FileManager()
// Note that this assumes your .scpt file is located somewhere in the Documents directory
let script: URL? = try? manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
if let scriptPath = script?.appendingPathComponent("/path/to/scriptName").appendingPathExtension("scpt").path {
    let process = Process()
    if process.isRunning == false {
        let pipe = Pipe()
        process.launchPath = "/usr/bin/osascript"
        process.arguments = [scriptPath]
        process.standardError = pipe
        process.launch()
    }
}
3
Ben

私は数時間苦労しましたが、何もうまくいきませんでした。最後に、シェルを介してAppleScriptを実行することができました。

let proc = Process()
proc.launchPath = "/usr/bin/env"
proc.arguments = ["/usr/bin/osascript", "scriptPath"]
proc.launch()

Dunnoはこれを行うための最良の方法ですが、少なくとも機能します。

2
user4646361

AppleのテクニカルノートTN2084からNSAppleScriptを試すことができます。CocoaアプリケーションでAppleScriptスクリプトを使用する https://developer.Apple.com/library/mac/technotes/tn2084/_index.html

NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
            @"\
            set app_path to path to me\n\
            tell application \"System Events\"\n\
            if \"AddLoginItem\" is not in (name of every login item) then\n\
            make login item at end with properties {hidden:false, path:app_path}\n\
            end if\n\
            end tell"];

returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
2
Yongxu Ren