Konvertieren Sie das Wörterbuch in Swift in JSON

188

Ich habe das nächste Wörterbuch erstellt:

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

und ich bekomme:

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

Wie kann ich es in JSON konvertieren?

Orkhan Alizade
quelle
1
NSJSONSerialization
Matthias Bauch

Antworten:

240

Swift 3.0

Mit Swift 3 haben sich der Name NSJSONSerializationund seine Methoden gemäß den Swift API Design Guidelines geändert .

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

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

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

Eric Aya
quelle
Ich bekomme den nächsten [2: A, 1: A, 3: A]. Aber was ist mit geschweiften Klammern?
Orkhan Alizade
1
Ich verstehe deine Frage nicht. Welche geschweiften Klammern? Sie haben nach der Codierung eines Wörterbuchs in JSON gefragt, und das ist meine Antwort.
Eric Aya
1
JSON geschweifte Klammern, wie{"result":[{"body":"Question 3"}] }
Orkhan Alizade
2
@OrkhanAlizade Der obige Aufruf von dataWithJSONObject würde die "geschweiften Klammern" (dh die geschweiften Klammern) als Teil des resultierenden NSDataObjekts erzeugen .
Rob
Vielen Dank. Randnotiz - Verwenden Sie stattdessen d0, um (Wörterbuch) abzukürzen.
Johndpope
165

Sie machen eine falsche Annahme. Nur weil der Debugger / Playground Ihr Wörterbuch in eckigen Klammern anzeigt (so zeigt Cocoa Wörterbücher an), bedeutet dies nicht, dass die JSON-Ausgabe so formatiert ist.

Hier ist ein Beispielcode, der ein Wörterbuch mit Zeichenfolgen in JSON konvertiert:

Swift 3 Version:

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

Um das Obige im "hübsch gedruckten" Format anzuzeigen, ändern Sie die Optionszeile in:

    options: [.prettyPrinted]

Oder in der Swift 2-Syntax:

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!)")

Die Ausgabe davon ist

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

Oder in hübschem Format:

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

Das Wörterbuch ist in der JSON-Ausgabe in geschweiften Klammern eingeschlossen, genau wie Sie es erwarten würden.

BEARBEITEN:

In der Swift 3/4 Syntax sieht der obige Code folgendermaßen aus:

  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)")
    }
  }
Duncan C.
quelle
Ein regulärer Swift-String funktioniert auch mit der JSONText-Deklaration.
Fred Faust
@thefredelement, Wie konvertiert man NSData direkt in einen Swift-String? Die Konvertierung von Daten in Zeichenfolgen ist eine Funktion von NSString.
Duncan C
Ich habe diese Methode implementiert und den Daten- / Codierungsinit für eine Swift-Zeichenfolge verwendet. Ich bin mir nicht sicher, ob dies für Swift 1.x verfügbar war.
Fred Faust
Hat meinen Tag gerettet. Vielen Dank.
Shobhit C
sollte Antwort (y) ausgewählt werden
iBug
49

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

Beachten Sie, dass Schlüssel und Werte implementiert werden müssen Codable. Strings, Ints und Doubles (und mehr) sind bereits vorhanden Codable. Siehe Kodieren und Dekodieren von benutzerdefinierten Typen .

Ryan H.
quelle
26

Meine Antwort auf Ihre Frage ist unten

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)

Antwort ist

{
  "0" : "ArrayObjectOne",
  "1" : "ArrayObjecttwo",
  "2" : "ArrayObjectThree"
}
user3182143
quelle
24

Swift 4 DictionaryErweiterung.

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

        return String(data: theJSONData, encoding: .ascii)
    }
}
thexande
quelle
Dies ist eine gute und wiederverwendbare Methode zur Lösung des Problems, aber eine kleine Erklärung würde Neuankömmlingen helfen, es besser zu verstehen.
Nilobarp
Könnte dies angewendet werden, wenn die Schlüssel des Wörterbuchs ein Array von benutzerdefinierten Objekten enthalten?
Raju yourPepe
2
Es ist keine gute Idee, encoding: .asciiin der öffentlichen Erweiterung zu verwenden. .utf8wird viel sicherer sein!
ArtFeel
Dieser Ausdruck mit Escapezeichen gibt es irgendwo, um das zu verhindern?
MikeG
23

Manchmal ist es notwendig, die Antwort des Servers für Debugging-Zwecke auszudrucken. Hier ist eine Funktion, die ich benutze:

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

}

Anwendungsbeispiel:

(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"
}
Andrey Gordeev
quelle
10

Swift 3 :

let jsonData = try? JSONSerialization.data(withJSONObject: dict, options: [])
let jsonString = String(data: jsonData!, encoding: .utf8)!
print(jsonString)
Bilal
quelle
Dies stürzt ab, wenn ein Teil Null ist. Dies ist eine sehr schlechte Vorgehensweise, um das Auspacken der Ergebnisse zu erzwingen. // Wie auch immer, es gibt bereits die gleichen Informationen (ohne den Absturz) in anderen Antworten. Bitte vermeiden Sie es, doppelte Inhalte zu veröffentlichen. Vielen Dank.
Eric Aya
5

Die Antwort auf Ihre Frage finden Sie unten:

Swift 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)
        }
Dheeraj D.
quelle
2

Hier ist eine einfache Erweiterung, um dies zu tun:

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
    }

}
StevenOjo
quelle
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
}
Swati Desai
quelle
1
Einige Fehler hier. Warum das NSDictionary der Foundation anstelle des Swift's Dictionary verwenden?! Warum sollte ein neues Wörterbuch mit einem String als Wert zurückgegeben werden, anstatt die tatsächlichen JSON-Daten zurückzugeben? Das macht keinen Sinn. Auch das implizit ausgepackte Optional, das als Optional zurückgegeben wird, ist überhaupt keine gute Idee.
Eric Aya