Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift:将结构转换为JSON?_Json_Swift_Struct_Nsjsonserialization - Fatal编程技术网

Swift:将结构转换为JSON?

Swift:将结构转换为JSON?,json,swift,struct,nsjsonserialization,Json,Swift,Struct,Nsjsonserialization,我创建了一个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"

我创建了一个
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"
}
使用

使用此函数,您可能需要创建一个返回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字符串可能更容易。

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

Swift 4支持可编码协议,例如

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

let sentence = Sentence(sentence: "Hello world", lang: "en")
现在,您可以使用JSONEncoder自动将结构转换为JSON:

let jsonEncoder = JSONEncoder()
let jsonData = try jsonEncoder.encode(sentence)
打印出来:

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

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

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

可能的重复(作为提示,您只能将数组或字典转换为JSON,因此基本上您需要以JSON格式输入值的字典表示形式)。基本上,如果我可以将结构转换为类似JSON的字符串,那就太好了。当只有数组和字典可转换为JSON时,我的问题是:如何将结构转换为字典?有第三方库,如。但是,我没有这方面的经验。
toJSON()
的返回应该是
NSData
。另外,您创建的
props
字典中的第二个键是错误的。我已将第二个键更新为字符串,谢谢。第二点取决于用户想要返回什么我们如何将其重新转换为struct?@BhavinRamani添加一个初始值设定项init(dict:[String:Any]){…`并提取values@BhavinRamani,您可以自动完成,下面是一个很棒的教程:
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