แปลง Dictionary เป็น JSON ใน Swift


188

ฉันสร้างพจนานุกรมต่อไป:

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

และฉันได้รับ:

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

ดังนั้นฉันจะแปลงเป็น JSON ได้อย่างไร


คำตอบ:


240

Swift 3.0

กับสวิฟท์ 3 ชื่อของNSJSONSerializationและวิธีการของมันมีการเปลี่ยนแปลงไปตามแนวทางการออกแบบสวิฟท์ 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.x

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


[2: A, 1: A, 3: A]ฉันจะได้รับต่อไป แต่สิ่งที่เกี่ยวกับวงเล็บปีกกา?
Orkhan Alizade

1
ฉันไม่เข้าใจคำถามของคุณ วงเล็บปีกกาอะไร คุณถามเกี่ยวกับการเข้ารหัสพจนานุกรมใน JSON และนั่นคือคำตอบของฉัน
Eric Aya

1
วงเล็บปีกกา JSON เช่น{"result":[{"body":"Question 3"}] }
Orkhan Alizade

2
@OrkhanAlizade การเรียกไปด้านบนdataWithJSONObject จะสร้าง "วงเล็บปีกกา" (เช่นวงเล็บปีกกา) เป็นส่วนหนึ่งของNSDataวัตถุที่เกิด
Rob

ขอบคุณ หมายเหตุด้าน - พิจารณาใช้ d0 แทน tionary ย่อ (dic)
johndpope

166

คุณกำลังตั้งสมมติฐานผิด เพียงเพราะดีบักเกอร์ / สนามเด็กเล่นแสดงพจนานุกรมของคุณในวงเล็บเหลี่ยม (ซึ่งเป็นวิธีที่ Cocoa แสดงพจนานุกรม) ซึ่งไม่ได้หมายความว่าเป็นวิธีที่รูปแบบเอาต์พุต JSON

นี่คือตัวอย่างรหัสที่จะแปลงพจนานุกรมของสตริงเป็น JSON:

เวอร์ชั่น Swift 3:

import Foundation

let dictionary = ["aKey": "aValue", "anotherKey": "anotherValue"]
if let theJSONData = try? JSONSerialization.data(
    withJSONObject: dictionary,
    options: []) {
    let theJSONText = String(data: theJSONData,
                               encoding: .ascii)
    print("JSON string = \(theJSONText!)")
}

หากต้องการแสดงด้านบนในรูปแบบ "พิมพ์สวย" คุณต้องเปลี่ยนบรรทัดตัวเลือกเป็น:

    options: [.prettyPrinted]

หรือในไวยากรณ์ของ Swift 2:

import Foundation
 
let dictionary = ["aKey": "aValue", "anotherKey": "anotherValue"]
let theJSONData = NSJSONSerialization.dataWithJSONObject(
  dictionary ,
  options: NSJSONWritingOptions(0),
  error: nil)
let theJSONText = NSString(data: theJSONData!,
  encoding: NSASCIIStringEncoding)
println("JSON string = \(theJSONText!)")

ผลลัพธ์ของนั่นคือ

"JSON string = {"anotherKey":"anotherValue","aKey":"aValue"}"

หรือในรูปแบบที่สวยงาม:

{
  "anotherKey" : "anotherValue",
  "aKey" : "aValue"
}

พจนานุกรมถูกล้อมรอบด้วยเครื่องหมายปีกกาในเอาต์พุต JSON ตามที่คุณคาดหวัง

แก้ไข:

ในไวยากรณ์ Swift 3/4 โค้ดด้านบนมีลักษณะดังนี้:

  let dictionary = ["aKey": "aValue", "anotherKey": "anotherValue"]
    if let theJSONData = try?  JSONSerialization.data(
      withJSONObject: dictionary,
      options: .prettyPrinted
      ),
      let theJSONText = String(data: theJSONData,
                               encoding: String.Encoding.ascii) {
          print("JSON string = \n\(theJSONText)")
    }
  }

สตริง Swift ปกติทำงานได้ดีบนประกาศ JSONText
เฟร็ด Faust

@thefredelement คุณจะแปลง NSData โดยตรงเป็นสตริง Swift ได้อย่างไร การแปลงข้อมูลเป็นสตริงเป็นฟังก์ชันของ NSString
Duncan C

ฉันใช้วิธีนี้และใช้ข้อมูล / การเข้ารหัส init บนสตริง Swift ฉันไม่แน่ใจว่ามีใน Swift 1.x หรือไม่
Fred Faust

บันทึกวันของฉัน ขอบคุณ
Shobhit C

ควรเลือกคำตอบ (y)
iBug

50

