JSONSerialization解析问题:

问题描述 投票:0回答:2

我在解析json时遇到错误

"hoursOfOperation" : {
      "sat" : {
        "enabled" : true,
        "schedule" : [
          {
            "time" : {
              "close" : 1020,
              "open" : 600
            }
          }
        ]
      },
      "fri" : {
        "enabled" : true,
        "schedule" : [
          {
            "time" : {
              "close" : 1260,
              "open" : 660
            }
          }
        ]
      },
      "sun" : {
        "enabled" : true,
        "schedule" : [
          {
            "time" : {
              "close" : 1020,
              "open" : 600
            }
          }
        ]
      },
      "mon" : {
        "enabled" : true,
        "schedule" : [
          {
            "time" : {
              "close" : 1260,
              "open" : 960
            }
          }
        ]
      },
      "tue" : {
        "enabled" : true,
        "schedule" : [
          {
            "time" : {
              "close" : 1260,
              "open" : 660
            }
          }
        ]
      },
      "wed" : {
        "enabled" : true,
        "schedule" : [
          {
            "time" : {
              "close" : 1260,
              "open" : 660
            }
          }
        ]
      },
      "thu" : {
        "enabled" : true,
        "schedule" : [
          {
            "time" : {
              "close" : 1260,
              "open" : 660
            }
          }
        ]
      }
    }

这是JSON共享。我正在使用JSONSerialization来解析相同的内容。代码如下:

struct HoursOfOperation{

var sun : hoursOfOperationData?
var mon : hoursOfOperationData?
var tue : hoursOfOperationData?
var wed : hoursOfOperationData?
var thu : hoursOfOperationData?
var fri : hoursOfOperationData?
var sat : hoursOfOperationData?

init(_ info: AnyObject) {
    let s = String(describing: info)
    let data = s.data(using: String.Encoding.utf8, allowLossyConversion: false)!
    do {
        let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: AnyObject]

        if let sun = json["sun"]{
            self.sun = hoursOfOperationData.init(sun)
        }
        if let sat = json["sat"]{
            self.sat = hoursOfOperationData.init(sat)
        }
        if let fri = json["fri"]{
            self.fri = hoursOfOperationData.init(fri)
        }
        if let thu = json["thu"] {
            self.thu = hoursOfOperationData.init(thu)
        }
        if let wed = json["wed"]{
            self.wed = hoursOfOperationData.init(wed)
        }
        if let tue = json["tue"]{
            self.tue = hoursOfOperationData.init(tue)
        }
        if let mon = json["mon"] {
            self.mon = hoursOfOperationData.init(mon)
        }
    } catch let error as NSError {
        print("Failed to load: \(error.localizedDescription)")
    }
}
}

// hoursOfOperationData

struct hoursOfOperationData{

var enabled : AnyObject?
var schedule : [scheduleData]?

init(_ info: AnyObject) {
    let s = String(describing: info)
    let data = s.data(using: String.Encoding.utf8, allowLossyConversion: false)!
    do {
        let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: AnyObject]
        if let enabled = json["enabled"]{
            self.enabled = enabled as AnyObject
        }
        if let schedule = json["schedule"] as? NSArray{

            for dic in schedule{
                schedule.adding(scheduleData.init(dic as AnyObject))
            }
            self.schedule = schedule as? [scheduleData]
        }
    } catch let error as NSError {
        print("Failed to load: \(error.localizedDescription)")
    }
}
}

// scheduleData

struct scheduleData{

var time : scheduleDataForLocation?

init(_ info: AnyObject) {
    let s = String(describing: info)
    let data = s.data(using: String.Encoding.utf8, allowLossyConversion: false)!
    do {
        let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: AnyObject]
        if let time = json["time"]{
            self.time = scheduleDataForLocation.init(time)
        }
    } catch let error as NSError {
        print("Failed to load: \(error.localizedDescription)")
    }
    }
}

// scheduleDataForLocation

