无法解开 NSError
Posted
技术标签:
【中文标题】无法解开 NSError【英文标题】:Cannot unwrap NSError 【发布时间】:2014-12-12 16:24:52 【问题描述】:对于这个问题,我使用的是实际代码的精简版。
应用程序使用 MVVM 架构构建。假设有一个登录屏幕。有 3 个文件。
ApiClient
文件与服务器通信并获得响应。如果输入的用户名和密码匹配,它会调用success
闭包。如果匹配失败,我将在 failure
闭包中传递自定义创建的 NSError
对象。
ApiClient.swift
import Foundation
public class ApiClient
public func login(#username: String, password: String, success: (data: AnyObject!) -> Void, failure: (error: NSError) -> Void)
if username == "isuru" && password == "123"
let jsonResponse = "Login Successful"
let data = jsonResponse.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
success(data: data!)
else
let userInfo = [
NSLocalizedDescriptionKey: NSLocalizedString("Login Unsuccessful", comment: ""),
NSLocalizedFailureReasonErrorKey: NSLocalizedString("Wrong Email or Password", comment: ""),
NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString("Please Try Again", comment: "")]
let error = NSError(domain: "AppErrorDomain", code: 1200, userInfo: userInfo)
failure(error: error)
LoginViewModel
充当LoginViewController
和ApiClient
之间的中间人。
LoginViewModel.swift
import Foundation
protocol LoginDelegate
func loginCallFinished(status: Bool, error: NSError?)
class LoginViewModel
private let api = ApiClient()
var delegate: LoginDelegate?
init()
func login(#username: String, password: String)
api.login(username: username, password: password, success: (data) -> Void in
if let delegate = self.delegate
delegate.loginCallFinished(true, error: nil)
else
fatalError("Have you set the LoginDelegate?")
) (error) -> Void in
if let delegate = self.delegate
delegate.loginCallFinished(false, error: error)
else
fatalError("Have you set the LoginDelegate?")
从LoginViewController
,我调用LoginViewModel
中的login()
函数。响应返回给视图模型并调用LoginDelegate
的函数loginCallFinished()
并相应地传递参数值。
LoginViewController.swift
import UIKit
class LoginViewController: UIViewController, LoginDelegate
private let loginViewModel = LoginViewModel()
override func viewDidLoad()
super.viewDidLoad()
loginViewModel.delegate = self
loginViewModel.login(username: "isuru", password: "12")
// MARK: - LoginDelegate
func loginCallFinished(status: Bool, error: NSError?)
if status
println("Login Successful!")
else
if let error = error
let alert = UIAlertView(title: error.localizedDescription, message: "\(error.localizedFailureReason)\n\(error.localizedRecoverySuggestion)", delegate: nil, cancelButtonTitle: "OK")
alert.show()
逻辑工作正常。登录尝试失败时会出现我的问题。假设我输入了错误的用户名或密码,它会返回我在ApiClient
文件的login()
函数中创建的自定义错误对象。我从LoginViewController
检索它并在UIAlertView
中显示错误。
if let error = error
let alert = UIAlertView(title: error.localizedDescription, message: "\(error.localizedFailureReason)\n\(error.localizedRecoverySuggestion)", delegate: nil, cancelButtonTitle: "OK")
alert.show()
但这就是我看到的。
即使我解开 error
对象,我仍然会在字符串周围得到那些 Optional() 括号。
有人知道为什么会这样吗?
谢谢。
【问题讨论】:
【参考方案1】:您的 error
变量已解包。问题是字符串error.localizedFailureReason
和error.localizedRecoverySuggestion
没有展开。要么为它们添加一个额外的 if-let 层,要么通过像这样打印显式地打开它们:
if let error = error
let alert = UIAlertView(title: error.localizedDescription, message: "\(error.localizedFailureReason!)\n\(error.localizedRecoverySuggestion!)", delegate: nil, cancelButtonTitle: "OK")
alert.show()
【讨论】:
是的,就是这样。谢谢。以上是关于无法解开 NSError的主要内容,如果未能解决你的问题,请参考以下文章
无法转换类型的值'(数据:CMAccelerometerData!,错误:NSError!)
无法使用类型为 (('WeatherResponse?, NSError?) -> Void 的参数列表调用“responseObject”
在 Swift 3 中无法转换 (NSError)-> Void
无法将类型“([AnyObject]!,NSError!)-> Void”的值转换为期望参数类型“CLGeocodeCompletionHandler”
无法将类型 (PFUser!, NSError) void 的值转换为预期的参数类型 PFUserResultBlock