将 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 字符串的主要内容,如果未能解决你的问题,请参考以下文章

php如何将json对象转字符串

如何将数据实体转换为 JSON 字符串

jquery 怎么将json字符串转化为json对象

如何将数据实体转换为 JSON 字符串

如何将 javascript 对象转换成 json字符串

如何将 javascript 对象转换成 json字符串