На самом деле ошибка может исходить от NSAppleScript(source: script)!
поэтому правильного решения вернуть необязательную строку, а не использовать силу разворачивания на всех:
func runAppleScript(script:String) -> String? {
let errorInfo: AutoreleasingUnsafeMutablePointer<NSDictionary?> = nil
let startAtLoginScript = NSAppleScript(source: script)
let theDescriptor = startAtLoginScript?.executeAndReturnError(errorInfo)
return theDescriptor?.stringValue
}
if let scriptResult = runAppleScript("tell app \"Spotify\" to playpause") {
NSLog("\(scriptResult)")
} else {
print("the script execution failed")
}
Если вы предпочитаете иметь значение по умолчанию, а не ноль когда это не удается, то нет необходимости возвращать Дополнительно:
func runAppleScript(script:String) -> String {
let errorInfo: AutoreleasingUnsafeMutablePointer<NSDictionary?> = nil
let startAtLoginScript = NSAppleScript(source: script)
let theDescriptor = startAtLoginScript?.executeAndReturnError(errorInfo)
return theDescriptor?.stringValue ?? "" // if nil, returns the default ""
}
let scriptResult = runAppleScript("tell app \"Spotify\" to playpause")
NSLog("\(scriptResult)")
что касается использования новой Swift 2 система обработки ошибок, ни один из методов, которые вы используете внутри runAppleScript
, бросает ошибки, поэтому он будет работать только в том случае, если вы используете собственный тип ошибки и сами бросаете ошибки. Пример:
enum MyAppleScriptError: ErrorType {
case ExecutingScriptFailed
case GettingStringValueFailed
}
func runAppleScript(script:String) throws -> String {
let errorInfo: AutoreleasingUnsafeMutablePointer<NSDictionary?> = nil
let startAtLoginScript = NSAppleScript(source: script)
guard let theDescriptor = startAtLoginScript?.executeAndReturnError(errorInfo) else {
throw MyAppleScriptError.ExecutingScriptFailed
}
guard let value = theDescriptor.stringValue else {
throw MyAppleScriptError.GettingStringValueFailed
}
return value
}
do {
let scriptResult = try runAppleScript("tell app \"Spotify\" to playpause")
NSLog("\(scriptResult)")
} catch {
print(error)
}
Swift 3
Та же самая идея, но некоторые детали реализации различны.
func runAppleScript(_ script:String) -> String? {
let errorInfo: AutoreleasingUnsafeMutablePointer<NSDictionary?>? = nil
if let startAtLoginScript = NSAppleScript(source: script) {
let theDescriptor = startAtLoginScript.executeAndReturnError(errorInfo)
return theDescriptor.stringValue
}
return nil
}
if let scriptResult = runAppleScript("tell app \"Spotify\" to playpause") {
NSLog("\(scriptResult)")
} else {
print("no return value")
}
И с обработкой ошибок:
enum MyAppleScriptError: ErrorProtocol {
case ExecutingScriptFailed
case GettingStringValueFailed
}
func runAppleScript(_ script:String) throws -> String {
let errorInfo: AutoreleasingUnsafeMutablePointer<NSDictionary?>? = nil
let startAtLoginScript = NSAppleScript(source: script)
guard let theDescriptor = startAtLoginScript?.executeAndReturnError(errorInfo) else {
throw MyAppleScriptError.ExecutingScriptFailed
}
guard let value = theDescriptor.stringValue else {
throw MyAppleScriptError.GettingStringValueFailed
}
return value
}
do {
let scriptResult = try runAppleScript("tell app \"Spotify\" to playpause")
NSLog("\(scriptResult)")
} catch {
print(error)
}
Что линия это сбой на? Я мог видеть, что nslog сбой, если не было скриптаResult – bolnad
@bolnad Думайте, что это была строка 'let'. Будет проверять завтра. (GMT) У меня нет доступа к моему компьютеру. – iProgram
@bolnad Ошибка указана из строки 'let theResult: String = theDiscriptor.stringValue!' – iProgram