在Swift中读取JSON数据时获取nil值

时间:2017-02-17 19:59:49

标签: swift

if let postString = NSString(data:data!, encoding: NSUTF8StringEncoding) as? String {
                 guard let jsonData = postString.dataUsingEncoding(NSASCIIStringEncoding) else {
                    fatalError()
                 }

                 guard let jsonObjects =  try? NSJSONSerialization.JSONObjectWithData(jsonData,options: [])
                 ,let JSONArray = jsonObjects as? [[String: AnyObject]]
                 else {

                   fatalError()
                 }

                 print(JSONArray)

            }

在postString常量中,我得到" [{\"名称\":\" ABC \",\"年龄&#34 ; 35},{\"名称\":\" CDE \" \"年龄\" 36}]" 当我运行此代码然后fatalError()代码调用。

2 个答案:

答案 0 :(得分:1)

其他几个人已经解释了你在这种情况下做错了什么(试图在实际包含数组时将反序列化的输出转换为字典。)

从细节中退一步,当某些内容失败时,您需要将代码分成更小的部分,然后通过它追踪它以查看失败的内容。

" as?" cast说"尝试将此对象转换为其他类型。将结果包装在Optional中。"如果演员表失败,结果为零。如果成功,则optional包含新类型。

如果您将代码重写为:

let jsonObject = try NSJSONSerialization.JSONObjectWithData(data!,
  options: NSJSONReadingOptions.AllowFragments) 
guard let jsonDict = jsonObject as [String: Any] else {
  print("Cast failed")
  return
}

然后打印声明会触发,你知道演员阵容是问题所在。

编辑:

我刚注意到您的JSON数据包含[String: Int]类型的字典数组。在Swift中Int s不是对象类型,因此您需要将结果转换为[[String:Any]],而不是[[String:AnyObject]]。我已修复上面的代码。

我在游乐场写了下面的代码并且它有效:

let jsonString = "[{\"Name\":\"ABC\",\"Age\":35},{\"surveyName\":\"CDE\",\"Age\":36}]"
guard let jsonData = jsonString.data(using: .ascii) else {
  fatalError()
}
guard let jsonObjects = try? JSONSerialization.jsonObject(with: jsonData, options: []),
let JSONArray = jsonObjects as? [[String: Any]]
else {
  fatalError()
}

print(String(describing:  jsonObjects))

它给出了输出:

(
        {
        Age = 35;
        Name = ABC;
    },
        {
        Age = 36;
        surveyName = CDE;
    }
)

这就是我所期望的。

编辑#2:

实际上,在进一步调查时,我很难理解为什么你的代码不起作用。我刚测试过它,而as [[String: AnyObject]]正常。事实证明,在Swift 3中,如果你将Int投射到AnyObject并且你已经包含了基础(或UIKit),那么它会被静默转换为NSNumber,这是一个对象类型。

如果需要帮助调试它,您需要显示实际的JSON数据和将其转换为对象的代码。

编辑#3:

以下是我在Swift 2.3中编写和测试的代码:

func parseJSONTest() {
  let jsonString = "[{\"Name\":\"ABC\",\"Age\":35},{\"surveyName\":\"CDE\",\"Age\":36}]"
  guard let jsonData = jsonString.dataUsingEncoding(NSASCIIStringEncoding) else {
    fatalError()
  }

  //I'm not sure why you take JSON data, convert it to a string, and convert
  //It back to NSData, but to prove a point, this is your code being fed
  //well-formed JSON data in an NSData object:
  if let postString = NSString(data:jsonData,
                               encoding: NSASCIIStringEncoding) as? String {
    guard let jsonData = postString.dataUsingEncoding(NSASCIIStringEncoding) else {
      fatalError()
    }

    guard let jsonObjects =  try? NSJSONSerialization.JSONObjectWithData(jsonData,options: []),
        let JSONArray = jsonObjects as? [[String: AnyObject]]
      else {
        fatalError()
    }
    print(JSONArray)
  }

}

为了提供完整的测试,我首先获取一个包含JSON数据的字符串并将其转换为NSData。然后我将该NSData转换回JSON对象并将它们转换为所需的类型,并且它可以工作。上面的代码显示:

[["Name": ABC, "Age": 35], ["surveyName": CDE, "Age": 36]]

哪个与您拥有的结构(一组词典)相匹配。

答案 1 :(得分:0)

以上技术上不是json对象,它是json数组。 尝试转换为[AnyObject]而不是[String: AnyObject]

然后使用该阵列访问您需要的项目。然后把它投射到 [字符串:AnyObject]

因为它们是json数组中的json对象