NSNotificationCenter问题:抛出致命错误

时间:2016-05-12 02:54:31

标签: ios authentication if-statement swift2 instance-variables

我正在开发一个身份验证系统。目前,我可以提取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)

    }

}


}

2 个答案:

答案 0 :(得分:1)

正如丹所指出的,''之后的代码一旦网络请求完成,它将异步运行。在该代码中触发一个事件(例如,一个NSNotification),代码的其余部分可以用它来知道它是完整的。

编辑以回答更改的问题: 在设置变量之前,您仍然会发布通知。将该帖子移到' in'的末尾。块。

编辑2:关于nil错误,我认为这与您使用.string有关,请参阅this SO answer

答案 1 :(得分:0)

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

  • 处理传递数据的方式是错误的

在你的处理验证方法中,你应该这样做:

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)

         }

}

let errorMessage = dict["message"] as! Stringdict["error"]! as! Bool == true将从您的输出中移除选项

  • 处理JSON的方式不正确。根据我从其他帖子中可以理解的内容,您要查找的数据是数组形式。

您应该采取以下措施来获取密码和用户名错误的值:

 errorMessage = value["password"][0].string!
 errorMessage = value["username"][0].string!