struct scheduleDataForLocation{

var openTime : AnyObject?
var closeTime : AnyObject?

init(_ info: AnyObject) {
    let s = String(describing: info)
    let data = s.data(using: String.Encoding.utf8, allowLossyConversion: false)!
    do {
        let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: AnyObject]
        if let open = json["open"]{
            self.openTime = open as AnyObject
        }
        if let close = json["close"]{
            self.closeTime = close as AnyObject
        }
    } catch let error as NSError {
        print("Failed to load: \(error.localizedDescription)")
    }
}
}

准备此模型时我无法解析json并收到错误消息

'Error Domain = NSCocoaErrorDomain Code = 3840“字符6周围的对象中的值没有字符串键。” UserInfo = {NSDebugDescription =字符6周围的对象中的值没有字符串键。}'

请建议一个正确的方法来处理相同的问题。我访问了许多堆栈溢出问题和答案,但没有人回答我的问题。任何帮助都会很明显。

ios json swift nsjsonserialization
2个回答
2
投票

您可以直接使用下面的模型类,参考:http://www.jsoncafe.com/

class OperationModel : NSObject, NSCoding{

    var hoursOfOperation : HoursOfOperation!


    /**
     * Instantiate the instance using the passed dictionary values to set the properties values
     */
    init(fromDictionary dictionary: [String:Any]){
        if let hoursOfOperationData = dictionary["hoursOfOperation"] as? [String:Any]{
            hoursOfOperation = HoursOfOperation(fromDictionary: hoursOfOperationData)
        }
    }

    /**
     * Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
     */
    func toDictionary() -> [String:Any]
    {
        var dictionary = [String:Any]()
        if hoursOfOperation != nil{
            dictionary["hoursOfOperation"] = hoursOfOperation.toDictionary()
        }
        return dictionary
    }

    /**
     * NSCoding required initializer.
     * Fills the data from the passed decoder
     */
    @objc required init(coder aDecoder: NSCoder)
    {
        hoursOfOperation = aDecoder.decodeObject(forKey: "hoursOfOperation") as? HoursOfOperation
    }

    /**
     * NSCoding required method.
     * Encodes mode properties into the decoder
     */
    @objc func encode(with aCoder: NSCoder)
    {
        if hoursOfOperation != nil{
            aCoder.encode(hoursOfOperation, forKey: "hoursOfOperation")
        }
    }
}


class Schedule : NSObject, NSCoding{

    var time : Time!


    /**
     * Instantiate the instance using the passed dictionary values to set the properties values
     */
    init(fromDictionary dictionary: [String:Any]){
        if let timeData = dictionary["time"] as? [String:Any]{
            time = Time(fromDictionary: timeData)
        }
    }

    /**
     * Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
     */
    func toDictionary() -> [String:Any]
    {
        var dictionary = [String:Any]()
        if time != nil{
            dictionary["time"] = time.toDictionary()
        }
        return dictionary
    }

    /**
     * NSCoding required initializer.
     * Fills the data from the passed decoder
     */
    @objc required init(coder aDecoder: NSCoder)
    {
        time = aDecoder.decodeObject(forKey: "time") as? Time
    }

    /**
     * NSCoding required method.
     * Encodes mode properties into the decoder
     */
    @objc func encode(with aCoder: NSCoder)
    {
        if time != nil{
            aCoder.encode(time, forKey: "time")
        }
    }
}



class HoursOfOperation : NSObject, NSCoding{

    var fri : Day!
    var mon : Day!
    var sat : Day!
    var sun : Day!
    var thu : Day!
    var tue : Day!
    var wed : Day!


