解码后JSON数据为零

Posted

技术标签:

【中文标题】解码后JSON数据为零【英文标题】:JSON Data is nil after decoding 【发布时间】:2015-09-24 12:52:57 【问题描述】:

伙计们,我收到了对我进行的 api 调用的响应。它返回整个响应,我将它提供给类似的方法。

completionHandler(response: response, error: nil)

然后通过做

print(response.description)

结果是我得到了标题状态码等。

URL:
removed

Status Code:
200

Headers:
Keep-Alive: timeout=5, max=99
Content-Length: 2423
Server: Apache/2.4.10 (Debian)
SessionID: removed
Content-Type: application/json
Date: Thu, 24 Sep 2015 12:50:14 GMT
Connection: Keep-Alive
Cache-Control: no-cache

Payload:
["id":148,"name":"Amsterdam","avatar":"removed","cover":"removed"]

我最感兴趣的部分是这部分

Payload:
["id":148,"name":"Amsterdam","avatar":"removed","cover":"removed"]

不知何故,我无法提取该 json 对象数组。谁能帮我解决这个问题?

编辑:添加了我接收响应并将其传递的方法

func requestObj(url: Routes, params: Dictionary<String, String>?, completionHandler: (response: Response?, error: NSError?) -> ())

    self.requestConfig(completionHandler:  () -> () in
        if let req = NSMutableURLRequest(urlString: self.config!.api!.baseUrl! + "/v2" + url.rawValue) 
            do 
                req.addValue(String(self.config!.api!.token!), forHTTPHeaderField: "Token")
                req.addValue(String(self.sessionID), forHTTPHeaderField: "SessionID")
                let opt = HTTP(req)
                opt.start  response in
                    if let err = response.error 
                        print("error: \(err.localizedDescription)")
                        print("opt finished with error info: \(response.description)")
                        completionHandler(response: nil, error: nil)
                    
                    completionHandler(response: response, error: nil)
                    //print("data is: \(response.data)") access the response of the data with response.data
                
            
        
    ) // request a valid config before doing anything

这是用

调用的
    adapter.requestObj(APIAdapter.Routes.getMunicipalities, params: nil, completionHandler: (
        response, error) in
        if let response = response 
            print(response.description)
        
    )

【问题讨论】:

response的类型是什么?它不包含表示响应正文的属性吗? 您应该在响应数据变量中获取 JSON 数据。请粘贴更多代码,以便问题变得更清晰。在 NSURLConnection 的情况下,您会在连接委托方法 didReceiveData:. 中获得响应数据 @EricD。响应是响应类型。该属性是(我假设)“有效负载:”对吗? 我不知道任何Response 类型。是从图书馆来的吗?它是您代码中其他地方的自定义类型吗?它来自哪里? 啊,是的,对不起,我正在使用github.com/daltoniam/SwiftHTTP 库为我处理 http 请求。 @EricD。它基本上是一个 http 响应 【参考方案1】:

对于SwiftHTTP,您可以通过以下方式获取响应正文:

response.data

【讨论】:

