简体   繁体   中英

JSON parsed data not being called? Swift

I have parsed my data from the API but when I try to set some values from the parsed NSDictionary data , the println statement doesn't get called. It happens in the dictionary with the "user" key where I try to set the first name and last name of the student.

func getUserData(hostViewController: UIViewController ) {
        if self.userID == nil{
            println("User ID is nil")
        }
        else {
        var key = self.userID
        let urlString = UdacityClient.Constants.BaseURLSecure + "/users" + "/\(key)"
        println(urlString)
        let url = NSURL(string: urlString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)
        let request = NSMutableURLRequest(URL: url!)


        let task = session.dataTaskWithRequest(request) {data, response, error in
            if error != nil {
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    println(error)
                    let alertController = UIAlertController(title: "Oh no", message: "Error in User Data", preferredStyle: UIAlertControllerStyle.Alert)

                    let cancelAction = UIAlertAction(title: "Retry", style: UIAlertActionStyle.Default, handler: { (alert) -> Void in
                        hostViewController.dismissViewControllerAnimated(true, completion: nil)
                    })
                    alertController.addAction(cancelAction)

                    hostViewController.presentViewController(alertController, animated: true, completion: nil)
                })

                println("Error in User Data")

            }  else {
                let newData = data.subdataWithRange(NSMakeRange(5, data.length - 5))
                var parsingError: NSError? = nil
                let parsedResult = NSJSONSerialization.JSONObjectWithData(newData, options: NSJSONReadingOptions.AllowFragments, error: &parsingError) as! NSDictionary


                if let userDictionary = parsedResult["user"] as? [String: AnyObject] {
                    if let firstName = userDictionary["first_name"] as? String {
                        self.firstName = firstName
                        println("This is not printing ")
                        println(firstName)
                    }
                }

                if let userDictionary = parsedResult["user"] as? [String: AnyObject] {
                    if let lastName = userDictionary["last_name"] as? String {
                        self.lastName = lastName
                        println("This is not printing also")
                        println(lastName)
                    }
                }

                if let err = parsingError {
                    dispatch_async(dispatch_get_main_queue(),{ () -> Void in
                        println(err)
                        let alertController = UIAlertController(title: "Oh no", message: "Error in Parsing User Data from Udacity", preferredStyle: UIAlertControllerStyle.Alert)

                        let cancelAction = UIAlertAction(title: "Retry", style: UIAlertActionStyle.Default, handler: { (alert) -> Void in
                            hostViewController.dismissViewControllerAnimated(true, completion: nil)
                        })
                        alertController.addAction(cancelAction)

                        hostViewController.presentViewController(alertController, animated: true, completion: nil)
                    })

                }


            }
            }


        task.resume()
        }
    }

My URL for the request :

https://www.udacity.com/api/users/Optional("3778758647")

My ResponseKeys struct :

struct JSONResponseKeys {
        //getSessionID
        static let Status = "status"
        static let Account = "account"
        static let Key = "key"
        static let Session = "session"
        static let ID = "id"

        //getUserData
        static let User = "user"
        static let FirstName = "first_name"
        static let LastName = "last_name"


    }

The fatal error while unwrapping an Optional value happens when I called the first name and last name of the student in my client below :

UdacityClient.sharedInstance().firstName!) and      UdacityClient.sharedInstance().lastName!

JSON parsed result console log :

 {
    error = "Parameter 'user_key' key contains unescaped special character '\"': 'Optional(\"3778758647\")'";
    parameter = "user_key";
    status = 400;
}

I looks like your main error is coming form the fact that userID is an optional value that needs to be unwrapped. This is why you are seeing

https://www.udacity.com/api/users/Optional("3778758647") instead of https://www.udacity.com/api/users/3778758647 and your server error says the same thing.

Try this basic outline, instead of:

if self.userID == nil {
   ...
}

you can use a guard statement to return early, like so:

guard let userID = self.userID as? String else { return }

This has the benefit of also unwrapping your value, getting rid of the "Optional()"

Another way would be to use:

if let userID = self.userID as? String {
    ...
}

Firstly, I recommend you use SwiftyJson for data parsing (and while we're on it, you can use Alamofire or even afnetworking for REST calls).

I'll give you a couple of examples, how simple it is to parse data with Swify.

This is a model for an object

public class MyObject: NSObject, JsonInitializableProtocol {
var name = ""
var value = ""
var count = 0

required public init(json:JSON) {
    name = json["Name"].stringValue ?? ""
    value = json["Value"].stringValue ?? ""
    count = json["Count"].intValue ?? 0
}

override init() {}
}

And a func that GET's NSData with AFNetworking, converts it to JSON and creates and object of the type MyObject, and passes it back via a completionBlock

func getObjWithUrl(url: String, completionHandler: (object: MyObject?, error: NSError?) -> Void) {
        manager.GET(url, parameters: nil, success: { (operation: AFHTTPRequestOperation!, data: AnyObject?) -> Void in
                let json = JSON(data : data as! NSData)
                let myObject = MyObject(json: json)
                completionHandler(myObject, nil)
            }, failure: { (operation: AFHTTPRequestOperation!, error: AnyObject?) -> Void in
                if let operationUnwrapped = operation as AFHTTPRequestOperation? {
                    var error = NSError(operation: operationUnwrapped, message: nil)
                    completionHandler(nil, wsError)
                }
            }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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