Can Swift convert a class / struct data into dictionary?

前端 未结 3 1165
梦如初夏
梦如初夏 2020-11-30 03:41

For example:

class Test {
    var name: String;
    var age: Int;
    var height: Double;
    func convertToDict() -> [String: AnyObject] { ..... }
}

let         


        
3条回答
  •  既然无缘
    2020-11-30 03:57

    A bit late to the party, but I think this is great opportunity for JSONEncoder and JSONSerialization. The accepted answer does touch on this, this solution saves us calling JSONSerialization every time we access a key, but same idea!

    extension Encodable {
    
        /// Encode into JSON and return `Data`
        func jsonData() throws -> Data {
            let encoder = JSONEncoder()
            encoder.outputFormatting = .prettyPrinted
            encoder.dateEncodingStrategy = .iso8601
            return try encoder.encode(self)
        }
    }
    

    You can then use JSONSerialization to create a Dictionary if the Encodable should be represented as an object in JSON (e.g. Swift Array would be a JSON array)

    Here's an example:

    struct Car: Encodable {
        var name: String
        var numberOfDoors: Int
        var cost: Double
        var isCompanyCar: Bool
        var datePurchased: Date
        var ownerName: String? // Optional
    }
    
    let car = Car(
        name: "Mazda 2",
        numberOfDoors: 5,
        cost: 1234.56,
        isCompanyCar: true,
        datePurchased: Date(),
        ownerName: nil
    )
    
    let jsonData = try car.jsonData()
    
    // To get dictionary from `Data`
    let json = try JSONSerialization.jsonObject(with: jsonData, options: [])
    guard let dictionary = json as? [String : Any] else {
        return
    }
    
    // Use dictionary
    
    guard let jsonString = String(data: jsonData, encoding: .utf8) else {
        return
    }
    
    // Print jsonString
    print(jsonString)
    

    Output:

    {
      "numberOfDoors" : 5,
      "datePurchased" : "2020-03-04T16:04:13Z",
      "name" : "Mazda 2",
      "cost" : 1234.5599999999999,
      "isCompanyCar" : true
    }
    

提交回复
热议问题