也试过了。当我回馈它时,它会返回 NSData。然后我想把它作为 JSON 保存在一个领域对象中(参见 realm.io ),而不是为 SwiftHTTP 制作的 JSONJoy 对象。这就是问题发生的地方。 您的问题是如何从响应对象中获取数据。我相信我已经回答了这个问题。现在,如果您有一个新请求,例如如何从数据中获取 json 对象,然后使用 Realm 保存它,那将是一个完全不同的问题。 :) 怎么会......当我这样做时 let jsonResult = try NSJSONSerialization.JSONObjectWithData(response, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary print(jsonResult) catch let error as NSError print(error) 我得到 nil 吗? (即使不使用领域或任何东西) 我告诉过你使用response.data,但你仍在使用response,那是你的错误。 不,我将方法更改为返回 response.data completionHandler(response: response.data, error: nil),它是 NSData 作为该方法的返回值。所以那部分的响应是 NSData【参考方案2】:

您是否已经尝试过使用“SwiftyJson”,您可以将数据保存在 JSON 对象中,然后将数据作为字典访问这是我处理数据的方式

import Alamofire
import SwiftyJSON
 func RequestImages()

    Alamofire.request(.GET, "https://api.500px.com/v1/photos",parameters:["consumer_key":"gRU4LletUCA9RiOQhaJBAt62UyRRYUE6vsIcC7fO"])
        .responseJSON  _,_,result in
            switch result 
            case .Success(let data):
                let json = JSON(data)
                debugPrint(data)
                self.Photos = self.ParseJSON(json)
                self.performSegueWithIdentifier("ToCollection", sender: self)
            case .Failure(_, let error):
                print("Request failed with error: \(error)")
                   
    

这里有一些代码,我使用了一个名为 Alamofire 的库,我在其中检索 JSON 响应,然后如果找到数据,我将数据保存在 SwiftyJSON 库提供的 JSON 对象中

let json = JSON(data)

然后我有一个名为“照片”的“图像”模式的集合,我通过解析 JSON 数据来填充这个集合,如下所示

 func ParseJSON(json:JSON)->[Image]

    //Get Image_URL
    var pictures = [Image]()
    for result in json["photos"].arrayValue
    
        pictures.append(Image(url: result["image_url"].stringValue, name: result["name"].stringValue, news: result["description"].stringValue))
       
    debugPrint(pictures)
    return pictures


希望我的实现对您有所帮助!

【讨论】:

【参考方案3】:

试试这个:-

override func viewDidLoad() 
    super.viewDidLoad()

  get_data_from_url("http://yourURL")


 


func get_data_from_url(url:String) 

    let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
    Id = label1.text //your request parameters 
    JId = label2.text //your request parameters 

    var post:NSString = "uid=\(Id)&jid=\(JId)"
    //NSLog("PostData: %@",post);

    var url:NSURL = NSURL(string: url)!

    var postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!

    var postLength:NSString = String( postData.length )

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


    var reponseError: NSError?
    var response: NSURLResponse?

    var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)


    if  urlData != nil && reponseError == nil 

        let res = response as! NSHTTPURLResponse!;

        //NSLog("Response code: %ld", res.statusCode);

        if (res.statusCode >= 200 && res.statusCode < 300) 

            var responseData:NSString  = NSString(data:urlData!, encoding:NSUTF8StringEncoding)!

            NSLog("Response ==> %@", responseData)

            if Id != nil 

            extract_json(urlData!)

            



         else 


            var alertView:UIAlertView = UIAlertView()
            alertView.title = "Sign in Failed!"
            alertView.message = "Connection Failed"
            alertView.delegate = self
            alertView.addButtonWithTitle("OK")
            alertView.show()

        


     else 


        var alertView:UIAlertView = UIAlertView()
        alertView.title = "Sign in Failed!"
        alertView.message = "Connection Failure"
        if let error = reponseError 
            alertView.message = (error.localizedDescription)
        
        alertView.delegate = self
        alertView.addButtonWithTitle("OK")
        alertView.show()

    



  func extract_json(data:NSData)  

    var error: NSError?

    let jsonData:NSArray = NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers , error: &error) as! NSArray


    let Id_temp: AnyObject? = ((jsonData)[0] as! NSDictionary)["id"]
    let Name_temp: AnyObject? = ((jsonData)[0] as! NSDictionary)["name"]

首先访问此站点并验证您的 URL

https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo?utm_source=chrome-app-launcher-info-dialog(谷歌扩展) 然后根据您的设置替换以下给定值:-

  request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
  request.setValue("*/*", forHTTPHeaderField: "Accept")

【讨论】:

【参考方案4】:

试试这个:

NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:response options:0 error:&error];

然后你可以通过[jsonDictionary objectForKey:@""] 来检索值。

这是 Objective C,但我确信它在 Swift 中一定是相似的。

【讨论】:

我通过返回 response.data 进行了尝试,但这给了我 nil :/ @Reshad 你检查error 引用是否有值吗? @CraigOtis 是的。我尝试使用新的 Do Catch 块,它没有输入错误。相反,它打印了 Do 的值,但它是 nil 你能打印你得到的标题吗?

以上是关于解码后JSON数据为零的主要内容,如果未能解决你的问题,请参考以下文章

用 Go 解析复杂 JSON 的思路

swifty Json 解析数据显示我为零?

使用 Struct 解码 JSON 响应的 Alamofire 错误

解析后JSON结果为零

管理错误时,带有 JSON 数据参数的 NSURLSession 崩溃为零

2018-04-09(JSON.parse和JSON.stringify的编码解码)