    /**
     * Instantiate the instance using the passed dictionary values to set the properties values
     */
    init(fromDictionary dictionary: [String:Any]){
        if let friData = dictionary["fri"] as? [String:Any]{
            fri = Day(fromDictionary: friData)
        }
        if let monData = dictionary["mon"] as? [String:Any]{
            mon = Day(fromDictionary: monData)
        }
        if let satData = dictionary["sat"] as? [String:Any]{
            sat = Day(fromDictionary: satData)
        }
        if let sunData = dictionary["sun"] as? [String:Any]{
            sun = Day(fromDictionary: sunData)
        }
        if let thuData = dictionary["thu"] as? [String:Any]{
            thu = Day(fromDictionary: thuData)
        }
        if let tueData = dictionary["tue"] as? [String:Any]{
            tue = Day(fromDictionary: tueData)
        }
        if let wedData = dictionary["wed"] as? [String:Any]{
            wed = Day(fromDictionary: wedData)
        }
    }

    /**
     * Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
     */
    func toDictionary() -> [String:Any]
    {
        var dictionary = [String:Any]()
        if fri != nil{
            dictionary["fri"] = fri.toDictionary()
        }
        if mon != nil{
            dictionary["mon"] = mon.toDictionary()
        }
        if sat != nil{
            dictionary["sat"] = sat.toDictionary()
        }
        if sun != nil{
            dictionary["sun"] = sun.toDictionary()
        }
        if thu != nil{
            dictionary["thu"] = thu.toDictionary()
        }
        if tue != nil{
            dictionary["tue"] = tue.toDictionary()
        }
        if wed != nil{
            dictionary["wed"] = wed.toDictionary()
        }
        return dictionary
    }

    /**
     * NSCoding required initializer.
     * Fills the data from the passed decoder
     */
    @objc required init(coder aDecoder: NSCoder)
    {
        fri = aDecoder.decodeObject(forKey: "fri") as? Day
        mon = aDecoder.decodeObject(forKey: "mon") as? Day
        sat = aDecoder.decodeObject(forKey: "sat") as? Day
        sun = aDecoder.decodeObject(forKey: "sun") as? Day
        thu = aDecoder.decodeObject(forKey: "thu") as? Day
        tue = aDecoder.decodeObject(forKey: "tue") as? Day
        wed = aDecoder.decodeObject(forKey: "wed") as? Day
    }

    /**
     * NSCoding required method.
     * Encodes mode properties into the decoder
     */
    @objc func encode(with aCoder: NSCoder)
    {
        if fri != nil{
            aCoder.encode(fri, forKey: "fri")
        }
        if mon != nil{
            aCoder.encode(mon, forKey: "mon")
        }
        if sat != nil{
            aCoder.encode(sat, forKey: "sat")
        }
        if sun != nil{
            aCoder.encode(sun, forKey: "sun")
        }
        if thu != nil{
            aCoder.encode(thu, forKey: "thu")
        }
        if tue != nil{
            aCoder.encode(tue, forKey: "tue")
        }
        if wed != nil{
            aCoder.encode(wed, forKey: "wed")
        }
    }
}


class Time : NSObject, NSCoding{

    var close : Int!
    var open : Int!


    /**
     * Instantiate the instance using the passed dictionary values to set the properties values
     */
    init(fromDictionary dictionary: [String:Any]){
        close = dictionary["close"] as? Int
        open = dictionary["open"] as? Int
    }

    /**
     * Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
     */
    func toDictionary() -> [String:Any]
    {
        var dictionary = [String:Any]()
        if close != nil{
            dictionary["close"] = close
        }
        if open != nil{
            dictionary["open"] = open
        }
        return dictionary
    }

    /**
     * NSCoding required initializer.
     * Fills the data from the passed decoder
     */
    @objc required init(coder aDecoder: NSCoder)
    {
        close = aDecoder.decodeObject(forKey: "close") as? Int
        open = aDecoder.decodeObject(forKey: "open") as? Int
    }

    /**
     * NSCoding required method.
     * Encodes mode properties into the decoder
     */
    @objc func encode(with aCoder: NSCoder)
    {
        if close != nil{
            aCoder.encode(close, forKey: "close")
        }
        if open != nil{
            aCoder.encode(open, forKey: "open")
        }
    }
}


class Day : NSObject, NSCoding{

    var enabled : Bool!
    var schedule : [Schedule]!


