2016-09-29 4 views
1

Это код, который я использовал в Xcode 7.3.1 и что работал отлично:ScriptingBridge ошибки кода в Xcode 8.0 и 3.0 быстры

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 сильно изменились .... Любая помощь приветствуется!

ответ

1

Это немного другой подход, использующий пару нативных Swift функций для Swift 3

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 действительно необходим для получения стоимости имущества.

+0

Спасибо за ответ молниеносно. Он работает очень хорошо. Я использовал свои проекты с AppleScriptObjC, но в большинстве случаев я стараюсь использовать собственный Swift с минимальным количеством других помощников. Иногда невозможно иначе! –

+0

Причина, по которой люди рекомендуют использовать AppleScriptObjC, заключается в том, что ScriptingBridge пронизан ошибками и искаженными/отсутствующими функциями, чем причиной многих команд, которые отлично работают в AS, чтобы сбой в SB. Тем не менее, оба более сложно использовать в Swift, чем ObjC из-за более строгой типизации Swift. FWIW В настоящее время я разрабатываю собственный [Swift-to-AppleEvent bridge] (https://bitbucket.org/hhas/swiftae) как настоящую дружественную для Swift альтернативу AppleScript, с которой вы можете играть, хотя имейте в виду что моя долгосрочная поддержка для него будет зависеть от того, сколько поддержки он может привлечь среди разработчиков Apple/Swift. – foo

+0

Что касается «настоятельно рекомендуется использовать« AppleScriptObjC », что бы выглядела бы реализация Swift' AppleScriptObjC' selectedFinderFiles? Возможно ли реализовать быструю реализацию «AppleScriptObjC» без добавления кода Objective-C или AppleScript? –