swift项目中总是需要将实体类转换为json格式与服务器进行通讯,之前一直使用拼接字符串的方式,这样就造成了大量的资源浪费,自己动手写了model to json的方法但是是objc的,现项目需要使用swift又懒得重写,于是google找到了一个可以用的库,链接如下:
https://github.com/peheje/JsonSerializerSwift/blob/master/JsonSerializerSwift/JsonSerializer.swift
但是此方法并不能很好的满足实际需求,会有些问题。
问题1:如果model是一个数组,该方法的json字符串会以 {"[0]" 开头,并不是我们常用的 [{}]格式
问题2:如果model包含另一个实体类,该方法会直接将实体类的类名输出为字符串,也就是没有递归解析
问题3:代码太多
自己动手改了一点,整体的逻辑和方法还是用的原来的代码,基本可以满足项目的需求了。
代码如下:
class func toJson(object: Any, prettify: Bool = false) -> String {
var json = "{"
let mirror = Mirror(reflecting: object)
var children = [(label: String?, value: Any)]()
let mirrorChildrenCollection = AnyRandomAccessCollection(mirror.children)!
children += mirrorChildrenCollection
var currentMirror = mirror
while let superclassChildren = currentMirror.superclassMirror()?.children {
let randomCollection = AnyRandomAccessCollection(superclassChildren)!
children += randomCollection
currentMirror = currentMirror.superclassMirror()!
}
var filterredChildren = [(label: String?, value: Any)]()
for (optionalPropertyName, values) in children {
if !optionalPropertyName!.containsString("notMapped_") {
filterredChildren += [(optionalPropertyName, values)]
}
}
var skip = false
let size = filterredChildren.count
var index = 0
if let objArray = object as? NSArray {
var jsonArray = "["
for (index, value) in objArray.enumerate() {
jsonArray += toJson(value, prettify: prettify)
jsonArray += (index < objArray.count - 1 ? ", " : "")
}
jsonArray += "]"
return jsonArray
}
for (optionalPropertyName, value) in filterredChildren {
skip = false
let propertyName = optionalPropertyName!
let property = Mirror(reflecting: value)
var handleValue = String()
if property.displayStyle == Mirror.DisplayStyle.Struct || property.displayStyle == Mirror.DisplayStyle.Class {
handleValue = toJson(value)
skip = true
} else if (value is Int || value is Double || value is Float || value is Bool) && property.displayStyle != Mirror.DisplayStyle.Optional {
handleValue = String(value ?? "null")
} else if property.displayStyle == Mirror.DisplayStyle.Optional {
let str = String(value)
if str != "nil" {
let type = String(property.subjectType)
if type.containsString("String")
|| type.containsString("Int")
|| type.containsString("Double")
|| type.containsString("Bool")
|| type.containsString("NSDate")
|| type.containsString("Float") {
handleValue = String(str).substringWithRange(str.startIndex.advancedBy(9)..<str.endIndex.advancedBy(-1))
} else {
handleValue = toJson(value)
}
} else {
handleValue = "null"
}
} else {
handleValue = String(value) != "nil" ? "\"\(value)\"" : "null"
}
if !skip {
json += "\"\(propertyName)\": \(handleValue)" + (index < size - 1 ? ", " : "")
} else {
json = "\(handleValue)" + (index < size - 1 ? ", " : "")
}
index += 1
}
if !skip {
json += "}"
}
if prettify {
do {
let jsonData = json.dataUsingEncoding(NSUTF8StringEncoding)!
let jsonObject: AnyObject = try NSJSONSerialization.JSONObjectWithData(jsonData, options: [])
let prettyJsonData = try NSJSONSerialization.dataWithJSONObject(jsonObject, options: .PrettyPrinted)
json = NSString(data: prettyJsonData, encoding: NSUTF8StringEncoding)! as String
} catch _ {
// print(error)
}
}
return json
}
多次测试暂时没发现问题,希望测试到问题的同学能给我反馈,谢谢。
原文链接:iOS 实体类转json(swift),转载请注明来源!