将 swift 对象转换为 JSON 字符串
Posted
技术标签:
【中文标题】将 swift 对象转换为 JSON 字符串【英文标题】:Turn swift object into a JSON string 【发布时间】:2017-08-24 21:10:12 【问题描述】:我有这样的课程:
class MyDate
var year : String = ""
var month : String = ""
var day : String = ""
init(year : String , month : String , day : String)
self.year = year
self.month = month
self.day = day
class Lad
var firstName : String = ""
var lastName : String = ""
var dateOfBirth : MyDate?
init(firstname : String , lastname : String , dateofbirth : MyDate)
self.firstName = firstname
self.lastName = lastname
self.dateOfBirth = dateofbirth
class MainCon
func sendData()
let myDate = MyDate(year: "1901", month: "4", day: "30")
let obj = Lad(firstname: "Markoff", lastname: "Chaney", dateofbirth: myDate)
let api = ApiService()
api.postDataToTheServer(led: obj)
class ApiService
func postDataToTheServer(led : Lad)
// here i need to json
我想将 Lad
对象转换为 JSON 字符串,如下所示:
"firstName":"马尔科夫", "lastName":"Chaney", “出生日期”: "年":"1901", "月":"4", “天”:“30”
【问题讨论】:
@vadian 你能帮我吗 你在使用一些 JSON 框架吗?用 SwiftyJSON 很容易实现你所需要的 【参考方案1】:编辑 - 2017 年 10 月 31 日:这个答案主要适用于 Swift 3 和可能更早的版本。截至 2017 年底,我们现在拥有 Swift 4,您应该使用 Encodable 和 Decodable 协议在包括 JSON 和文件编码在内的表示之间转换数据。 (可以添加Codable协议实现编解码兼用)
在 Swift 中使用 JSON 的常用解决方案是使用字典。所以你可以这样做:
extension Date
var dataDictionary
return [
"year": self.year,
"month": self.month,
"day": self.day
];
extension Lad
var dataDictionary
return [
"firstName": self.firstName,
"lastName": self.lastName,
"dateOfBirth": self.dateOfBirth.dataDictionary
];
然后使用JSONSerialization
序列化字典格式的数据。
//someLad is a Lad object
do
// encoding dictionary data to JSON
let jsonData = try JSONSerialization.data(withJSONObject: someLad.dataDictionary,
options: .prettyPrinted)
// decoding JSON to Swift object
let decoded = try JSONSerialization.jsonObject(with: jsonData, options: [])
// after decoding, "decoded" is of type `Any?`, so it can't be used
// we must check for nil and cast it to the right type
if let dataFromJSON = decoded as? [String: Any]
// use dataFromJSON
catch
// handle conversion errors
如果您只需要为几个类执行此操作,则提供将它们转换为字典的方法是最易读的选项,并且不会使您的应用明显变大。
但是,如果您需要将许多不同的类转换为 JSON,那么编写如何将每个类转换为字典会很繁琐。因此,为了能够列出对象的属性,使用某种反射 API 会很有用。最稳定的选项似乎是EVReflection。使用 EVReflection,对于我们想要转换为 json 的每个类,我们可以这样做:
extension SomeClass: EVReflectable
let someObject: SomeClass = SomeClass();
let someObjectDictionary = someObject.toDictionary();
然后,就像之前一样,我们可以使用JSONSerialization
将刚刚获得的字典序列化为 JSON。我们只需要使用object.toDictionary()
而不是object.dataDictionary
。
如果您不想使用EVReflection
,您可以使用Mirror 类自己实现反射(查看对象具有哪些字段并对其进行迭代的能力)。有一个关于如何为此目的使用 Mirror 的说明 here。
所以,在定义了.dataDictionary
计算变量或使用EVReflection
的.toDictionary()
方法后,我们可以这样做
class ApiService
func postDataToTheServer(lad: Lad)
//if using a custom method
let dict = lad.dataDictionary
//if using EVReflection
let dict = lad.toDictionary()
//now, we turn it into JSON
do
let jsonData = try JSONSerialization.data(withJSONObject: dict,
options: .prettyPrinted)
// send jsonData to server
catch
// handle errors
【讨论】:
我的回答对你有帮助吗? 非常感谢..可以检查我的更新问题我很抱歉我的不好【参考方案2】:愿此 GitHub 代码对您有所帮助。
protocol SwiftJsonMappable
func getDictionary() -> [String: Any]
func JSONString() -> String
extension SwiftJsonMappable
//Convert the Swift dictionary to JSON String
func JSONString() -> String
do
let jsonData = try JSONSerialization.data(withJSONObject: self.getDictionary(), options: .prettyPrinted)
// here "jsonData" is the dictionary encoded in JSON data
let jsonString = String(data: jsonData, encoding: .utf8) ?? ""
// here "decoded" is of type `Any`, decoded from JSON data
return jsonString
// you can now cast it with the right type
catch
print(error.localizedDescription)
return ""
//Convert Swift object to Swift Dictionary
func getDictionary() -> [String: Any]
var request : [String : Any] = [:]
let mirror = Mirror(reflecting: self)
for child in mirror.children
if let lable = child.label
//For Nil value found for any swift propery, that property should be skipped. if you wanna print nil on json, disable the below condition
if !checkAnyContainsNil(object: child.value)
//Check whether is custom swift class
if isCustomType(object: child.value)
//Checking whether its an array of custom objects
if isArrayType(object: child.value)
if let objects = child.value as? [AMSwiftBase]
var decodeObjects : [[String:Any]] = []
for object in objects
//If its a custom object, nested conversion of swift object to Swift Dictionary
decodeObjects.append(object.getDictionary())
request[lable] = decodeObjects
else
//Not an arry, and custom swift object, convert it to swift Dictionary
request[lable] = (child.value as! AMSwiftBase).getDictionary()
else
request[lable] = child.value
return request
//Checking the swift object is swift base type or custom Swift object
private func isCustomType(object : Any) -> Bool
let typeString = String(describing: type(of: object))
if typeString.contains("String") || typeString.contains("Double") || typeString.contains("Bool")
return false
return true
//checking array
private func isArrayType(object : Any) -> Bool
let typeString = String(describing: type(of: object))
if typeString.contains("Array")
return true
return false
//Checking nil object
private func checkAnyContainsNil(object : Any) -> Bool
let value = "\(object)"
if value == "nil"
return true
return false
https://github.com/anumothuR/SwifttoJson
【讨论】:
以上是关于将 swift 对象转换为 JSON 字符串的主要内容,如果未能解决你的问题,请参考以下文章