展开可选值时意外发现 nil(AppleScript 结果)
Unexpectedly found nil while unwrapping an Optional value (AppleScript result)
我正在尝试在 Swift 2 中制作一个程序,该程序运行并获取 AppleScript 脚本的结果。
这是我的代码:
import Foundation
func runAppleScript(script:String) -> String
{
let errorInfo = AutoreleasingUnsafeMutablePointer<NSDictionary?>()
let startAtLoginScript: NSAppleScript = NSAppleScript(source: script)!
let theDiscriptor:NSAppleEventDescriptor = startAtLoginScript.executeAndReturnError(errorInfo)
let theResult:String = theDiscriptor.stringValue! //This is whats causing the error
return theResult
}
let scriptResult = runAppleScript("tell app \"Spotify\" to playpause")
NSLog("\(scriptResult)")
问题是程序崩溃并输出:
fatal error: unexpectedly found nil while unwrapping an Optional value
在控制台中。我也试过 if let else
,但这也不起作用。我该如何解决这个问题?
这是使用 swift 语言使用 OS X 命令行模板测试的。
实际上错误可能来自 NSAppleScript(source: script)!
所以 正确的 解决方案是 return 一个可选字符串而不是使用强制展开 完全:
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")
}
如果您希望在失败时使用默认值而不是 nil,则无需 return 可选:
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 错误处理系统,none 您在 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)
}
我已经修复了我自己的代码。
import Foundation
func runAppleScript(script:String) -> String
{
let theResult:String
let errorInfo = AutoreleasingUnsafeMutablePointer<NSDictionary?>()
let startAtLoginScript: NSAppleScript = NSAppleScript(source: script)!
let theDiscriptor:NSAppleEventDescriptor = startAtLoginScript.executeAndReturnError(errorInfo)
if let _ = theDiscriptor.stringValue
{
theResult = theDiscriptor.stringValue!
} else {
theResult = ""
}
return theResult
}
let scriptResult = runAppleScript("")
我必须做的是在展开之前检查 theDiscriptor.stringValue 是否有值。我得到的错误是因为我试图在打开它之后检查它的值。只需删除支票上的 !
即可解决我的问题。
编辑
在 Swift 3 中尝试此操作时,代码 let errorInfo = AutoreleasingUnsafeMutablePointer<NSDictionary?>()
不再有效。为了解决这个问题,我更新了代码。
func runAppleScript(script:String) -> String?
{
var theResult:String?
let startAtLoginScript: NSAppleScript = NSAppleScript(source: script)!
var errorInfo:NSDictionary? = nil
let theDiscriptor:NSAppleEventDescriptor = startAtLoginScript.executeAndReturnError(&errorInfo)
if let _ = theDiscriptor.stringValue {theResult = theDiscriptor.stringValue!}
return theResult
}
奖金
通过返回一个可选字符串,它允许您检查代码是否返回了一个值。
示例:
老办法
let output = runAppleScript("script")
if output != ""
{
//Script returned date
} else {
//Script did not return data
}
新方式
if let output = runAppleScript("script")
{
//Script returned data
} else {
//Script did not return data
}
我正在尝试在 Swift 2 中制作一个程序,该程序运行并获取 AppleScript 脚本的结果。
这是我的代码:
import Foundation
func runAppleScript(script:String) -> String
{
let errorInfo = AutoreleasingUnsafeMutablePointer<NSDictionary?>()
let startAtLoginScript: NSAppleScript = NSAppleScript(source: script)!
let theDiscriptor:NSAppleEventDescriptor = startAtLoginScript.executeAndReturnError(errorInfo)
let theResult:String = theDiscriptor.stringValue! //This is whats causing the error
return theResult
}
let scriptResult = runAppleScript("tell app \"Spotify\" to playpause")
NSLog("\(scriptResult)")
问题是程序崩溃并输出:
fatal error: unexpectedly found nil while unwrapping an Optional value
在控制台中。我也试过 if let else
,但这也不起作用。我该如何解决这个问题?
这是使用 swift 语言使用 OS X 命令行模板测试的。
实际上错误可能来自 NSAppleScript(source: script)!
所以 正确的 解决方案是 return 一个可选字符串而不是使用强制展开 完全:
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")
}
如果您希望在失败时使用默认值而不是 nil,则无需 return 可选:
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 错误处理系统,none 您在 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)
}
我已经修复了我自己的代码。
import Foundation
func runAppleScript(script:String) -> String
{
let theResult:String
let errorInfo = AutoreleasingUnsafeMutablePointer<NSDictionary?>()
let startAtLoginScript: NSAppleScript = NSAppleScript(source: script)!
let theDiscriptor:NSAppleEventDescriptor = startAtLoginScript.executeAndReturnError(errorInfo)
if let _ = theDiscriptor.stringValue
{
theResult = theDiscriptor.stringValue!
} else {
theResult = ""
}
return theResult
}
let scriptResult = runAppleScript("")
我必须做的是在展开之前检查 theDiscriptor.stringValue 是否有值。我得到的错误是因为我试图在打开它之后检查它的值。只需删除支票上的 !
即可解决我的问题。
编辑
在 Swift 3 中尝试此操作时,代码 let errorInfo = AutoreleasingUnsafeMutablePointer<NSDictionary?>()
不再有效。为了解决这个问题,我更新了代码。
func runAppleScript(script:String) -> String?
{
var theResult:String?
let startAtLoginScript: NSAppleScript = NSAppleScript(source: script)!
var errorInfo:NSDictionary? = nil
let theDiscriptor:NSAppleEventDescriptor = startAtLoginScript.executeAndReturnError(&errorInfo)
if let _ = theDiscriptor.stringValue {theResult = theDiscriptor.stringValue!}
return theResult
}
奖金
通过返回一个可选字符串,它允许您检查代码是否返回了一个值。
示例:
老办法
let output = runAppleScript("script")
if output != ""
{
//Script returned date
} else {
//Script did not return data
}
新方式
if let output = runAppleScript("script")
{
//Script returned data
} else {
//Script did not return data
}