Ios 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

我正在研究一个认证系统。目前,我可以提取API数据并对用户进行身份验证。我使用NSNotificationCenter字典存储我的值,我可以打印出字符串消息,但我的布尔值返回可选值。此外,我也不确定在使用完观察者后应将其移除到何处。我应该如何着手实施它

接收用户输入的代码

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有关,请参见

没有收到所需布尔结果的原因有两个:

  • 处理传递的数据的方式是错误的
在handlingAuthentication方法中,您应该执行以下操作:

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)。如何从中获取布尔变量