在Swift中将字典转换为JSON

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

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

得到:

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

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

349012 次浏览

斯威夫特3.0

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

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

你的假设是错误的。只是因为调试器/Playground用方括号显示你的字典(这是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!)")
}

以“pretty print "格式你可以更改选项行:

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

我对你的问题的回答如下

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: String.Encoding.utf8.rawValue)! as String


print(jsonString)

答案是

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

你问题的答案如下:

斯威夫特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)
}

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

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

斯威夫特3:

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

斯威夫特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。看到编码和解码自定义类型

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

这是一个简单的扩展来做到这一点:

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
}


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

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

使用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\"}"

这对我来说很管用:

import SwiftyJSON


extension JSON {
    

mutating func appendIfKeyValuePair(key: String, value: Any){
if var dict = self.dictionaryObject {
dict[key] = value
self = JSON(dict)
}
}
}

用法:

var data: JSON = []


data.appendIfKeyValuePair(key: "myKey", value: "myValue")

斯威夫特5:

extension Dictionary {
    

/// Convert Dictionary to JSON string
/// - Throws: exception if dictionary cannot be converted to JSON data or when data cannot be converted to UTF8 string
/// - Returns: JSON string
func toJson() throws -> String {
let data = try JSONSerialization.data(withJSONObject: self)
if let string = String(data: data, encoding: .utf8) {
return string
}
throw NSError(domain: "Dictionary", code: 1, userInfo: ["message": "Data cannot be converted to .utf8 string"])
}
}

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

2022年,swift 5

扩展的使用:

编码:

if let json = statisticsDict.asJSONStr() {
//your action with json
}

从字典解码:

json.decodeFromJson(type: [String:AppStat].self)
.onSuccess{
$0// your dictionary of type: [String:AppStat]
}

扩展:

extension Dictionary where Key: Encodable, Value: Encodable {
func asJSONStr() -> String? {
let encoder = JSONEncoder()
if let jsonData = try? encoder.encode(self) {
if let jsonString = String(data: jsonData, encoding: .utf8) {
return jsonString
}
}
        

return nil
}
}


public extension String {
func decodeFromJson<T>(type: T.Type) -> Result<T, Error> where T: Decodable {
self.asData()
.flatMap { JSONDecoder().try(type, from: $0) }
}


func asData() -> Result<Data, Error> {
if let data = self.data(using: .utf8) {
return .success(data)
} else {
return .failure(WTF("can't convert string to data: \(self)"))
}
}
}


extension JSONDecoder {
func `try`<T: Decodable>(_ t: T.Type, from data: Data) -> Result<T,Error> {
do {
return .success(try self.decode(t, from: data))
} catch {
return .failure(error)
}
}
}
 do{
let dataDict = [ "level" :
[
["column" : 0,"down" : 0,"left" : 0,"right" : 0,"row" : 0,"up" : 0],
["column" : 1,"down" : 0,"left" : 0,"right" : 0,"row" : 0,"up" : 0],
["column" : 2,"down" : 0,"left" : 0,"right" : 0,"row" : 0,"up" : 0],
["column" : 0,"down" : 0,"left" : 0,"right" : 0,"row" : 1,"up" : 0],
["column" : 1,"down" : 0,"left" : 0,"right" : 0,"row" : 1,"up" : 0],
["column" : 2,"down" : 0,"left" : 0,"right" : 0,"row" : 1,"up" : 0]
]
]
var jsonData = try JSONSerialization.data(withJSONObject: dataDict, options: JSONSerialization.WritingOptions.prettyPrinted)
let jsonStringData =  NSString(data: jsonData as Data, encoding: NSUTF8StringEncoding)! as String
print(jsonStringData)
}catch{
print(error.localizedDescription)
}