I am trying to send a request to an API that requires this format:
{
"inputs": [
{
"data": {
"image": {
"base64": "iVBORw0KGgoAAAIVnFT/DPAAAAAElFTkSuQmCC..."
}
}
}
]
}
This is what I tried in 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)
I got an invalid request error when trying to hit the endpoint. Not surprising - when I printed it:
let jsonString = try! JSONSerialization.jsonObject(with: jsonData, options: [])
print(jsonString)
It produced a string like this:
(
{
data = {
image = {
base64 = 1010101;
};
};
}
)
For now, I am rolling my own string. It works...but it's ugly as hell and just really not tenable.
let imageAsString = "{\"inputs\": [{\"data\": {\"image\": {\"base64\": \"\(strBase64)\"}}}]}"
My other thought was that I could create a series of embedded objects: a Data object that holds a dictionary; an Image object that holds a Data object; and an Inputs object that holds an array of Data objects.
class Image {
var base64 = Dictionary<String, String>()
}
class Data {
var image = Image()
}
class Inputs {
var inputs = [Data]()
}
But initializing them all and calling JSONSerialization.data
doesn't work as this takes a dictionary object.
I'm not really interested in pulling in 3rd party plugins for now. Any ideas on how to convert these nested objects into json using the native iOS libraries?
Absolutely! Using the Codable
protocol and JSONEncoder
in Swift 4 will do the trick:
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 {
}
If Swift 3 is your only option, then you will have to make JSONSerialization.data
work:
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 {
}