【问题标题】:How do I get values from a complex JSON object?如何从复杂的 JSON 对象中获取值?
【发布时间】:2016-04-30 10:09:04
【问题描述】:

有没有人可以告诉我如何打印出这些披萨店的名称?我的应用程序打印出预期的"Status Code: 200"。但是,我的控制台只显示空括号[]。我怀疑我没有正确地从我的 JSON 对象中提取值。

我正在将此链接用于我的 API。

Link For API

问题

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

相关代码:

    // 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()

【问题讨论】:

    标签: json swift swift2 httpresponse jsonserializer


    【解决方案1】:

    您需要将NSJSONSerialization.JSONObjectWithData 结果转换为[String:AnyObject]

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

    一旦你有了这些,你需要做的就是注意你正在投射的东西。以下面的代码为例。如果我们想使用jsonObject["response"] 获取我们的response 对象,我们有什么样的数据结构?

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

    左边是"response",它是一个字符串,右边是{},它是一个AnyObject。所以我们有[String: AnyObject]。你只需要考虑一件一件地处理什么对象。下面是一个工作示例,您可以将其粘贴到您的应用程序中。

    完整的工作代码:

    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()
    }
    

    将它放在类声明之外的自己的文件中,

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

    【讨论】:

    • 工作完美。仍然是初学者程序员和 Swift 新手。唯一要做的就是通过它并了解实际发生的事情以使其发挥作用。感谢您的宝贵时间。
    • 没问题!随着您的进行,它变得越来越容易,最终一切都开始点击。
    【解决方案2】:

    并不是说这就是你要找的东西,但是既然你是 Swift 的新手,那么看看 Alamofire。它为您处理 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)")
                }
            }
    

    【讨论】:

    • Alamofire 确实让生活变得更简单。虽然我确实建议开发人员知道如何同时做到这一点。
    • @DanBeaulieu,不确定我是否同意。我不会在 Javascript 中使用 XMLHttpRequest,因为有一些库可以为我处理这些混乱。到目前为止,我还没有放弃使用 Alamofire,如果我这样做了,我想我会坚持下去。
    • 我实际上在上课,不能使用 Alamofire,因为教授不允许。几天前,其他人也向我提到了这一点。一旦我像这样把它弄下来,我会检查一下。感谢您的帮助@Trent
    • @Trent 我们当然不必同意我的看法。我个人喜欢对事物的运作方式有一个完整的了解。我自己是一个长期的 ajax 用户,但当我的 Javascript 讲师向我们展示如何使用 XMLHttpRequest 时,我感到非常高兴。
    猜你喜欢
    • 2019-12-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 2021-05-06
    • 1970-01-01
    相关资源
    最近更新 更多