Swift:将struct转换为JSON?

ixa*_*any 14 json struct nsjsonserialization swift

我创建了一个struct并希望将其保存为JSON文件.

struct Sentence {
    var sentence = ""
    var lang = ""
}

var s = Sentence()
s.sentence = "Hello world"
s.lang = "en"
print(s)
Run Code Online (Sandbox Code Playgroud)

...导致:

Sentence(sentence: "Hello world", lang: "en")
Run Code Online (Sandbox Code Playgroud)

但是我怎样才能将struct对象转换为:

{
    "sentence": "Hello world",
    "lang": "en"
}
Run Code Online (Sandbox Code Playgroud)

vad*_*ian 22

您可以添加计算属性以获取JSON表示,并添加静态(类)函数以从Sentence数组创建JSON 数组.

struct Sentence {
  var sentence = ""
  var lang = ""

  static func jsonArray(array : [Sentence]) -> String
  {
    return "[" + array.map {$0.jsonRepresentation}.joinWithSeparator(",") + "]"
  }

  var jsonRepresentation : String {
    return "{\"sentence\":\"\(sentence)\",\"lang\":\"\(lang)\"}"
  }
}


let sentences = [Sentence(sentence: "Hello world", lang: "en"), Sentence(sentence: "Hallo Welt", lang: "de")]
let jsonArray = Sentence.jsonArray(sentences)
print(jsonArray) // [{"sentence":"Hello world","lang":"en"},{"sentence":"Hallo Welt","lang":"de"}]
Run Code Online (Sandbox Code Playgroud)

编辑:

Swift 4引入了Codable协议,它提供了一种非常方便的方法来编码和解码自定义结构.

struct Sentence : Codable {
    let sentence : String
    let lang : String
}

let sentences = [Sentence(sentence: "Hello world", lang: "en"), 
                 Sentence(sentence: "Hallo Welt", lang: "de")]

do {
    let jsonData = try JSONEncoder().encode(sentences)
    let jsonString = String(data: jsonData, encoding: .utf8)!
    print(jsonString) // [{"sentence":"Hello world","lang":"en"},{"sentence":"Hallo Welt","lang":"de"}]

    // and decode it back
    let decodedSentences = try JSONDecoder().decode([Sentence].self, from: jsonData)
    print(decodedSentences)
} catch { print(error) }
Run Code Online (Sandbox Code Playgroud)


Scr*_*ble 11

使用NSJSONSerialization类.

使用它作为参考,您可能需要创建一个返回JSON序列化字符串的函数.在此函数中,您可以获取所需的属性并从中创建NSDictionary并使用上面提到的类.

像这样的东西:

struct Sentence {
    var sentence = ""
    var lang = ""

    func toJSON() -> String? {
        let props = ["Sentence": self.sentence, "lang": lang]
        do {
            let jsonData = try NSJSONSerialization.dataWithJSONObject(props,
            options: .PrettyPrinted)
            return String(data: jsonData, encoding: NSUTF8StringEncoding)
        } catch let error {
            print("error converting to json: \(error)")
            return nil
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

因为您的struct只有两个属性,所以可能更容易自己构建JSON字符串.


alg*_*rid 11

这是一个很好的扩展和 JSON 编码/解码的方法:

extension Encodable {
    
    func toJSONString() -> String {
        let jsonData = try! JSONEncoder().encode(self)
        return String(data: jsonData, encoding: .utf8)!
    }
    
}

func instantiate<T: Decodable>(jsonString: String) -> T? {
    return try? JSONDecoder().decode(T.self, from: jsonString.data(using: .utf8)!)
}
Run Code Online (Sandbox Code Playgroud)

使用示例:

struct Sentence: Codable {
    var sentence = ""
    var lang = ""
}

let sentence = Sentence(sentence: "Hello world", lang: "en")
let jsonStr = sentence.toJSONString()
print(jsonStr)      // prints {"lang":"en","sentence":"Hello world"}

let sentenceFromJSON: Sentence? = instantiate(jsonString: jsonStr)
print(sentenceFromJSON!)    // same as original sentence
Run Code Online (Sandbox Code Playgroud)


Bre*_*ett 10

Swift 4支持Encodable协议,例如

struct Sentence: Encodable {
    var sentence: String?
    var lang: String?
}

let sentence = Sentence(sentence: "Hello world", lang: "en")
Run Code Online (Sandbox Code Playgroud)

现在,您可以使用JSONEncoder自动将Struct转换为JSON:

let jsonEncoder = JSONEncoder()
let jsonData = try jsonEncoder.encode(sentence)
Run Code Online (Sandbox Code Playgroud)

打印出来:

let jsonString = String(data: jsonData, encoding: .utf8)
print(jsonString)

{
    "sentence": "Hello world",
    "lang": "en"
}
Run Code Online (Sandbox Code Playgroud)

https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types