macos - 如何从 SwiftUI View 中运行 AppleScript?

标签 macos applescript swiftui

我对基本的 SwiftUI 有了更多的了解,但现在我想扩展我的应用程序,为我实际做一些关于系统组件的事情。基本上我想运行一个 AppleScript 从我的应用程序内部,它在 Mac Mail 中创建一个签名。脚本本身非常简单:

// Generates a signature in Mac Mail
tell application "Mail"
    set newSig to make new signature with properties {name:"The Signature Name"}
    set content of newSig to "My New Signature Content"
end tell

我创建了一个 查看 带有一个应该执行脚本的按钮:

import SwiftUI

struct SomeView: View {

    @State var status = ""

    var body: some View {

        VStack(alignment: .center) {
            Button(action: {

                let source = """
                tell application \"Mail\"
                    set newSig to make new signature with properties {name: \"The Signature Name\"}
                    set content of newSig to \"My New Signature Content\"
                end tell
                """

                var error: NSDictionary?
                if let scriptObject = NSAppleScript(source: source) {
                    if let output: NSAppleEventDescriptor = scriptObject.executeAndReturnError(&error) {
                        self.status = output.stringValue ?? "some default"
                    } else if (error != nil) {
                        self.status = "error: \(error)"
                    }
                }

            }) {
                Text("Generate").font(.callout)
            }
            Text("\(self.status)")

        }
    }
}

struct SomeView_Previews: PreviewProvider {
    static var previews: some View {
        SomeView()
    }
}

一切都执行,但我收到错误
AppleScript run error = {
    NSAppleScriptErrorAppName = Mail;
    NSAppleScriptErrorBriefMessage = "Application isn\U2019t running.";
    NSAppleScriptErrorMessage = "Mail got an error: Application isn\U2019t running.";
    NSAppleScriptErrorNumber = "-600";
    NSAppleScriptErrorRange = "NSRange: {0, 0}";
}

经过一番研究,我发现 this article这很好地描述了这个问题。显然这个错误是 因为应用程序在沙箱中运行 并且沙箱内的邮件确实没有运行。我有点理解 Apple 的想法,不要让应用程序在未经用户同意的情况下做任何他们想做的事......

无论如何,不​​幸的是这篇文章描述了使用 Objective C 的解决方案。这一点我比 SwiftUI 还不清楚。

谁能告诉我如何从 SwitUI View 中运行(或将我的 script.scpt 文件复制到可访问的库文件夹并运行)脚本?这将是非常有帮助的!

谢谢!!!

最佳答案

我已经用这种方式玩了很多,在对该主题进行了多次讨论和反复试验之后,我想提出 2 个解决方案(到目前为止,这些似乎是沙盒应用程序唯一可能的解决方案)。

首先,如果您不考虑在 上分发您的应用程序应用商店 ,您可以忘记以下内容,因为您只需要 停用沙盒 你基本上可以做任何你想做的事!

如果您计划分发 沙盒应用 ,运行脚本并与用户系统上的其他应用程序交互的唯一方法是 从应用程序脚本文件夹运行脚本文件 .此文件夹是用户库结构中的指定文件夹:/Users/thisUser/Library/Application Scripts/com.developerName.appName/ .无论这里输入什么脚本,您都有权从您的应用程序运行 appName .

您基本上有两个选项可以将脚本文件放入该文件夹:

选项 1 - 安装脚本文件

如果您的 ,这(在我看来)显然是您应该选择的选项。脚本是静态的 (不需要来自您的应用程序的任何其他用户数据)。你所要做的就是

  • 选择项目(一)
  • 点击 构建阶段 (2)
  • 添加 复制文件 设置(如果尚未存在)
  • 选择 应用程序中的脚本文件位置 (通过 AppStore 分发时,唱歌可能是一个不错的选择)
  • 添加 Application Script您的应用程序文件夹到目的地。因此,选择绝对路径然后输入 Users/$USER/Library/Application Scripts/$PRODUCT_BUNDLE_IDENTIFIER路径 field 。

  • 如果您的脚本完全是静态的,您也可以选择仅在安装时复制选项,但如果您在关闭并重新打开应用程序时对脚本进行了更改,并且您想更新脚本,请将此选项留空(我尚未对此进行测试) !)。

    enter image description here

    完成后,您可以通过 NSUserScriptTask 执行脚本. here. 提供了有关如何实现此功能的更详细说明。

    选项 2 - 授予对文件夹的访问权限并按需复制文件

    这当然是您的 时的解决方案脚本文件动态更新 根据例如用户输入。不幸的是,这有点麻烦并且没有(在我看来)令人满意的解决方案。为此,您必须授予对文件夹 的访问权限(在这种情况下 Application Scripts/ )。这是通过 NSOpenPanel 完成的.给出了一个非常好的教程如何实现这一点 here.

    默认情况下,您将只拥有对该文件夹的读取权限。由于您正在尝试将文件复制到该文件夹​​中,因此您必须将其更改为在您的 中读/写。能力以及。

    enter image description here

    我希望这会帮助一些人“照亮黑暗”!对我来说,这是一段相当长的旅程,因为那里只有很少的信息。

    关于macos - 如何从 SwiftUI View 中运行 AppleScript?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61988694/

    相关文章:

    objective-c - 如何以编程方式设置代理设置

    python - 导入错误 : No module named PyQt5 - OSX Mavericks

    string - "set foo to text returned of"代表数字吗?

    ios - SwiftUI - 如何在不滚动的情况下将多行文本包装在 UITextView 中?

    swift - 在 SwiftUI 中将 View 声明为 View 主体内的变量时出现 "Function declares an opaque return type [...]"错误

    azure - Node.js 加载项下载方法在 MacBook 中不起作用

    JavaScript/AppleScript : Get current time of html video

    dialog - 带有自定义图标的applescript显示对话框

    SwiftUI 使按钮在 HStack 中水平地彼此靠近

    swift - 打印用户点击的NSTableView的行号