【问题标题】:AppleScript used in my cocoa mac app, stopped working in osx 10.14在我的 cocoa mac 应用程序中使用的 AppleScript 在 osx 10.14 中停止工作
【发布时间】:2019-05-03 00:06:36
【问题描述】:

我使用 AppleScript 从第三方应用程序中获取选定的文本。在 osx 10.13 中运行良好,但在 osx 10.14 中停止工作。

从搜索中,得到了一个在 info.plist 中添加“NSAppleEventsUsageDescription”的建议,但这对我也不起作用。

let latestApp = "Safari"

        //Write script to activate the app and get the selected text to our app
        let script = """
        tell application \"\(latestApp)\"
        activate
        end tell
        tell application \"System Events\"
        tell process \"\(latestApp)\"
        keystroke \"c\" using {command down}
        delay 0.1
        set myData to (the clipboard) as text
        return myData
        end tell
        end tell
        """
        let scriptObject = NSAppleScript.init(source: script)
        let errorDict: AutoreleasingUnsafeMutablePointer<NSDictionary?>? = nil
        var returnDescription:NSAppleEventDescriptor? = nil
        returnDescription = scriptObject?.executeAndReturnError(errorDict)
        if( returnDescription != nil ){
            if( kAENullEvent != returnDescription?.descriptorType ){ //successful execution
                if( cAEList == returnDescription?.descriptorType ){
                    print("return  value")
                }else{
                    print("Returned string : \(String(describing: returnDescription?.stringValue))")
                    let selectedStr = returnDescription?.stringValue!
                    if( (selectedStr?.count)! > 0 ){
                        print("selectedStr is :\(String(describing: selectedStr))")
                    }
                }
            }

        }else{
            print("Error is : \(String(describing: errorDict))")

        }

它也可以在 os 10.12 & 10.13 & ScriptEditor 中完美运行。

【问题讨论】:

  • @Willeke,我在 info.plist 中添加了“NSAppleEventsUsageDescription”,在权利中设置了“App Sandbox” No,功能也是,应用沙箱已关闭。但它仍然不起作用。如果我在 Safari 中选择任何文本并从我的应用程序中运行 appleScript(通过与我设置 appleScript 的按钮交互),Safari 应用程序会被激活,但我没有得到选定的数据。
  • 我也在我的应用程序中使用了辅助功能,所以当我现在从 Xcode 运行我的应用程序时,Xcode 被添加到“安全和隐私”->“辅助功能”中
  • Mojave 中的一项新安全功能围绕系统对话框展开,提示您授予对想要控制其他应用程序的应用程序的访问权限。我也没有得到任何这样的对话。我在启动时只有一个对话框,用于在系统偏好设置中授予我的应用程序的可访问性权限。
  • 请在上下文中显示实际代码。什么是最新应用程序?你用脚本做什么?提供 MCVE。

标签: swift macos applescript


【解决方案1】:

由于您告诉“Safari”激活,所以没有必要使用"System Events" to tell process "Safari"...。只需使用"System Events"keystroke "c" using {command down} 即可完成同样的事情。这不是什么大不了的事,但在这里和那里消除不必要的代码行,使浏览代码更容易和更清晰。此外,在keystroke "c" using {command down} 命令之前没有添加额外的delay 0.3,50% 的时间在我的系统上返回一个空剪贴板。

此 AppleScript 代码适用于我使用最新版本的 macOS Mojave。

tell application "Safari" to activate
delay 0.2 -- Adjust As Needed
tell application "System Events" to keystroke "c" using {command down}
set myData to (the clipboard) as text

由于clipboard 命令由标准添加而不是系统事件处理(正如@user3439894 在他的评论中提到的那样),从@987654329 中删除set myData to (the clipboard) as text @tell block,让我成功删除了delay 0.1 命令。

或选项 2

实际上,再想一想,如果您只想在 Safari 中使用它,那么下面一行 AppleScript 代码就可以满足您的需求。

