По этому вопросу я использую упрощенную, упрощенную версию моего фактического кода.Невозможно развернуть NSError
Приложение структурировано с использованием архитектуры 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
объект, я все еще получаю эти Факультативные() скобки строк.
У кого-нибудь есть идея, почему это происходит?
спасибо.
Да, это все. Спасибо. – Isuru