【发布时间】:2018-03-26 21:56:48
【问题描述】:
我正在使用 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 脚本似乎完全被忽略了。当我从 Terminal 运行 myscript 时,它会按预期运行。
测试myscript 文件如下所示:
#!/bin/sh
/usr/bin/osascript -e "tell app \"System Events\" to display dialog \"Message: $1\""
(这只是一个测试脚本;真正的调用emacsclient。)shell脚本文件设置为可执行(权限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) {
脚本运行。现在我需要弄清楚在第一次安装或运行应用程序时如何将脚本复制到脚本文件夹。
【问题讨论】:
-
你不能:A sandboxed application may read from, but not write to, this folder. (applicationScriptsDirectory)。顺便说一句,为什么你用
osascript和NSUserUnixTask运行AppleScript 而不是直接使用NSUserAppleScriptTask? -
谢谢。我使用
NSUserUnixTask运行它,因为我的脚本中有参数,而且它不是我真实应用程序中的 Apple 脚本。我真正想要的是运行emacsclient。顺便说一句,如果禁止写信给applicationScriptsDirectory,那么拥有该文件夹有什么意义呢?用户是否应该手动将文件复制到脚本文件夹? -
developer.apple.com/library/content/documentation/Security/…中说:“用户必须手动将脚本放在这里”
-
请在下方添加您编辑的问题答案作为真实答案:)
标签: swift macos shell cocoa appstore-sandbox