您必须在 Safari 的开发菜单中启用 Allow JavaScript from Apple Events 选项才能使用do JavaScript

tell application "Safari" to set myData to (do JavaScript "''+document.getSelection()" in document 1)

我只讨论了 AppleScript 部分,因为 @matt 在他的帖子中彻底涵盖了所有其他问题。

【讨论】:

  • 我还要指出 set myData to (the clipboard) as textreturn myData 确实不属于 tell application "System Events" block,因为它们是 StandardAdditions 的一部分b>,而不是系统事件。至于 System Events 之前的delay command 执行keystroke command,在这种情况下我会使用repeat System Events tell block 内的 i>loop,例如:repeat until (name of every process whose frontmost is true) = {"Safari"} 后跟 delay 0.01 并关闭 loop i> 与end repeat.
  • 我知道@user3439894 给了你一些非常好的、明智的批评。剧本可能并不完美,但尽管如此,这可能是我从你那里读到的最喜欢的答案之一。您在这里似乎很认真地解决了 OP 的脚本问题,正如您所说,这可能不是生死攸关的问题,但很高兴看到您关注细节并传递有关生产更清洁的精神,更精简的代码和简单的编程技巧。 delay 0.3 可能不是这里的黄金标准,但您向 OP 推理并改进了他的脚本。为所有这些 +1。
  • @user3439894 @CJK 我的第一个代码版本实际上确实使用了repeat until 循环而不是delay .3。我选择不使用它,因为超过 50% 的时间它返回一个空的剪贴板,而 delay .3 被证明是 100% 的成功(在我的系统上,同时有 8 个不同的桌面空间处于活动状态,同时运行了 6 个其他应用程序)。
  • @wch1zpink,这再次表明 UI 脚本是不可靠的,应该避免使用,除非没有其他方法可以完成工作! :)
  • 别忘了在答案的选项 2 中使用 JaveScript,即 Allow JavaScript from Apple Events,默认隐藏, Safari 中的 Develop 菜单必须选中。
【解决方案2】:

您在以前的系统中说“它工作得很好”。我觉得这很难相信,因为您的代码几乎所有内容都是错误的。我更正了您的代码并让您的脚本正常工作,几乎没有什么困难。

我会试着描述一下我做了什么。

为了做好准备,我在脚本编辑器中运行了您的脚本版本(当然删除了反斜杠和字符串插值):

tell application "Safari"
    activate
end tell
tell application "System Events"
    tell process "Safari.app"
        keystroke "c" using {command down}
        delay 0.1
        set myData to (the clipboard) as text
        return myData
    end tell
end tell

脚本一开始没有运行,但一个对话框将我发送到系统偏好设置 -> 安全和隐私 -> 可访问性,在那里我检查了脚本编辑器和系统事件。

现在我已准备好创建应用程序。我的应用程序称为 AnotherAppleScriptExample。就其权利而言,沙盒是不行的。

在它的 Info.plist 中有这个条目:

我的代码版本(修复各种 Swift 错误)是这样的:

        let app = "Safari.app"
        let script = """
        tell application "\(app)"
            activate
        end tell
        tell application "System Events"
            tell process "\(app)"
                keystroke "c" using {command down}
                delay 0.1
                set myData to (the clipboard) as text
                return myData
            end tell
        end tell
        """
        if let scriptObject = NSAppleScript(source: script) {
            var error: NSDictionary? = nil
            let result = scriptObject.executeAndReturnError(&error)
            if( kAENullEvent != result.descriptorType ){
                print(result.stringValue as Any)
            }
        }

我运行了应用程序。我有两个对话框。首先是:

我点击了确定。那么这个:

我点击了打开系统偏好设置。在系统偏好设置中,我检查了我的应用程序(现在系统事件和我的应用程序都已检查):

现在地面已经准备就绪。我退出了应用程序并再次运行它。脚本正常运行,在 Safari 中打印选择。

【讨论】:

    猜你喜欢
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 2021-04-14
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多