简体   繁体   English

在Swift 2的闭包内部未分配类属性

[英]Class property not assigned inside closure in Swift 2

I am having trouble assigning a value to a property inside my Swift class. 我在为Swift类中的属性分配值时遇到麻烦。 The property prints out fine inside the class but returns nil when accessed externally when calling the class method that assigns the property in the main viewController. 该属性在类内部可以正常打印,但是当调用在主viewController中分配属性的类方法时,从外部访问该属性将返回nil Here is my class definition. 这是我的班级定义。

import Foundation

class NetworkConnection {

    var jsonObj: AnyObject?

    func makeHTTPRequest(data: String, location: String, completion: (jsonData: AnyObject?, error: NSError?) -> Void){

        var jsonData: AnyObject!

        let post: NSString = "data=\(data)"
        let url = NSURL(string: location)!
        let postData = post.dataUsingEncoding(NSUTF8StringEncoding)!

        let postLength = String(postData.length)
        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "POST"
        request.HTTPBody = postData
        request.setValue(postLength, forHTTPHeaderField: "Content-Length")
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.setValue("application/json", forHTTPHeaderField: "Accept")

        let session = NSURLSession.sharedSession()

        let task = session.dataTaskWithRequest(request) { urlData, response, responseError in

            if let receiveData = urlData {

                let res = response as! NSHTTPURLResponse!

                if 200..<300 ~= res.statusCode {
                    do {
                        jsonData = try NSJSONSerialization.JSONObjectWithData(receiveData, options: NSJSONReadingOptions.init(rawValue:0))

                        completion(jsonData: jsonData, error: nil)
                    } catch let error as NSError {
                        let returnedError = NSError(domain: "validateUser", code: 3, userInfo: [
                            "title": "Made up title",
                            "message": "This is a messsage",
                            "cause": error
                            ])
                        completion(jsonData: nil, error: returnedError)
                    }
                }else{
                    let returnedError = NSError(domain: "validateUser", code: 1, userInfo: [
                        "title": "Second made up title",
                        "message": "This is another message"
                        ])
                    completion(jsonData: nil, error: returnedError)
                }
            }else{

                var userInfo: [NSObject: AnyObject] = [
                    "title": "Third made up title",
                    "message": "This is yet another message"
                ]
                if let error = responseError {
                    userInfo["message"] = error.localizedDescription
                    userInfo["cause"] = error
                }
                let returnedError = NSError(domain: "validateUser", code: 2, userInfo: userInfo)
                completion(jsonData: nil, error: returnedError)
            }


        }
        task.resume()

    }

    func validateUser(location: String, username: String, password: String) {

        let data = "&username=\(username)&password=\(password)"

        self.makeHTTPRequest(data, location: location) { jsonData, error in

            if let json = jsonData {

                self.jsonObj = json


                print(self.jsonObj)   // This shows property was assigned without errors

            }else{
                let userInfo = error!.userInfo
                let title = userInfo["title"] as! String
                let message = userInfo["message"] as! String
                print(title)
                print(message)
            }
        }
    }
}

This is the function that I call the validatUser() method in my viewController 这是我在validatUser()调用validatUser()方法的函数

@IBAction func login(sender: AnyObject) {

        let service = NetworkConnection()
        service.validateUser("http://myPhpServiceLink.com/mobile.login.php", username: usernameField.text!, password: passwordField.text!)

        if let serviceObj = service.jsonObj {

            print("success loading object \(serviceObj)")

        } else {

            print("error loading object from call \(service.jsonObj)")

        }
}

Here is the JSON data to be returned by PHP. 这是PHP要返回的JSON数据。

{"id":"1","username":"admin","message":"User is valid","error":null}

The line: print("service object = \\(self.jsonObj)") prints out the following in the console: 行: print("service object = \\(self.jsonObj)")在控制台中输出以下内容:

service object = Optional({
     error = "<null>";
     id = 1;
     message = "User is valid";
     username = admin;
})

But I get the "error loading object from call nil" from the @IBAction function. 但是我从@IBAction函数得到“从调用nil加载错误的对象”。 I've looked everywhere to find out why the property always returns nil when called externally and it is also hard to articulate my problem. 我到处寻找以找出为什么该属性在外部调用时总是返回nil ,并且也很难阐明我的问题。

I bet this is due to your http request being performed in the background. 我敢打赌这是由于您的http请求是在后台执行的。
if let serviceObj = service.jsonObj is being executed before your validateUser method is completed. if let serviceObj = service.jsonObj在您的validateUser方法完成之前正在执行if let serviceObj = service.jsonObj you need to rewrite `valdiateUser to take a completion handler. 您需要重写`valdiateUser以获取完成处理程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM