Swift içinde Sözlük JSON dönüştürmek


Yanıtlar:


240

Swift 3.0

Swift 3 ile, Swift API Tasarım Yönergeleri'neNSJSONSerialization göre adı ve yöntemleri değişti .

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

Hızlı 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
    }
}


Bir sonrakini anladım [2: A, 1: A, 3: A]. Peki ya kıvırcık parantez?
Orkhan Alizade

1
Sorunu anlamıyorum. Hangi süslü ayraçlar? JSON'da bir sözlüğü kodlamayı istediniz ve bu benim cevabım.
Eric Aya

1
JSON kıvırcık parantez, gibi{"result":[{"body":"Question 3"}] }
Orkhan Alizade

2
Yukarıdaki çağrı @OrkhanAlizade dataWithJSONObject olur elde edilen bir parçası olarak "küme parantezleri" (yani parantez) üretmek NSDatanesne.
Rob

Teşekkürler. yan not - kısaltmayı (dic) kısaltmak için d0 kullanmayı düşünün.
johndpope

166

Yanlış bir varsayım yapıyorsunuz. Hata ayıklayıcı / Playground, sözlüğünüzü köşeli parantez içinde gösterdiği için (bu, Cocoa'nın sözlükleri nasıl görüntülediği) JSON çıktısının biçimlendirildiği anlamına gelmez.

Dizelerin sözlüğünü JSON'a dönüştürecek örnek kod:

Swift 3 sürümü:

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

Yukarıdakileri "güzel yazdırılmış" biçimde görüntülemek için seçenekler satırını şu şekilde değiştirebilirsiniz:

    options: [.prettyPrinted]

Veya Swift 2 sözdiziminde:

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

Bunun çıktısı

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

Veya güzel biçimde:

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

Sözlük, JSON çıktısında beklediğiniz gibi kıvırcık parantez içine alınır.

DÜZENLE:

Swift 3/4 sözdiziminde, yukarıdaki kod şöyle görünür:

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

Normal bir Swift dizesi, JSONText bildiriminde de çalışır.
Fred Faust

@thefredelement, NSData'yı doğrudan Swift dizesine nasıl dönüştürürsünüz? Veriyi dizeye dönüştürme NSString işlevidir.
Duncan C

Bu yöntemi uyguluyordum ve bir Swift dizesinde veri / kodlama initini kullandım, Swift 1.x'te mevcut olup olmadığından emin değilim.
Fred Faust

Günümü kurtardım. Teşekkürler.
Shobhit C

cevap seçilmelidir (y)
iBug

50

Hızlı 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)
    }
}

Anahtarların ve değerlerin uygulanması gerektiğini unutmayın Codable. Dizeler, Ints ve Çiftler (ve daha fazlası) zaten Codable. Bkz . Özel Türleri Kodlama ve Kod Çözme .


26

Sorunuz için cevabım aşağıda

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)

Cevap:

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

24

Swift 4 Dictionaryuzantısı.

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

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

Bu, sorunu çözmenin iyi ve tekrar kullanılabilir bir yoludur, ancak küçük bir açıklama yeni gelenlerin sorunu daha iyi anlamalarına yardımcı olacaktır.
nilobarp

Sözlüğün anahtarları özel nesneler dizisi içeriyorsa bu uygulanabilir mi?
Raju yourPepe

2
encoding: .asciiKamuya açık uzantıda kullanmak iyi bir fikir değildir . .utf8çok daha güvenli olacak!
ArtFeel

Bu kaçış karakterleri ile yazdırır bunu önlemek için herhangi bir yerde var mı?
MikeG

23

Bazen hata ayıklama amacıyla sunucunun yanıtını yazdırmak gerekir. İşte kullandığım bir fonksiyon:

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

}

Kullanım örneği:

(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

Hızlı 3 :

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

Herhangi bir kısmı sıfır, sonuçların açılmasını zorlamak için çok kötü bir uygulama ise bu çökecektir. // Her neyse, diğer yanıtlarda zaten aynı bilgiler (kilitlenme olmadan) var, lütfen yinelenen içerik göndermekten kaçının. Teşekkürler.
Eric Aya

5

Sorunuzun cevabı aşağıda:

Hızlı 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

İşte bunu yapmak için kolay bir uzantı:

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
Burada birkaç hata var. Neden Swift'in Sözlüğü yerine Vakfın NSDictionary kullanılıyor ?! Ayrıca, gerçek JSON verilerini döndürmek yerine neden String olarak yeni bir sözlük döndürüyorsunuz? Bu mantıklı değil. Ayrıca isteğe bağlı olarak döndürülen örtük olarak kaydırılmamış isteğe bağlı gerçekten iyi bir fikir değildir.
Eric Aya
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.