【问题标题】:Swift: Convert struct to JSON?斯威夫特:将结构转换为 JSON?
【发布时间】:2017-02-02 11:05:04
【问题描述】:

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

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

var s = Sentence()
s.sentence = "Hello world"
s.lang = "en"
print(s)

...导致:

Sentence(sentence: "Hello world", lang: "en")

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

{
    "sentence": "Hello world",
    "lang": "en"
}

【问题讨论】:

  • Convert Dictionary to JSON in Swift 的可能重复项(作为提示,您只能将数组或字典转换为 JSON,因此基本上您需要一个字典表示要以 JSON 格式输入的值)。
  • 基本上,如果我可以将结构转换为类似 json 的字符串,那就太好了。当只有数组和字典可以转换为 JSON 时,我的问题是:如何将结构转换为字典?
  • github.com/Hearst-DD/ObjectMapper等第三方库。但是,我没有这方面的经验。

标签: json swift struct nsjsonserialization


【解决方案1】:

使用NSJSONSerialization class

将其用于reference,您可能需要创建一个返回 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
        }
    }

}

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

【讨论】:

  • toJSON() 的返回应该是NSData。另外,您创建的props 字典中的第二个键是错误的。
  • 我已将第二个键更新为字符串,谢谢。第二点取决于用户想要返回什么
【解决方案2】:

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

【讨论】:

  • 我们如何将其重新转换为结构?
  • @BhavinRamani 添加初始化器 init(dict: [String:Any]) {...` 并提取值
  • @BhavinRamani,你可以自动完成,这里有一个很棒的教程:letsbuildthatapp.com/course_video?id=1562
【解决方案3】:

Swift 4 支持 Encodable 协议,例如

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

let sentence = Sentence(sentence: "Hello world", lang: "en")

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

let jsonEncoder = JSONEncoder()
let jsonData = try jsonEncoder.encode(sentence)

打印出来:

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

{
    "sentence": "Hello world",
    "lang": "en"
}

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

【讨论】:

    【解决方案4】:

    这是一个不错的扩展和 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)!)
    }
    

    示例用法:

    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
    

    【讨论】:

      猜你喜欢
      • 2018-01-04
      • 2023-03-07
      • 2017-02-15
      • 1970-01-01
      • 1970-01-01
      • 2017-07-22
      • 2017-03-24
      • 1970-01-01
      相关资源
      最近更新 更多