Ios NSNotificationCenter问题:引发致命错误
我正在研究一个认证系统。目前,我可以提取API数据并对用户进行身份验证。我使用NSNotificationCenter字典存储我的值,我可以打印出字符串消息,但我的布尔值返回可选值。此外,我也不确定在使用完观察者后应将其移除到何处。我应该如何着手实施它 接收用户输入的代码Ios NSNotificationCenter问题:引发致命错误,ios,authentication,if-statement,swift2,instance-variables,Ios,Authentication,If Statement,Swift2,Instance Variables,我正在研究一个认证系统。目前,我可以提取API数据并对用户进行身份验证。我使用NSNotificationCenter字典存储我的值,我可以打印出字符串消息,但我的布尔值返回可选值。此外,我也不确定在使用完观察者后应将其移除到何处。我应该如何着手实施它 接收用户输入的代码 import UIKit class LoginViewController: UIViewController { @IBOutlet weak var usernameField: UITextField! @IB
import UIKit
class LoginViewController: UIViewController {
@IBOutlet weak var usernameField: UITextField!
@IBOutlet weak var pwdField: UITextField!
@IBAction func loginBtn(sender: AnyObject) {
let loginobj = Login(userName : self.usernameField.text!, passWord : self.pwdField.text!)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(LoginViewController.handlingAuthentication(_:)), name:"errorPresent", object: nil)
loginobj.getRequest()
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func handlingAuthentication(notification: NSNotification) {
let dict = notification.object as! NSDictionary
let errorFound = dict["error"]
let errorMessage = dict["message"]
print(errorFound)
if((errorFound?.string)! == true){
//initialize Alert Controller
let alertController = UIAlertController(title: "Authentication error", message: errorMessage?.string, preferredStyle: .Alert)
//Initialize Actions
let okAction = UIAlertAction(title: "Ok", style: .Default){
(action) -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
}
//Add Actions
alertController.addAction(okAction)
//Present Alert Controller
self.presentViewController(alertController, animated: true, completion: nil)
}
else
{
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isUserLoggedIn")
NSUserDefaults.standardUserDefaults().synchronize()
self.dismissViewControllerAnimated(true, completion:nil)
}
}
}
LoginViewController的代码处理数据处理
import Foundation
import Alamofire
import SwiftyJSON
import RealmSwift
class Login {
init(userName: String, passWord: String) {
Data.sharedInstance.userName = userName
Data.sharedInstance.passWord = passWord
}
// call this method to login
func getRequest() {
Alamofire.request(.POST, Data.todoEndpoint, parameters: ["username": Data.sharedInstance.userName!, "password": Data.sharedInstance.passWord!])
.responseJSON { response in
var errorFound = Bool()
var errorMessage = String()
if let result = response.result.value
{
let value = JSON(result)
var outcome = String()
//No username
if value["password"] == nil && value["message"] == nil && value["name"] == nil
{
errorFound = true
outcome = "No username: \(value)"
errorMessage = outcome
}
//No password
else if value["username"] == nil && value["message"] == nil
{
errorFound = true
outcome = "No password: \(value)"
errorMessage = outcome
}
//No password/ username
else if value["username"] == nil && value["password"] == nil && value["message"] != nil
{
outcome = "Incorrect cred: \(value)"
errorFound = true
errorMessage = outcome
}
//success
else if value["username"] != nil && value["password"] == nil && value["message"] == nil
{
errorFound = false
if let api_key = value["api_token"].string
{
print("The token is " + api_key)
}
else
{
print("error parsing api token")
}
//pass data to Users class
_ = Users.init(Name: value["name"].string, Email: value["email"].string, Id: value["id"].int, ProfilePicture: value["profile_picture"].string, Username: value["username"].string)
NSNotificationCenter.defaultCenter().removeObserver(self, name: "errorPresent", object: nil)
}
else
{
errorFound = true
outcome = "No password and username: \(value)"
errorMessage = outcome
}
}
else
{
print("JSON data is nil.")
}
let errorDict = ["error": errorFound, "message": errorMessage]
NSNotificationCenter.defaultCenter().postNotificationName("errorPresent", object:errorDict)
}
}
}
正如Dan指出的,“in”之后的代码将在网络请求完成后异步运行。在该代码中触发一个事件(例如NSNotification),您的其他代码可以使用该事件来知道它已完成 编辑以回答修改后的问题: 在设置变量之前,您仍在发布通知。把那根柱子移到“in”块的末尾
编辑2:关于nil错误,我认为这与使用.string有关,请参见没有收到所需布尔结果的原因有两个:
- 处理传递的数据的方式是错误的
func handlingAuthentication(notification: NSNotification) {
let dict = notification.object as! NSDictionary
if dict["error"]! as! Bool == true {
let errorMessage = dict["message"] as! String
//initialize Alert Controller
let alertController = UIAlertController(title: "Authentication error", message: errorMessage, preferredStyle: .Alert)
//Initialize Actions
let okAction = UIAlertAction(title: "Ok", style: .Default){
(action) -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
}
//Add Actions
alertController.addAction(okAction)
//Present Alert Controller
self.presentViewController(alertController, animated: true, completion: nil)
}
else
{
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isUserLoggedIn")
NSUserDefaults.standardUserDefaults().synchronize()
self.dismissViewControllerAnimated(true, completion:nil)
}
}
其中让errorMessage=dict[“message”]as!字符串
和dict[“错误”]!作为!Bool==true
将从输出中删除选项
- 处理JSON的方式不正确。从你的其他帖子中我可以了解到,你正在寻找的数据是以数组的形式存在的李>
errorMessage = value["password"][0].string!
errorMessage = value["username"][0].string!
网络是异步的。您正在检查网络呼叫的结果,但它还没有完成运行。@dan我应该怎么做才能让网络呼叫首先完成运行?您好@Ali我已尝试按照我的回答更新它,但仍然没有更新working@noobdev你好您正在设置全局设置之前发布通知。设置所有适当的全局变量,然后发布通知。在调用getRequest之前也要注册通知-这可能不是这里的问题,但以后可能会导致问题。一般来说,您需要了解多线程应用程序以及如何在线程之间进行通信。我已经按照您的建议更新了代码,但它仍然不起作用。还有什么我可以试着解决的吗it@noobdev你应该问一个新问题,而不是改变原来的问题。不过,这次我会更新我的答案。啊,我明白了,我的错,我对这个还是很陌生的。我在LoginViewController中获得了errorFound变量的可选(0)。如何从中获取布尔变量