2017-08-14 29 views
0

我想测试解析json文件。 我有以下Json文件作为内部文件存储在项目中。如何解析包含词典中不均匀项目的Json

问题:

  • 房间里有不均匀的物品;有些有2个项目,有些有3个项目。

如何处理这种情况?

-------------- Json file: 

[ 
   { 
      "_id":"598f1442bf068c0b28c2f991", 
      "purpose":"Meeting with Jay", 
      "date":"2017-08-09T03:32:43.395Z", 
      "__v":0, 
      "room":{ 
         "capacity":0, 
         "address":"-" 
      } 
   }, 
   { 
      "_id":"598f147ebf068c0b28c2f992", 
      "purpose":"Presentation to mike", 
      "date":"2017-08-10T07:45:43.395Z", 
      "__v":0, 
      "room":{ 
         "name":"SC-07-01", 
         "capacity":10, 
         "address":"The Hi Five" 
      } 
   }, 
   { 
      "_id":"598f1508bf068c0b28c2f993", 
      "purpose":"Demo to users", 
      "date":"2017-08-11T09:00:00.000Z", 
      "__v":0, 
      "room":{ 
         "name":"SC-08-01", 
         "capacity":30, 
         "address":"The Hi Five" 
      } 
   }, 
   { 
      "_id":"598f16b3bf068c0b28c2f994", 
      "purpose":"Cooking with William", 
      "date":"2017-08-09T05:26:43.395Z", 
      "__v":0, 
      "room":{ 
         "name":"MBC-#07-01", 
         "capacity":10, 
         "address":"Maple Tree garden" 
      } 
   } 
] 

- 更新 -

class RoomBooking { 

    var purpose:String? 
    var date:String? // need to take the date and hh:mm out from it 
    var hhmm: String? 
    var bookDate: String? 
    Var room:Room? 

    init(purpose:String, date:String,hhmm :String, bookDate:String, room : Room) { 

    self.purpose = purpose 
    self.date = date 
    self.hhmm = hhmm 
    self.bookDate = bookDate 
    self.room = room 

    } 
} 

class Room { 
    var name:String? 
    var capacity:Int? 
    var address:String? 
} 


//-1- How to iterate the room? 
//-2- How to get the date and time (hh:mm) from the date Object 

//-3- create an array object of RoomBooking 


var rmbookingArray = [RoomBooking]() 

for user in array { 

     if let userDict = user as? [String:Any]{ 

      if let purpose = userDict.value(forKey: "purpose") { 
            return purpose as! String 
           } 
           return "No purpose enter" 

          }() 

      if let userDate = userDict.value(forKey: "date") { 

            return date as! String 
           } 
           return "No date enter" 

          }() 

      if let userRoom = ?? 

      } 

      var roomObject = Room() 
      roomObject.name = userRoom["name"] as? String 
      roomObject.capacity = userRoom["capacity"] as? Int 
      roomObject.address = userRoom["address"] as? String 

     var rb = RoomBooking() 
     rb.purpose = userPurpose 
     rb.date = userDate 
     rb.room = roomObject 

     rmbookingArray.append(rb) 

    } 

} 

感谢

+0

默认情况下,您应该让您的房间拥有3个物品,如果某个物品没有物品,只需将其设置为“空”即可。这应该会改善你的解析问题 – Lamar

+0

你能告诉我该怎么做。我对swift和json很陌生。房间应该有3个,怎么知道它什么时候包含2个? – MilkBottle

+0

例如,你看到你的第一个对象是如何处理你的地址的:“ - ”,我猜这是说你没有这个人的地址。当你解析时,你可以说如果'-'不显示这个用户的地址 – Lamar

回答

0

你应该创建一个类,其字段是可选项,并如果你的JSON属性之一是缺少,见好就收值为零。如果您期望某些缺失字段,请勿使用guard语句,因为guard总是会在else子句中退出范围。改为使用if let

class RoomBooking { 

    var purpose:String 
    var date:Date 
    var hhmm: String 
    var bookDate: Date 
    var room:Room 

    init(purpose:String, date:Date,hhmm :String, bookDate:Date, room : Room) { 

    self.purpose = purpose 
    self.date = date 
    self.hhmm = hhmm 
    self.bookDate = bookDate 
    self.room = room 

    } 
} 
class Room { 
    var name:String? 
    var capacity:Int? 
    var address:String? 
} 

var rmbookingArray = [RoomBooking]() 

for user in array {  
    if let userDict = user as? [String:Any]{ 
     let df = DateFormatter() 
     df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.z" 

     guard let userDateString = userDict["date"] as? String, let userDate = df.date(from: userDateString) else { return} 
     guard let userPurpose = userDict["purpose"] as? String else { return} 
     //-- the room contain dictionary 

     guard let userRoom = userDict["room"] as? [String:Any] else { return} 

     var roomObject = Room() 
     roomObject.name = userRoom["name"] as? String 
     roomObject.capacity = userRoom["capacity"] as? Int 
     roomObject.address = userRoom["address"] as? String 

     let bookingDateFormatter = DateFormatter() 
     bookingDateFormatter.dateFormat = "hhmm" 

     //I cannot see anything related to bookDate in your JSON, so bookDate is just a dummy variable, set it up to whatever you want to 
     var booking = RoomBooking(purpose: userPurpose, date: userDate, hhmm: bookingDateFormatter.string(from: bookDate), bookDate: bookDate, room: roomObject) 
     rmbookingArray.append(booking) 
    } 
} 

如果您解析您的文件这样,你将能够解析即使某些属性丢失文件的每个“房间”的元素,他们也只是在Room对象nil。我在代码中留下了一些警戒声明,因为从示例中可以看出这些字段总是存在。如果这些可能会丢失,只需将它们更改为if let即可。

+0

给我一些时间,我会回到这里。你的解决方案应该工作。我现在正在努力。 – MilkBottle

+0

json的日期如下:“date”:“2017-08-09T03:32:43.395Z”,如何将字符串日期转换为Date并将日期转换为yyyy mm dd和hour min,如hh:mm。我需要添加到类如var hhmm:string? – MilkBottle

+0

@MilkBottle更新了我的答案,将日期字符串解析为一个Date对象。为了将其转换回另一个字符串表示形式,只需使用带有另一个日期格式的'DateFormatter'。 –