以下是代码(主要是从http://codelle.com/blog/2016/5/an-easy-way-to-convert-swift-structs-to-json/复制而来):
import Foundation
protocol JsonRepresentable {
var JsonRepresentation: AnyObject {get}
}
protocol JsonSerializable: JsonRepresentable {
}
extension JsonSerializable {
var JsonRepresentation: AnyObject {
var representation = [String: AnyObject]()
for case let (label?, value) in Mirror(reflecting: self).children {
switch value {
case let value as JsonRepresentable:
representation[label] = value.JsonRepresentation
case let value as NSNumber:
representation[label] = value
case let value as NSString:
representation[label] = value
case let value as NSArray:
representation[label] = value
case let value as NSDictionary:
representation[label] = value
case let value as NSNull:
representation[label] = value
default:
break
}
}
return representation as AnyObject
}
func toJson() -> String? {
let representation = JsonRepresentation
guard JSONSerialization.isValidJSONObject(representation) else {
return nil
}
do {
let data = try JSONSerialization.data(withJSONObject: representation, options: [])
return String(data: data, encoding: String.Encoding.utf8)
} catch {
return nil
}
}
}
struct Owner: JsonSerializable {
var name: String
}
struct Car: JsonSerializable {
var manufacturer: String
var model: String
var mileage: Float
var owner: Owner
}
let car = Car(manufacturer: "Kia", model: "K23", mileage: 143.3, owner: Owner(name: "娴静"))
print(car.toJson())
一切都按预期工作,我唯一的问题是NSString, NSNumber, NSArray
等的分支是完全相同的。如何避免这种冗余?
答案 0 :(得分:1)
而不是case let
,您可以使用可级联的is
extension JsonSerializable {
var JsonRepresentation: Any {
var representation = [String: Any]()
for case let (label?, value) in Mirror(reflecting: self).children {
switch value {
case let value as JsonRepresentable:
representation[label] = value.JsonRepresentation
case is NSNumber, is NSString, is NSArray, is NSDictionary, is NSNull: representation[label] = value
default:
break
}
}
return representation as Any
}
....
考虑到Swift 3中的JSON是Any