将swift对象转换为JSON字符串 [英] Turn swift object into a JSON string

查看:1985
本文介绍了将swift对象转换为JSON字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的课程:

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字符串:

And I would like to turn a Lad object into a JSON string like this:


{
firstName:Markoff,
lastName:Chaney,
dateOfBirth:
{
年:1901,
月:4,
day:30
}
}

{ "firstName":"Markoff", "lastName":"Chaney", "dateOfBirth": { "year":"1901", "month":"4", "day":"30" } }


推荐答案

编辑 - 10/31/2017:这个答案主要适用于Swift 3和可能的早期版本。截至2017年底,我们现在拥有Swift 4,你应该使用 Encodable 可解码协议,用于在表示之间转换数据,包括JSON和文件编码。 (您可以添加 Codable 协议以使用编码和解码)

EDIT - 10/31/2017: This answer mostly applies to Swift 3 and possibly earlier versions. As of late 2017, we now have Swift 4 and you should be using the Encodable and Decodable protocols to convert data between representations including JSON and file encodings. (You can add the Codable protocol to use both encoding and decoding)

在Swift中使用JSON的常用解决方案是使用字典。所以你可以这样做:

The usual solution for working with JSON in Swift is to use dictionaries. So you could do:

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
    ];  
  } 
}

然后使用<$序列化字典格式的数据C $ C> 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
}

如果你只是需要为几个类做这个,提供将它们变成字典的方法是最可读的选项,不会让你的应用明显更大。

If you just need to do this for few classes, providing methods to turn them into dictionaries is the most readable option and won't make your app noticeably larger.

但是,如果你需要将许多不同的类转换为JSON,那么写出如何将每个类转换成字典将会很繁琐。因此,使用某种反射API以便能够列出对象的属性会很有用。最稳定的选项似乎是 EVReflection 。使用EVReflection,我们可以为每个类转换为json:

However, if you need to turn a lot of different classes into JSON it would be tedious to write out how to turn each class into a dictionary. So it would be useful to use some sort of reflection API in order to be able to list out the properties of an object. The most stable option seems to be EVReflection. Using EVReflection, for each class we want to turn into json we can do:

extension SomeClass: EVReflectable { }

let someObject: SomeClass = SomeClass();
let someObjectDictionary = someObject.toDictionary();

然后,就像之前一样,我们可以使用<$ c将我们刚刚获得的字典序列化为JSON $ C> JSONSerialization 。我们只需要使用 object.toDictionary()而不是 object.dataDictionary

and then, just like before, we can serialize the dictionary we just obtained to JSON using JSONSerialization. We'll just need to use object.toDictionary() instead of object.dataDictionary.

如果您不想使用 EVReflection ,您可以实现反射(能够查看对象具有哪些字段并迭代它们) )使用镜像课程自己。有关如何使用Mirror的说明此处

If you don't want to use EVReflection, you can implement reflection (the ability to see which fields an object has and iterate over them) yourself by using the Mirror class. There's an explanation of how to use Mirror for this purpose here.

因此,定义了 .dataDictionary 计算变量或使用 EVReflection .toDictionary()方法,我们可以做到

So, having defined either a .dataDictionary computed variable or using EVReflection's .toDictionary() method, we can do

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
    }
  }
}

这篇关于将swift对象转换为JSON字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