Swiftで辞書をJSONに変換する


回答:


240

Swift 3.0

Swift API設計ガイドラインNSJSONSerializationに従って、Swift 3の名前とメソッドが変更されました。

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

スウィフト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 2015

1
質問が理解できません。中括弧は何ですか?JSONで辞書をエンコードすることについて質問しましたが、それが私の答えです。
Eric Aya

1
JSON中かっこなど{"result":[{"body":"Question 3"}] }
Orkhan Alizade

2
する@OrkhanAlizade上記コールdataWithJSONObject であろう得の一部としての「中括弧」(すなわち、中括弧)を生成するNSDataオブジェクト。
Rob

ありがとう。サイドノート-(dic)tionaryを短縮するために、代わりにd0の使用を検討してください。
johndpope

165

あなたは間違った仮定をしています。デバッガ/プレイグラウンドが角括弧で辞書を表示する(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宣言でも機能します。
フレッドファウスト

@thefredelement、どのようにしてNSDataを直接Swift文字列に変換しますか?データから文字列への変換は、NSStringの関数です。
Duncan C

私はこのメソッドを実装していて、Swift文字列でデータ/エンコーディングの初期化を使用していましたが、それがSwift 1.xで使用できるかどうかはわかりません。
フレッドファウスト

私の日を救った。ありがとう。
Shobhit C 2017

回答を選択する必要があります(y)
iBug

49

スウィフト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。文字列、整数、倍精度(およびそれ以上)はすでに使用されてい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

Swift 4 Dictionary拡張。

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より安全になります!
ArtFeel、

これはエスケープ文字で印刷されますが、それを防ぐための場所はありますか?
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)

これは、いずれかの部分がnilの場合にクラッシュします。結果を強制的にアンラップすることは非常に悪い習慣です。//とにかく、他の回答にはすでに同じ情報(クラッシュなし)があります。重複したコンテンツを投稿しないでください。ありがとう。
エリックアヤ

5

あなたの質問に対する答えは以下の通りです:

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


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
ここでいくつかの間違い。なぜSwiftの辞書ではなくFoundationのNSDictionaryを使用するのですか?また、実際のJSONデータを返すのではなく、文字列を値として持つ新しい辞書を返すのはなぜですか?これは意味がありません。また、オプションとして返された暗黙的にアンラップされたオプションは、まったく良い考えではありません。
エリックアヤ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.