使用 swift 从解析的 Json 中提取数据

Posted

技术标签:

【中文标题】使用 swift 从解析的 Json 中提取数据【英文标题】:pull data from parsed Json with swift 【发布时间】:2016-08-15 14:03:57 【问题描述】:

我想从我之前解析过的 JsonObject 中获取我的 CampaignList。但是它在运行时会出现致命错误。

错误

“致命错误:在展开可选值时意外发现 nil”

self.CampaignArray = Campaigns as! NSMutableArray  

代码:

var CampaignArray:NSMutableArray = []

func Get()
    let res: String = ""

    let jsonObject = ["PhoneNumber": "xxxxx"]
    let Jsn = JsonClass(value: jsonObject, text: res)

    Alamofire.request(.POST, "http://MYURL",parameters: jsonObject,
        encoding: .JSON).validate(statusCode: 200..<303)
        .validate(contentType: ["application/json"])
        .responseJSON  (response) in
            NSLog("response = \(response)")

            switch response.result 
            case .Success:
                guard let resultValue = response.result.value else 
                    NSLog("Result value in response is nil")
                    //completionHandler(response: nil)
                    return
                
                let responseJSON = resultValue
                print(responseJSON)
                let result = Jsn.convertStringToDictionary(responseJSON as! String)!
                print("result: \(result)")
                let Campaigns = (result as NSDictionary)["Campaigns"]
                print(Campaigns)
                self.CampaignArray = Campaigns as! NSMutableArray
                let notifications = (result as NSDictionary)["Notifications"]
                print(notifications)
                break
            case .Failure(let error):
                NSLog("Error result: \(error)")
                // Here I call a completionHandler I wrote for the failure case
                return
            
    

而我的回应 Json 是:

json: "CampaignList":[
         "Bonus":"5","CampaignId":"zQUuB2RImUZlcFwt3MjLIA==","City":"34" 
          "Bonus":"3","CampaignId":"VgYWLR6eL2mMemFCPkyocA==","City":"34"],
 "MemberId":"ZBqVhLv\/c2BtMInW52qNLg==",     
 "NotificationList":["Notification":"Filiz Makarnadan Milli Piyango Çekiliş Hakkı Kazanmak İster misin ?","PhoneNumber":"555555555"]

【问题讨论】:

你应该停止使用 NSMutableArray/NSDictionary/etc 并使用 Swift 数组和字典。 // 不要强制打开你的 Optionals,总是用可选绑定处理可能的失败(如果让其他)。 // 另请注意,变量和属性应小写,否则代码的其他读者会误导您的对象类型。 【参考方案1】:

您提供的 JSON 无效。 Campaigns 字典中缺少,。 有效的 JSON 如下所示:


  "CampaignList": [
    
      "Bonus": "5",
      "CampaignId": "zQUuB2RImUZlcFwt3MjLIA==",
      "City": "34"
    ,
    
      "Bonus": "3",
      "CampaignId": "VgYWLR6eL2mMemFCPkyocA==",
      "City": "34"
    
  ],
  "MemberId": "ZBqVhLv/c2BtMInW52qNLg==",
  "NotificationList": [
    
      "Notification": "Filiz Makarnadan Milli Piyango Çekiliş Hakkı Kazanmak İster misin ?",
      "PhoneNumber": "555555555"
    
  ]

致命错误:在展开可选值时意外发现 nil

您收到此错误是因为您尝试将 nil 转换为 NSDictionary 对象。 您提供的 JSON 中没有 Campaigns 密钥,因此当您尝试从 JSON 获取此密钥时,您将得到 nil。在下一步中,您尝试将此 nil 转换为 NSDictionary

尝试使用CampaignList 键来获取您想要的数据。

let result: [String: AnyObject] = Jsn.convertStringToDictionary(responseJSON as! String)!
let campaigns: [Campaign] = result["CampaignList"] as! [Campaign]
print(Campaigns)
self.CampaignArray = campaigns 
let notifications = result["NotificationList"]
print(notifications)

JSON 字典中的 Notifications 键也是如此。

你还应该在objective-c NSDictionary 和NSArray 上使用swift 类型。

【讨论】:

【参考方案2】:

尝试使用 SwiftyJSON (https://github.com/SwiftyJSON/SwiftyJSON)

这个库(pod)非常简单,有详细的文档。

你的例子:

我将子文件“data.json”放在我的项目中并阅读它。感谢 Daniel Sumara 对您的 json 示例进行更正。

  if let path = NSBundle.mainBundle().pathForResource("data", ofType: "json") 
        if let data = NSData(contentsOfFile: path) 
            let json = JSON(data: data)

            if let CampaignList = json["CampaignList"].array 
                for index in 0 ..< CampaignList.count 

                    print("Campaign [\(index)]")
                    if let CampaignId = CampaignList[index]["CampaignId"].string 
                        print("     CampaignId: \(CampaignId)")
                    

                    if let City = CampaignList[index]["City"].string 
                        print("     City: \(City)")
                    

                    if let Bonus = CampaignList[index]["Bonus"].string 
                        print("     Bonus: \(Bonus)")
                    
                
            

            if let MemberId = json["MemberId"].string 
                print("MemberId: \(MemberId)")
            

            if let NotificationList = json["NotificationList"].array 
                print("NotificationList")
                for notification in NotificationList 
                    if let Notification = notification["Notification"].string 
                         print("     Notification: \(Notification)")
                    

                    if let PhoneNumber = notification["PhoneNumber"].string 
                        print("     PhoneNumber: \(PhoneNumber)")
                    
                
            
        
    

你也可以使用 Alamofire-SwiftyJSON (https://github.com/SwiftyJSON/Alamofire-SwiftyJSON)

附:您有致命错误,因为您不检查 value 是否为 nil。阅读“if let”表达式 (https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html)

【讨论】:

我无法使用 swifty json 获得任何结果。当我打印出“json”时,我可以看到输出,但是当我尝试打印活动时,它返回 nil。 ' var json = JSON(data) print("json: (json)") if let campaign = json["CampaignList"].array print("campaigns: (campaigns)") ' 您能在此处粘贴您的 JSON 答案之一吗? 那么,这个解决方案有帮助吗?

以上是关于使用 swift 从解析的 Json 中提取数据的主要内容,如果未能解决你的问题,请参考以下文章

解析 json 数组在 swift 中返回空元素

如何在 Swift 5 中使用 Alamofire 解析 json

如何使用 swift 从 JSON 中提取数据

使用 swiftyJSON/swift 从 Firebase 解析排行榜数据

使用 swift Codable 从 JSON 数组中提取数据

使用 Swift Alamofire 从 SOAP 中提取 JSON 数据