我已经创建了下一个字典:

var postJSON = [ids[0]:answersArray[0], ids[1]:answersArray[1], ids[2]:answersArray[2]] as Dictionary

得到:

[2: B, 1: A, 3: C]

那么,如何将其转换为JSON呢?


当前回答

斯威夫特5:

let dic = ["2": "B", "1": "A", "3": "C"]
let encoder = JSONEncoder()
if let jsonData = try? encoder.encode(dic) {
    if let jsonString = String(data: jsonData, encoding: .utf8) {
        print(jsonString)
    }
}

注意键和值必须实现Codable。字符串、整型和双精度(以及更多)已经是可编码的。参见编码和解码自定义类型。

还要注意,Any不符合Codable。这可能仍然是一个很好的方法来调整你的数据成为可编码的,这样你就可以使用Swift类型(特别是在你也要解码任何编码的json的情况下),这样你就可以更声明你的编码的结果。

其他回答

斯威夫特3.0

在Swift 3中,NSJSONSerialization的名字和它的方法已经改变了,根据Swift API设计指南。

let dic = ["2": "B", "1": "A", "3": "C"]

do {
    let jsonData = try JSONSerialization.data(withJSONObject: dic, options: .prettyPrinted)
    // here "jsonData" is the dictionary encoded in JSON data

    let decoded = try JSONSerialization.jsonObject(with: jsonData, options: [])
    // here "decoded" is of type `Any`, decoded from JSON data

    // you can now cast it with the right type        
    if let dictFromJSON = decoded as? [String:String] {
        // use dictFromJSON
    }
} catch {
    print(error.localizedDescription)
}

快2.倍

do {
    let jsonData = try NSJSONSerialization.dataWithJSONObject(dic, options: NSJSONWritingOptions.PrettyPrinted)
    // here "jsonData" is the dictionary encoded in JSON data

    let decoded = try NSJSONSerialization.JSONObjectWithData(jsonData, options: [])
    // here "decoded" is of type `AnyObject`, decoded from JSON data

    // you can now cast it with the right type 
    if let dictFromJSON = decoded as? [String:String] {
        // use dictFromJSON
    }
} catch let error as NSError {
    print(error)
}

斯威夫特1

var error: NSError?
if let jsonData = NSJSONSerialization.dataWithJSONObject(dic, options: NSJSONWritingOptions.PrettyPrinted, error: &error) {
    if error != nil {
        println(error)
    } else {
        // here "jsonData" is the dictionary encoded in JSON data
    }
}

if let decoded = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &error) as? [String:String] {
    if error != nil {
        println(error)
    } else {
        // here "decoded" is the dictionary decoded from JSON data
    }
}

斯威夫特5:

let dic = ["2": "B", "1": "A", "3": "C"]
let encoder = JSONEncoder()
if let jsonData = try? encoder.encode(dic) {
    if let jsonString = String(data: jsonData, encoding: .utf8) {
        print(jsonString)
    }
}

注意键和值必须实现Codable。字符串、整型和双精度(以及更多)已经是可编码的。参见编码和解码自定义类型。

还要注意,Any不符合Codable。这可能仍然是一个很好的方法来调整你的数据成为可编码的,这样你就可以使用Swift类型(特别是在你也要解码任何编码的json的情况下),这样你就可以更声明你的编码的结果。

使用lldb

(lldb) p JSONSerialization.data(withJSONObject: notification.request.content.userInfo, options: [])
(Data) $R16 = 375 bytes
(lldb) p String(data: $R16!, encoding: .utf8)!
(String) $R18 = "{\"aps\": \"some_text\"}"

//or
p String(data: JSONSerialization.data(withJSONObject: notification.request.content.userInfo, options: [])!, encoding: .utf8)!
(String) $R4 = "{\"aps\": \"some_text\"}"

有时为了调试目的,有必要打印出服务器的响应。下面是我使用的函数:

extension Dictionary {

    var json: String {
        let invalidJson = "Not a valid JSON"
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: self, options: .prettyPrinted)
            return String(bytes: jsonData, encoding: String.Encoding.utf8) ?? invalidJson
        } catch {
            return invalidJson
        }
    }

    func printJson() {
        print(json)
    }

}

使用示例:

(lldb) po dictionary.printJson()
{
  "InviteId" : 2,
  "EventId" : 13591,
  "Messages" : [
    {
      "SenderUserId" : 9514,
      "MessageText" : "test",
      "RecipientUserId" : 9470
    },
    {
      "SenderUserId" : 9514,
      "MessageText" : "test",
      "RecipientUserId" : 9470
    }
  ],
  "TargetUserId" : 9470,
  "InvitedUsers" : [
    9470
  ],
  "InvitingUserId" : 9514,
  "WillGo" : true,
  "DateCreated" : "2016-08-24 14:01:08 +00:00"
}

在Swift 5.4中

extension Dictionary {
    var jsonData: Data? {
        return try? JSONSerialization.data(withJSONObject: self, options: [.prettyPrinted])
    }
    
    func toJSONString() -> String? {
        if let jsonData = jsonData {
            let jsonString = String(data: jsonData, encoding: .utf8)
            return jsonString
        }
        
        return nil
    }
}

把它作为变量的想法是,这样你就可以像这样重用它:

extension Dictionary {
    func decode<T:Codable>() throws -> T {
        return try JSONDecoder().decode(T.self, from: jsonData ?? Data())
    }
}