สวิฟท์ 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ต่างๆ สตริง Ints และคู่ผสม (และอื่น ๆ ) Codableมีอยู่แล้ว ดูประเภทการเข้ารหัสและถอดรหัสที่กำหนดเอง


26

คำตอบสำหรับคำถามของคุณอยู่ด้านล่าง

let dict = ["0": "ArrayObjectOne", "1": "ArrayObjecttwo", "2": "ArrayObjectThree"]

var error : NSError?

let jsonData = try! NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions.PrettyPrinted)

let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding)! as String

print(jsonString)

คำตอบคือ

{
  "0" : "ArrayObjectOne",
  "1" : "ArrayObjecttwo",
  "2" : "ArrayObjectThree"
}

24

Dictionaryส่วนขยายSwift 4

extension Dictionary {
    var jsonStringRepresentation: String? {
        guard let theJSONData = try? JSONSerialization.data(withJSONObject: self,
                                                            options: [.prettyPrinted]) else {
            return nil
        }

        return String(data: theJSONData, encoding: .ascii)
    }
}

นี่เป็นวิธีที่ดีและนำมาใช้ซ้ำในการแก้ปัญหา แต่คำอธิบายเล็กน้อยจะช่วยให้ผู้มาใหม่เข้าใจได้ดีขึ้น
nilobarp

สามารถใช้สิ่งนี้ได้หรือไม่หากคีย์ของพจนานุกรมมีอาร์เรย์ของวัตถุที่กำหนดเอง
Raju yourPepe

2
ไม่ควรใช้encoding: .asciiในส่วนขยายสาธารณะ .utf8จะปลอดภัยมากขึ้น!
Artainless

ภาพนี้พิมพ์ด้วยอักขระเลี่ยงมีที่ไหนเพื่อป้องกันหรือไม่
MikeG

23

บางครั้งจำเป็นต้องพิมพ์การตอบสนองของเซิร์ฟเวอร์เพื่อจุดประสงค์ในการดีบั๊ก นี่คือฟังก์ชั่นที่ฉันใช้:

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

10

สวิฟท์ 3 :

let jsonData = try? JSONSerialization.data(withJSONObject: dict, options: [])
let jsonString = String(data: jsonData!, encoding: .utf8)!
print(jsonString)

สิ่งนี้จะล้มเหลวหากส่วนใดส่วนหนึ่งเป็นศูนย์ // อย่างไรก็ตามมีข้อมูลเดียวกันอยู่แล้ว (โดยไม่เกิดข้อผิดพลาด) ในคำตอบอื่น ๆ โปรดหลีกเลี่ยงการโพสต์เนื้อหาที่ซ้ำกัน ขอบคุณ
Eric Aya

5

คำตอบสำหรับคำถามของคุณอยู่ด้านล่าง:

สวิฟท์ 2.1

     do {
          if let postData : NSData = try NSJSONSerialization.dataWithJSONObject(dictDataToBeConverted, options: NSJSONWritingOptions.PrettyPrinted){

          let json = NSString(data: postData, encoding: NSUTF8StringEncoding)! as String
          print(json)}

        }
        catch {
           print(error)
        }

2

ต่อไปนี้เป็นส่วนขยายที่ทำได้ง่าย:

https://gist.github.com/stevenojo/0cb8afcba721838b8dcb115b846727c3

extension Dictionary {
    func jsonString() -> NSString? {
        let jsonData = try? JSONSerialization.data(withJSONObject: self, options: [])
        guard jsonData != nil else {return nil}
        let jsonString = String(data: jsonData!, encoding: .utf8)
        guard jsonString != nil else {return nil}
        return jsonString! as NSString
    }

}

1
private func convertDictToJson(dict : NSDictionary) -> NSDictionary?
{
    var jsonDict : NSDictionary!

    do {
        let jsonData = try JSONSerialization.data(withJSONObject:dict, options:[])
        let jsonDataString = String(data: jsonData, encoding: String.Encoding.utf8)!
        print("Post Request Params : \(jsonDataString)")
        jsonDict = [ParameterKey : jsonDataString]
        return jsonDict
    } catch {
        print("JSON serialization failed:  \(error)")
        jsonDict = nil
    }
    return jsonDict
}

1
ความผิดพลาดหลายประการที่นี่ ทำไมต้องใช้ NSDictionary ของมูลนิธิแทนพจนานุกรมของ Swift! ทำไมการส่งคืนพจนานุกรมใหม่ที่มีสตริงเป็นค่าแทนที่จะส่งคืนข้อมูล JSON จริง มันไม่สมเหตุสมผล นอกจากนี้ตัวเลือกที่ไม่ได้เปิดคืนโดยอ้อมกลับมาเป็นตัวเลือกนั้นไม่ใช่ความคิดที่ดีเลย
Eric Aya
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.