【问题标题】:How to generate JSON string in Swift 3?如何在 Swift 3 中生成 JSON 字符串?
【发布时间】:2018-07-27 22:12:28
【问题描述】:

我正在尝试向需要此格式的 API 发送请求:

{
    "inputs": [
        {
            "data": {
                "image": {
                    "base64": "iVBORw0KGgoAAAIVnFT/DPAAAAAElFTkSuQmCC..."
                }
            }
        }
    ]
}

这是我在 Swift 3 中尝试过的:

let base64 = ["base64": "1010101..."]

let image: [String: Any] = ["image": base64]

let data: [String: Any] = ["data": image]

var input = [Dictionary<String, Any>]()

input = [data]

let jsonData = try! JSONSerialization.data(withJSONObject: input, options: .prettyPrinted)

尝试访问端点时出现无效请求错误。不足为奇 - 当我打印出来时:

let jsonString = try! JSONSerialization.jsonObject(with: jsonData, options: [])

print(jsonString)

它产生了这样的字符串:

(
        {
        data =         {
            image =             {
                base64 = 1010101;
            };
        };
    }
)

现在,我正在滚动自己的字符串。它有效……但它丑得要命,而且真的站不住脚。

let imageAsString = "{\"inputs\": [{\"data\": {\"image\": {\"base64\": \"\(strBase64)\"}}}]}"

我的另一个想法是我可以创建一系列嵌入对象:一个包含字典的 Data 对象;一个包含 Data 对象的 Image 对象;和一个包含 Data 对象数组的 Inputs 对象。

class Image {
    var base64 = Dictionary<String, String>()
}

class Data {
    var image = Image()
}

class Inputs {
    var inputs = [Data]()
}

但是初始化它们并调用JSONSerialization.data 不起作用,因为这需要一个字典对象。

我现在对引入 3rd 方插件并不感兴趣。关于如何使用原生 iOS 库将这些嵌套对象转换为 json 的任何想法?

【问题讨论】:

  • 你打印的是input而不是jsonData吗?
  • 没有。但我很感激你问。我编辑了问题以添加我打印 json 数据的方式。
  • 您没有打印 JSON,而是将其转换回 Foundation 对象的结果。 – 试试print(String(data: jsonData, encoding: .utf8)!),你会发现你的 JSON 正确的。

标签: ios json swift clarifai


【解决方案1】:

绝对!在 Swift 4 中使用 Codable 协议和 JSONEncoder 就可以了:

struct ImageObj: Codable {
    let base64: String
}

struct DataObj: Codable {
    let image: ImageObj
}

struct InputObj: Codable {
    let data: DataObj
}

struct InputsContainerObj: Codable {
    let inputs: [InputObj]
}

let imageObj = ImageObj(base64: "abc123")
let dataObj = DataObj(image: imageObj)
let inputObj = InputObj(data: dataObj)
let inputsContainerObj = InputsContainerObj(inputs: [inputObj])

let encoder = JSONEncoder()
do {
    let jsonData = try encoder.encode(inputsContainerObj)
    let jsonString = String(data: jsonData, encoding: .utf8)!

    print(jsonString) //{"inputs":[{"data":{"image":{"base64":"abc123"}}}]}
} catch _ as NSError {

}

如果 Swift 3 是您唯一的选择,那么您必须让 JSONSerialization.data 工作:

let dict = ["inputs": [["data": ["image": ["base64": "abc123"]]]]]
do {
    let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
    let jsonString = String(data: jsonData, encoding: .utf8)!

    print(jsonString)

    /*
    {
        "inputs" : [
            {
            "data" : {
                "image" : {
                    "base64" : "abc123"
                }
            }
            }
        ]
    }
    */

} catch _ as NSError {

}

【讨论】:

  • 我认为这是我升级到 Xcode 10 和 Swift 4 的借口。您的 Swift 4 解决方案效果很好。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
  • 2015-04-17
相关资源
最近更新 更多