对于这个问题,我使用的是实际代码的简化版本。
该应用程序使用MVVM架构构建。说那是一个登录屏幕。有3个文件。
ApiClient
文件与服务器通信并获得响应。如果输入的用户名和密码匹配,则调用success
闭包。匹配失败,我在NSError
闭包中传递了自定义创建的failure
对象。
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
,我调用login()
中的LoginViewModel
功能。响应将返回到视图模型,并调用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()
}
}
}
}
逻辑正常。登录尝试失败时出现问题。假设我输入了错误的用户名或密码,它会返回我在login()
文件的ApiClient
函数中创建的自定义错误对象。我从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()括号。
任何人都知道为什么会这样?
谢谢。
答案 0 :(得分:2)
您的error
var已经解开了。问题是字符串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()
}