3

I'm having an Applescript which gives me a result. But I am unable to unwarp the value to String so i can use it.

var set: String = "set windowTile to \"\"\n"
var tell: String = "tell application \"System Events\"\n"
var setFrontApp: String = "set frontApp to first application process whose frontmost is true\n"
var setFrontAppName: String = "set frontAppName to name of frontApp\n"
var tellProcces: String = "tell process frontAppName\n"
var tellFirst: String = "tell (1st window whose value of attribute \"AXMain\" is true)\n"
var setWindowTitle: String = "set windowTitle to value of attribute \"AXTitle\"\n"
var endTellFirst: String = "end tell\n"
var endTellProcess: String = "end tell\n"
var endTell: String = "end tell"
var startAtLoginScript: NSAppleScript = NSAppleScript(source: set + tell + setFrontApp + setFrontAppName + tellProcces + tellFirst + setWindowTitle + endTellFirst + endTellProcess + endTell)     
var scriptResult:NSAppleEventDescriptor = startAtLoginScript.executeAndReturnError(errorInfo)!

NSLog ("%@",  scriptResult)

The NSLog looks like this:

2015-03-14 15:15:14.001 test[7315:161881] 
<NSAppleEventDescriptor:'utxt'("test.swift")>

The actual Result is a String "test.swift". How can I unwrap/parse this result?

I tried adding this:

var number:Int = 1
let result = scriptResult.descriptorAtIndex(number)

Also i tried using the method descriptorForKeyword(<#keyword: AEKeyword#>) but i do not know hot to set AEKeyword.

Thomas Tempelmann
  • 11,045
  • 8
  • 74
  • 149
Silve2611
  • 2,198
  • 2
  • 34
  • 55

2 Answers2

2

You can use if…let syntax to simultaneously check the result for nil and unwrap it if it has a value.

descriptorAtIndex won’t get what you want because the descriptor doesn’t contain a utxt entry – it is a utxt entry (you can see this by printing out result.descriptorType which will give you the four-characted code for 'utxt'). So stringValue should get you the plain string value, but it’s an optional so you can unwrap in the same let.

If you only want to output the data, println will do it without the timestamp etc. (in fact NSLog also logs an error to the console which you probably don’t want)

import Foundation

let script = "\n".join([
  "set windowTile to \"\"",
  "tell application \"System Events\"",
    "set frontApp to first application process whose frontmost is true",
    "set frontAppName to name of frontApp",
    "tell process frontAppName",
      "tell (1st window whose value of attribute \"AXMain\" is true)",
        "set windowTitle to value of attribute \"AXTitle\"",
      "end tell",
    "end tell",
  "end tell",
])

var errorInfo: NSDictionary?

if let script = NSAppleScript(source: script),
   let result = script.executeAndReturnError(&errorInfo),
   let text = result.stringValue {
    println(text)
}
else if let error = errorInfo {
    println(error)
}
else {
    println("Unexpected error while executing script")
}
Airspeed Velocity
  • 40,491
  • 8
  • 113
  • 118
1

scriptResult.stringValue(), maybe? (I don't use Swift much.)

Wevah
  • 28,182
  • 7
  • 83
  • 72
  • this is not working as it is returning too much `.2015-03-14 15:51:43.143 test[8272:175567] test.swift.` i only need the last part – Silve2611 Mar 14 '15 at 14:52
  • That's just logging detritus. – Wevah Mar 14 '15 at 15:42
  • OP is correct. `-stringValue` will coerce the AE descriptor to `typeUnicodeText` then unpack it as an `NSString`, or `nil` if it can't coerce the descriptor to that type. As to the noise, I think you're having a reading problem: the datestamp, etc. is included by `NSLog` when it writes your message string to stderr; it's not part of your result. (Tip: `CFShow((CFStringRef)[NSString stringWithFormat:...])` is a less noisy option.) – foo Mar 14 '15 at 15:48
  • 1
    @Wevah this does it, except `stringValue` is a property so no need for `()`, and it’s an optional string so wants unwrapping. – Airspeed Velocity Mar 14 '15 at 17:37
  • Like I said, I don't use Swift much. :p – Wevah Mar 15 '15 at 09:52