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

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


编辑 - 10/31/2017:这个答案主要适用于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类EVReflection实现反射(可以查看对象具有哪些字段并遍历它们)。 这里有一个关于如何使用Mirror的解释。

因此,在定义了.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
    }
  }
}

这个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

链接地址: http://www.djcxy.com/p/37871.html

上一篇: Turn swift object into a JSON string

下一篇: Generics / JSON JavaScriptSerializer C#