NSUserUnixTask静静地忽略脚本

时间:2017-10-15 06:32:35

标签: swift macos shell cocoa appstore-sandbox

我正在使用Xcode 9在macOS High Sierra上使用Swift 4编写沙盒应用程序。我的应用程序在安装时将一个shell脚本文件(例如,myscript)复制到Bundle.main.resourceURL目录。我想使用NSUserUnixTask运行此shell脚本,如下所示:

if let scriptUrl = URL(string: "myscript", relativeTo: Bundle.main.resourceURL) {
    do {
        let task = try NSUserUnixTask(url: scriptUrl)
        task.execute(withArguments: [ "hello" ])
        debugPrint("OK")
    } catch let error {
        debugPrint(error)
    }
} else {
    debugPrint("Script not found")
}

// output: "OK"

这不会给出任何错误消息和" OK"正确显示。但myscript脚本似乎完全被忽略了。当我从myscript运行Terminal时,它会按预期运行。

测试myscript文件如下:

#!/bin/sh
/usr/bin/osascript -e "tell app \"System Events\" to display dialog \"Message: $1\""

(这只是一个测试脚本;真正的一个调用emacsclient。)shell脚本文件设置为executable(权限755)。似乎忽略了这个shell脚本以及任何其他shell脚本。例如,如果第二行替换为/usr/bin/printf "\a",则不会发出蜂鸣声。我尝试了很多其他的shell脚本,但似乎没什么用。

我该如何解决这个问题?

编辑:

我很仓促。类文档说"如果应用程序是沙箱,则脚本必须位于applicationScriptsDirectory文件夹中。"现在我想知道如何在安装时复制脚本文件。

编辑2:

我手动将myscript复制到~/Library/Applications Scripts/com.mydomain.myApp/,然后将上述Swift代码的第一行(if let scriptUrl ...)更改为

let scriptFolderUrl = try! FileManager.default.url(for: .applicationScriptsDirectory, 
    in: .userDomainMask, appropriateFor: nil, create: true)
if let scriptUrl = URL(string: "myscript", relativeTo: scriptFolderURL) {

https://tutel.me/c/programming/questions/43741325/swift+3++sandbox++how+to+create+applicationscriptsdirectory+if+it+doesn39t+exist

脚本运行。现在,我需要弄清楚如何在第一次安装或运行应用程序时将脚本复制到脚本文件夹。

1 个答案:

答案 0 :(得分:1)

pkamp请求了正确的答案。 :)

正如class document所说,脚本必须位于applicationScriptsDirectory文件夹中。正如vadian所指出的,此文件夹不能被沙盒应用程序写入。脚本(myscript)必须手动复制到applicationScriptDirectory文件夹(例如~/Library/Applications Scripts/com.mydomain.myApp/)中。

完成此操作后,将第一行更改为以下内容:

// --------------------------------------------------------
let scriptFolderUrl = try! FileManager.default.url(for: .applicationScriptsDirectory,
    in: .userDomainMask, appropriateFor: nil, create: true)
if let scriptUrl = URL(string: "myscript", relativeTo: scriptFolderURL) {
// --------------------------------------------------------
    // same below
    do {
        let task = try NSUserUnixTask(url: scriptUrl)
        task.execute(withArguments: [ "hello" ])
        debugPrint("OK")
    } catch let error {
        debugPrint(error)
    }
} else {
    debugPrint("Script not found")
}

第一行让我受益于this link