无法解码json

时间:2018-11-11 12:35:32

标签: ios json swift decodable

嗨,我想检索json数据,json数据就是这样

"items":[  
  {  
     "date_for":"2018-11-11",
     "fajr":"5:28 am",
     "shurooq":"6:37 am",
     "dhuhr":"11:52 am",
     "asr":"2:40 pm",
     "maghrib":"5:06 pm",
     "isha":"6:15 pm"
  }
],

与之相比,我使JSONDecoder可解码的方式如下:

struct PrayerModel: Decodable {
var items: [Items]
}

struct Items: Decodable {
var fajr: String
var dhuhr: String
var asr: String
var maghrib: String
var isha: String

init(dictionary: [String: String]) {
    self.fajr = dictionary["fajr"] ?? ""
    self.dhuhr = dictionary["dhuhr"] ?? ""
    self.asr = dictionary["asr"] ?? ""
    self.maghrib = dictionary["maghrib"] ?? ""
    self.isha = dictionary["isha"] ?? ""
  }
}

然后创建一个对象来存储可解码数据:

struct Prayer {
var prayerName: String
var prayerIcon: UIImage
var prayerTime: String

init(prayerName: String, prayerIcon: UIImage, prayerTime: String) {
    self.prayerName = prayerName
    self.prayerIcon = prayerIcon
    self.prayerTime = prayerTime
 }
}

并使用URLSession检索它:

do {
     let prayerData = try JSONDecoder().decode(PrayerModel.self, from: data)

     prayerData.items.forEach({ (item) in
     let isya = Prayer(prayerName: "Isya", prayerIcon: #imageLiteral(resourceName: "Clear"), prayerTime: item.isha)
     self.prayers.append(contentsOf: [shubuh, dzuhur, ashar, maghrib, isya])
      })
        DispatchQueue.main.async {
        self.tableView.reloadData()
       }
            } catch let decodeErr {
                print("Failed to decode:", decodeErr)
            }

我得到了这个错误

  

解码失败:dataCorrupted(Swift.DecodingError.Context(codingPath:[],debugDescription:“给定的数据不是有效的JSON。”,underlyingError:可选(错误域= NSCocoaErrorDomain代码= 3840,JSON文本未开始带有数组或对象以及允许未设置片段的选项。“ UserInfo = {NSDebugDescription = JSON文本不是以数组或对象开头并且允许不允许设置片段的选项。})))

我的代码的问题在哪里,任何人都可以提供帮助?

2 个答案:

答案 0 :(得分:0)

就像我在评论中提到的json消息不正确一样,我在其中添加了{}并且效果很好。

  

{“商品”:[{
       “ date_for”:“ 2018-11-11”,        “ fajr”:“ 5:28 am”,        “ shurooq”:“上午6:37”,        “ dhuhr”:“上午11:52”,        “ asr”:“ 2:40 pm”,        “ maghrib”:“ 5:06 pm”,        “ isha”:“下午6:15”
      }]     }

如果您不想使用所有元素,则不必在json消息中包括所有元素,因此我从init()中删除了Items方法,因为它没有使用。

struct Items: Decodable {
  var fajr: String
  var dhuhr: String
  var asr: String
  var maghrib: String
  var isha: String
}

然后使用下面的代码就可以正常工作

let str = "{\"items\":[{\"date_for\":\"2018-11-11\",\"fajr\":\"5:28 am\",\"shurooq\":\"6:37 am\",\"dhuhr\":\"11:52 am\",\"asr\":\"2:40 pm\",\"maghrib\":\"5:06 pm\",\"isha\":\"6:15 pm\"}]}"

do {
  if let data = str.data(using: .utf8) {
    let prayerData = try JSONDecoder().decode(PrayerModel.self, from: data)
    for item in prayerData.items {
      print(item)
    }
  }
} catch let decodeErr {
  print("Failed to decode:", decodeErr)
}

答案 1 :(得分:-1)

如果要在JSON中使用Decodable原型,则变量应具有完全相同的名称,并包括所有具有相同位置的项目。

尝试一下:

var date_for: String
var fajr: String
var shurooq: String
var dhuhr: String
var asr: String
var maghrib: String
var isha: String

init(dictionary: [String: String]) {
    self.date_for = dictionary["date_for"] ?? ""
    self.fajr = dictionary["fajr"] ?? ""
    self.shurooq = dictionary["shurooq"] ?? ""
    self.dhuhr = dictionary["dhuhr"] ?? ""
    self.asr = dictionary["asr"] ?? ""
    self.maghrib = dictionary["maghrib"] ?? ""
    self.isha = dictionary["isha"] ?? ""
}