如何从复杂的JSON对象中获取值?

时间:2022-09-25 08:45:36

Is it possible that someone could show me how to get the names of these pizza places printing out? My application prints out the expected "Status Code: 200". However, my console only shows empty brackets []. I suspect that I am not pulling values from my JSON object properly.

有人能告诉我如何把这些披萨店的名字打印出来吗?我的应用程序打印出预期的“状态代码:200”。但是,我的控制台只显示空括号[]。我怀疑我没有正确地从JSON对象中提取值。

I'm using this link for my API.

我把这个链接用在我的API上。

Link For API

链接API

Question

How can I properly fetch values from my serialized JSON object?

如何正确地从序列化的JSON对象中获取值?

relevant code:

相关代码:

    // Response
    if let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode == 200, let data = data {
        print("Status Code: \(httpResponse.statusCode)")



        do {
            let json = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers)

            if let pizzaPlaces = json["response"] as? [[String: AnyObject]] {
                for place in pizzaPlaces {
                    if let name = place ["name"] as? String {
                        self.PizzaClass.append(name)
                    }
                }
            }
        } catch {
            print("Error Serializing JSON Data: \(error)")
        }
        print(self.PizzaClass)


    }
}).resume()

2 个解决方案

#1


1  

You need to cast your NSJSONSerialization.JSONObjectWithData result as a [String:AnyObject].

您需要强制执行NSJSONSerialization。JSONObjectWithData结果为[String:AnyObject]。

    let jsonObject = try NSJSONSerialization.JSONObjectWithData(returnedData, options: .MutableLeaves) as! [String: AnyObject]

Once you have that all you need to do is pay attention to what you're casting. Take the code below for an example. If we want to get our response object using jsonObject["response"] what kind of data structure do we have?

一旦你有了这些,你所需要做的就是关注你的选择。以下面的代码为例。如果我们想用jsonObject["response"]来获取我们的响应对象,我们有什么样的数据结构呢?

"response": {
        "venues": [{
            //... continues
        }]
    } 

On the left we have "response" which is a string, on the right we have {} which is an AnyObject. So we have [String: AnyObject]. You just need to think about what object your dealing with piece by piece. Below is a working example that you can just paste into your application.

左边是一个字符串,右边是一个AnyObject的{}。我们有[String: AnyObject]你只需要考虑你要处理的对象是什么。下面是一个可以直接粘贴到应用程序中的示例。

full working code:

完整的工作代码:

func getJson() {

    let request = NSMutableURLRequest(URL: NSURL(string: "https://api.foursquare.com/v2/venues/search?client_id=0F5M0EYOOFYLBXUOKTFKL5JBRZQHAQF4HEM1AG5FDX5ABRME&client_secret=FCEG5DWOASDDYII4U3AAO4DQL2O3TCN3NRZBKK01GFMVB21G&v=20130815%20&ll=29.5961,-104.2243&query=burritos")!)
    let session = NSURLSession.sharedSession()

    request.HTTPMethod = "GET"
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    let task = session.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in

        guard let testResponse = response as? NSHTTPURLResponse else {
            print("\(response)")
            return
        }

        guard let status = HTTPStatusCodes(rawValue: testResponse.statusCode) else {
            print("failed to unwrap status")
            return
        }
        print(status)

        switch status {
        case .Created:
            print("ehem")
        case .BadRequest:
            print("bad request")
        case .Ok:
            print("ok")

            guard let returnedData = data else {
                print("no data was returned")
                break
            }
            do {
                let jsonObject = try NSJSONSerialization.JSONObjectWithData(returnedData, options: .MutableLeaves) as! [String: AnyObject]

                guard let response = jsonObject["response"] as? [String: AnyObject] else { return }     
                guard let venues = response["venues"] as? [AnyObject] else { return }
                guard let location = venues[0]["location"] as? [String:AnyObject] else { return }
                guard let formattedAddress = location["formattedAddress"] else { return }

                print("response: \n\n \(response)\n------")
                print("venues : \n\n \(venues)\n-------")
                print("location : \n\n \(location)\n------")
                print("formatted address : \n \(formattedAddress)")

            } catch let error {
                print(error)
            }

            // update user interface
            dispatch_sync(dispatch_get_main_queue()) {
                print("update your interface on the main thread")
            }
        }  
    }
    task.resume()
}

place this either in its own file our outside of the class declaration,

把这个放到它自己的文件中我们的类声明之外,

  enum HTTPStatusCodes : Int {
        case Created = 202
        case Ok = 200
        case BadRequest = 404 
    }

#2


0  

Not that this was what you are looking for, but since you are new to Swift take a look at Alamofire. It handles JSON serialization for you. And when you need to chain calls PromiseKit is super slick.

