【问题标题】:ScriptingBridge code errors in Xcode 8.0 and swift 3.0Xcode 8.0 和 swift 3.0 中的 ScriptingBridge 代码错误
【发布时间】:2016-09-29 15:18:03
【问题描述】:

这是我在 Xcode 7.3.1 中使用的代码,运行良好:

    var selectedFiles = NSMutableArray(capacity:1)
    let  finder: AnyObject! = SBApplication(bundleIdentifier:"com.apple.finder")
    let finderObject = finder.selection as! SBObject
    let selection: AnyObject! = finderObject.get()
    let items = selection.arrayByApplyingSelector(Selector("URL"))

    let filteredfiles = (items as NSArray).pathsMatchingExtensions(["ai","pdf","ap","paf","pafsc"])
    for  item in filteredfiles {
        let url = NSURL(string:item ,relativeToURL:nil)
        selectedFiles.addObject(url!)
    }

这是针对 Xcode 8.0 更正的代码,但不起作用: 最后一行产生错误

error = 不能调用非函数类型'[Any]!'的值

    var selectedFiles = NSMutableArray(capacity:1)
    let  finder: AnyObject! = SBApplication(bundleIdentifier:"com.apple.finder")
    let finderObject = finder.selection as! SBObject
    if let selection = finderObject.get()  as AnyObject?{
        let items =  selection.array(#selector(getter: NSTextCheckingResult.url))
        let filteredfiles = (items as NSArray).pathsMatchingExtensions(["ai","pdf","ap","paf","pafsc"])
        for  item in filteredfiles {
          let url = NSURL(string:item ,relativeToURL:nil)
          selectedFiles.addObject(url!)
       }
    }

我尝试了很多解决方案,但不幸的是找不到线索。 我猜这是因为 Swift 3.0x API 发生了巨大的变化...... 欢迎任何帮助!

【问题讨论】:

    标签: swift3 xcode8 finder scripting-bridge macos-sierra


    【解决方案1】:

    这是一种稍微不同的方法,它使用了 Swift 3 的几个原生 Swift 函数

    var selectedFiles = [URL]()
    let  finder : AnyObject = SBApplication(bundleIdentifier:"com.apple.finder")!
    let finderObject = finder.selection as! SBObject
    if let selection = finderObject.get() as? [SBObject] {
      selection.forEach { item in
          let url = URL(string: item.value(forKey:"URL") as! String)!
          selectedFiles.append(url)
        }
    
      let goodExtensions = ["ai","pdf","ap","paf","pafsc"]
      let filteredURLs = selectedFiles.filter({goodExtensions.contains($0.pathExtension)})
      print(filteredURLs)
    }
    

    PS:我强烈推荐使用AppleScriptObjC。它更容易使用。

    PPS:valueForKey 是故意使用的,因为确实需要 KVC 来获取属性值。

    【讨论】:

    • 感谢闪电般的快速回答。它工作得很好。我曾经使用 AppleScriptObjC 制作我的项目,但在大多数情况下,我会尝试使用原生 Swift 和最少的其他帮助程序。有时这是不可能的!
    • 人们推荐使用 AppleScriptObjC 的原因是 ScriptingBridge 充满了错误和残缺/缺失的功能,而不是导致许多在 AS 中完美运行的命令在 SB 中失败。也就是说,由于 Swift 更严格的类型,两者在 Swift 中的使用都比在 ObjC 中更复杂。 FWIW 我目前正在开发一个原生 Swift-to-AppleEvent bridge 作为 AppleScript 的真正 Swift 友好替代品,欢迎您使用它,但请注意,我对它的长期支持将取决于它可以吸引多少支持Apple/Swift 开发者。
    • 关于“强烈推荐使用AppleScriptObjC”,Swift AppleScriptObjC selectedFinderFiles 实现会是什么样子?如果不添加任何 Objective-C 或 AppleScript 代码,是否可以实现 Swift AppleScriptObjC
    • 在 Swift 应用程序中使用 AppleScriptObjC 需要一个微型 ObjC 桥,但所有与 AppleScript 相关的代码都可以是原生 AppleScript(可以与一种 Objective-C 语法混合)。一个好处是您可以轻松地从 Swift 代码调用本机 AppleScript 处理程序。以here 为例
    猜你喜欢
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多