    /**
     * Instantiate the instance using the passed dictionary values to set the properties values
     */
    init(fromDictionary dictionary: [String:Any]){
        enabled = dictionary["enabled"] as? Bool
        schedule = [Schedule]()
        if let scheduleArray = dictionary["schedule"] as? [[String:Any]]{
            for dic in scheduleArray{
                let value = Schedule(fromDictionary: dic)
                schedule.append(value)
            }
        }
    }

    /**
     * Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
     */
    func toDictionary() -> [String:Any]
    {
        var dictionary = [String:Any]()
        if enabled != nil{
            dictionary["enabled"] = enabled
        }
        if schedule != nil{
            var dictionaryElements = [[String:Any]]()
            for scheduleElement in schedule {
                dictionaryElements.append(scheduleElement.toDictionary())
            }
            dictionary["schedule"] = dictionaryElements
        }
        return dictionary
    }

    /**
     * NSCoding required initializer.
     * Fills the data from the passed decoder
     */
    @objc required init(coder aDecoder: NSCoder)
    {
        enabled = aDecoder.decodeObject(forKey: "enabled") as? Bool
        schedule = aDecoder.decodeObject(forKey: "schedule") as? [Schedule]
    }

    /**
     * NSCoding required method.
     * Encodes mode properties into the decoder
     */
    @objc func encode(with aCoder: NSCoder)
    {
        if enabled != nil{
            aCoder.encode(enabled, forKey: "enabled")
        }
        if schedule != nil{
            aCoder.encode(schedule, forKey: "schedule")
        }
    }
}

使用 :

let jsonData = try Data(contentsOf: url)
let json = try JSONSerialization.jsonObject(with: jsonData) as! [String : Any]
let arrOper = OperationModel(fromDictionary: json)

输出:

enter image description here


0
投票

我发现一些问题,如果你JSON与缺少开括号或方括号{}有关

所以首先纠正,然后你的JSON将是:

{
"hoursOfOperation" : {
  "sat" : {
    "enabled" : true,
    "schedule" : [
      {
        "time" : {
          "close" : 1020,
          "open" : 600
        }
      }
    ]
  },
  "fri" : {
    "enabled" : true,
    "schedule" : [
      {
        "time" : {
          "close" : 1260,
          "open" : 660
        }
      }
    ]
  },
  "sun" : {
    "enabled" : true,
    "schedule" : [
      {
        "time" : {
          "close" : 1020,
          "open" : 600
        }
      }
    ]
  },
  "mon" : {
    "enabled" : true,
    "schedule" : [
      {
        "time" : {
          "close" : 1260,
          "open" : 960
        }
      }
    ]
  },
  "tue" : {
    "enabled" : true,
    "schedule" : [
      {
        "time" : {
          "close" : 1260,
          "open" : 660
        }
      }
    ]
  },
  "wed" : {
    "enabled" : true,
    "schedule" : [
      {
        "time" : {
          "close" : 1260,
          "open" : 660
        }
      }
    ]
  },
  "thu" : {
    "enabled" : true,
    "schedule" : [
      {
        "time" : {
          "close" : 1260,
          "open" : 660
        }
      }
    ]
  }
}
}

现在您可以使用THIS站点和代码创建您的Codable协议,它将如下所示:

import Foundation

struct ScheduleData: Codable {
  let hoursOfOperation: HoursOfOperation
}

struct HoursOfOperation: Codable {
    let sat, fri, sun, mon: Fri
    let tue, wed, thu: Fri
}

struct Fri: Codable {
 let enabled: Bool
 let schedule: [Schedule]
}

struct Schedule: Codable {
 let time: Time
}

struct Time: Codable {
 let close, timeOpen: Int

  enum CodingKeys: String, CodingKey {
    case close
    case timeOpen = "open"
  }
}

用途:

let scheduleData = try? JSONDecoder().decode(ScheduleData.self, from: response.data!)
let close_time = scheduleData?.hoursOfOperation.sat.schedule[0].time.close
Print(close_time)

输出:1020

© www.soinside.com 2019 - 2024. All rights reserved.