Convert list of AppleScript strings to a Swift array

627 Views Asked by At

I have a complicated AppleScript that returns a list of strings that I need to access from Swift. I've boiled it down to a simple example and I just can't figure out how to map the AppleScript strings to an array of Swift strings.

let listOfStringsScript = """
                          set listOfStrings to { "one", "two", "three" }
                          """

 if let scriptObject = NSAppleScript(source: listOfStringsScript) {
    var errorDict: NSDictionary? = nil
    let resultDescriptor = scriptObject.executeAndReturnError(&errorDict)

    if errorDict == nil {
      // TODO: convert the resultDescriptor (NSAppleEventDescriptor) into an array of strings
      print(resultDescriptor)
      // OUTPUT: <NSAppleEventDescriptor: [ 'utxt'("one"), 'utxt'("two"), 'utxt'("three") ]>
    }
}
2

There are 2 best solutions below

3
RobertJoseph On

Answer with help from @Alexander and @MartinR:

extension NSAppleEventDescriptor {

  func toStringArray() -> [String] {
    guard let listDescriptor = self.coerce(toDescriptorType: typeAEList) else {
      return []
    }

    return (0..<listDescriptor.numberOfItems)
      .compactMap { listDescriptor.atIndex($0 + 1)?.stringValue }
  }

}

...

let resultDescriptor = scriptObject.executeAndReturnError(&errorDict)
let subjectLines = resultDescriptor.toStringArray()
0
tyirvine On

An alternative is to gather the Apple Script result as lines of text separated by line breaks and then parse the string in Swift.

So break up the Apple Script result using

set AppleScript's text item delimiters to linefeed

Then simply parse

let selectedItems = scriptExecuted.stringValue!
let selectedItemsFiltered = selectedItems.components(separatedBy: .newlines)

.components returns a string array