这并不是你要找的,但既然你是斯威夫特的新手,那就看看阿拉莫菲尔吧。它为您处理JSON序列化。当你需要连锁呼叫时,PromiseKit是超级圆滑的。

         Alamofire.request(.GET, url).responseJSON {response in

            switch (response.result) {
            case .Success(let value):

                let pizzas = JSON(value).arrayValue

                for place in pizzaPlaces {
                   if let name = place ["name"] as? String {
                     self.PizzaClass.append(name)
                   }
                }                 

            case .Failure(let error):
                if let data = response.data, let dataString = String(data: data, encoding: NSUTF8StringEncoding) {
                    print("ERROR data: \(dataString)")
                }
                print("ERROR: \(error)")
            }
        }

#1


1  

You need to cast your NSJSONSerialization.JSONObjectWithData result as a [String:AnyObject].

您需要强制执行NSJSONSerialization。JSONObjectWithData结果为[String:AnyObject]。

    let jsonObject = try NSJSONSerialization.JSONObjectWithData(returnedData, options: .MutableLeaves) as! [String: AnyObject]

Once you have that all you need to do is pay attention to what you're casting. Take the code below for an example. If we want to get our response object using jsonObject["response"] what kind of data structure do we have?

一旦你有了这些,你所需要做的就是关注你的选择。以下面的代码为例。如果我们想用jsonObject["response"]来获取我们的响应对象,我们有什么样的数据结构呢?

"response": {
        "venues": [{
            //... continues
        }]
    } 

On the left we have "response" which is a string, on the right we have {} which is an AnyObject. So we have [String: AnyObject]. You just need to think about what object your dealing with piece by piece. Below is a working example that you can just paste into your application.

左边是一个字符串,右边是一个AnyObject的{}。我们有[String: AnyObject]你只需要考虑你要处理的对象是什么。下面是一个可以直接粘贴到应用程序中的示例。

full working code:

完整的工作代码:

func getJson() {

    let request = NSMutableURLRequest(URL: NSURL(string: "https://api.foursquare.com/v2/venues/search?client_id=0F5M0EYOOFYLBXUOKTFKL5JBRZQHAQF4HEM1AG5FDX5ABRME&client_secret=FCEG5DWOASDDYII4U3AAO4DQL2O3TCN3NRZBKK01GFMVB21G&v=20130815%20&ll=29.5961,-104.2243&query=burritos")!)
    let session = NSURLSession.sharedSession()

    request.HTTPMethod = "GET"
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    let task = session.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in

        guard let testResponse = response as? NSHTTPURLResponse else {
            print("\(response)")
            return
        }

        guard let status = HTTPStatusCodes(rawValue: testResponse.statusCode) else {
            print("failed to unwrap status")
            return
        }
        print(status)

        switch status {
        case .Created:
            print("ehem")
        case .BadRequest:
            print("bad request")
        case .Ok:
            print("ok")

            guard let returnedData = data else {
                print("no data was returned")
                break
            }
            do {
                let jsonObject = try NSJSONSerialization.JSONObjectWithData(returnedData, options: .MutableLeaves) as! [String: AnyObject]

                guard let response = jsonObject["response"] as? [String: AnyObject] else { return }     
                guard let venues = response["venues"] as? [AnyObject] else { return }
                guard let location = venues[0]["location"] as? [String:AnyObject] else { return }
                guard let formattedAddress = location["formattedAddress"] else { return }

                print("response: \n\n \(response)\n------")
                print("venues : \n\n \(venues)\n-------")
                print("location : \n\n \(location)\n------")
                print("formatted address : \n \(formattedAddress)")

            } catch let error {
                print(error)
            }

            // update user interface
            dispatch_sync(dispatch_get_main_queue()) {
                print("update your interface on the main thread")
            }
        }  
    }
    task.resume()
}

place this either in its own file our outside of the class declaration,

把这个放到它自己的文件中我们的类声明之外,

  enum HTTPStatusCodes : Int {
        case Created = 202
        case Ok = 200
        case BadRequest = 404 
    }

#2


0  

Not that this was what you are looking for, but since you are new to Swift take a look at Alamofire. It handles JSON serialization for you. And when you need to chain calls PromiseKit is super slick.

这并不是你要找的,但既然你是斯威夫特的新手,那就看看阿拉莫菲尔吧。它为您处理JSON序列化。当你需要连锁呼叫时,PromiseKit是超级圆滑的。

         Alamofire.request(.GET, url).responseJSON {response in

            switch (response.result) {
            case .Success(let value):

                let pizzas = JSON(value).arrayValue

                for place in pizzaPlaces {
                   if let name = place ["name"] as? String {
                     self.PizzaClass.append(name)
                   }
                }                 

            case .Failure(let error):
                if let data = response.data, let dataString = String(data: data, encoding: NSUTF8StringEncoding) {
                    print("ERROR data: \(dataString)")
                }
                print("ERROR: \(error)")
            }
        }