Create JSON Object from Class in Swift

Create JSON Object from Class in Swift

You should look over [NSJSONSerialization] class here.

class LocationPoint {
var x: Double
var y: Double
var orientation: Double

init(x: Double, y: Double, orientation: Double) {
self.x = x
self.y = y
self.orientation = orientation
}
}

func locationPointToDictionary(locationPoint: LocationPoint) -> [String: NSNumber] {
return [
"x": NSNumber(double: locationPoint.x),
"y": NSNumber(double: locationPoint.y),
"orientation": NSNumber(double: locationPoint.orientation)
]
}

var locationPoint = LocationPoint(x: 0.0, y: 0.0, orientation: 1.0)
var dictPoint = locationPointToDictionary(locationPoint)

if NSJSONSerialization.isValidJSONObject(dictPoint) {
print("dictPoint is valid JSON")

// Do your Alamofire requests

}

how to create json object in swift 5

Not sure about JSON but according to giving JSON and code part.

JSON should be {"orderItems" : [{"product_id" : 19 , "quantity" : 2 , "size_key" : "39 40 42"}],"retailer_id":20,"status":"initial"}

JSON creator code:

var para : [String:Any] = [String:Any]()
var prodArray : [[String:Any]] = [[String:Any]]()

para["retailer_id"] = 20
para["initial"] = "status"

for product in colorsArray {
var prod : [String : Any] = [String : Any]()
if let productId = product.product?["id"] {
prod["product_id"] = productId
}

prod["quantity"] = "1"
prod["size_key"] = variabledata

prodArray.append(prod)
}

para["orderItems"] = prodArray
print(para)

Create Object from JSON Object in Swift 5

You were just missing Codable implementation with ObjSportsIcon class.

struct ObjSportsList : Codable {

var id:Int
var name:String
var slug:String
var icons:ObjSportsIcon
}

struct ObjSportsIcon : Codable {
var green:String
var grey:String
var white:String
var black:String
}

OR You can use the following code to make it proper:

public struct ObjSportsList : Codable {

var id:Int
var name:String
var slug:String
var icons:ObjSportsIcon

public init(id: Int, name: String, slug: String, icons: ObjSportsIcon) {
self.id = id
self.name = name
self.slug = slug
self.icons = icons
}

public enum CodingKeys: String, CodingKey {
case id
case name
case slug
case icons
}
}

public struct ObjSportsIcon : Codable {
var green:String
var grey:String
var white:String
var black:String

public init(green: String, grey: String, white: String, black: String) {
self.green = green
self.grey = grey
self.white = white
self.black = black
}

public enum CodingKeys: String, CodingKey {
case green
case grey
case white
case black
}
}

Change following line of code to solve your 2nd error:

self.arrSports = try decoderdec.decode(Array<ObjSportsList>.self, from: jsonData)


Update by Vivek :

I found my mistake and solution for the second error

Old code var arrSports:[[String:Any]] = []

New code var arrSports:[ObjSportsList] = []


You have to implement init(from decoder: Decoder) method to achieve the same.
Note: You have to set default values to every property

struct ObjSportsIcon : Codable {
var green:String
var grey:String
var white:String
var black:String
var pink:String

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.green = try container.decodeIfPresent(String.self, forKey: .green) ?? "green"
self.grey = try container.decodeIfPresent(String.self, forKey: .grey) ?? "grey"
self.white = try container.decodeIfPresent(String.self, forKey: .white) ?? "white"
self.black = try container.decodeIfPresent(String.self, forKey: .black) ?? "black"
self.pink = try container.decodeIfPresent(String.self, forKey: .pink) ?? "pink"
}
}

Create JSON in swift

One problem is that this code is not of type Dictionary.

let jsonObject: [Any]  = [
[
"type_id": singleStructDataOfCar.typeID,
"model_id": singleStructDataOfCar.modelID,
"transfer": savedDataTransfer,
"hourly": savedDataHourly,
"custom": savedDataReis,
"device_type":"iOS"
]
]

The above is an Array of AnyObject with a Dictionary of type [String: AnyObject] inside of it.

Try something like this to match the JSON you provided above:

let savedData = ["Something": 1]

let jsonObject: [String: Any] = [
"type_id": 1,
"model_id": 1,
"transfer": [
"startDate": "10/04/2015 12:45",
"endDate": "10/04/2015 16:00"
],
"custom": savedData
]

let valid = JSONSerialization.isValidJSONObject(jsonObject) // true

How to create the model class for the following JSON data and parse it?

After going through your JSON response, what I see is that you are getting an object which has two nodes(or properties).
First- "addon_items" which has as array and for which you have created a class AddOnItems which is correct.
Second- "addon": this key over here is reference to a 'Dictionary' rather than to an array.

So to store the response in your AddOnResponse object, try the following code.

Alamofire.request(.GET, myAddOnUrl).validate().reponseJSON { response in
switch resonse.result {
case .Success:
if let value = response.result.value {
let json = JSON(value)
let responseDictionary = json.dictionaryValue as? [String: AnyObject]
let addOnRes = AddOnResponse(addon:responseDictionary["addon"].dictionaryValue, addonitems:responseDictionary["addon_items"].arrayValue)
}
case .Failure:
break
}
}

Also make change to your AddOnResponse class

class AddOnResponse {
var addon: [String: AnyObject]?
var addonitems: Array<AnyObject>?

init(addon:[String: AnyObject]?,addonitems: Array<AnyObject>?){
self.addon = addon
self.addonitems = addonitems
}
}

TL;DR
Your JSON response doesn't properly correspond to the model you've made in your app. Double check the "addon" key of your json response which has a dictionary object to it and NOT AN ARRAY and accordingly make your model classes.

Edit: Rectifying the mistake to point the casting error.
What I would now suggest is that pass the JSON object for `add_on' key. In the AddOn class change the initialiser so that it takes a JSON object. Then initialising them using.
AddOn Class Initialiser

init(json: JSON) {
id = json["id"].intValue
name = json["name"].stringValue
// and so on
}

Similarly do the same for AddOnItems. And in the AddOnResponse initialiser iterate in a loop the JSON object for AddOnItems. Initialise it and append to the addOnItems array property.
Sorry cannot write the code for it right now. Got a time constraint.

How to generate JSON string in Swift 3?

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 {

}

Is there a way to only partially create an object from JSON in Swift?

Yes, you can do this by setting the coding keys on your Codable class. Just leave out the ones that you don't want to update from the json.

class Flashcard: Codable, Identifiable {
let id = UUID()
var status: Int = 0
let chapter: Int
let question: String
let answer: String
let reference: String

enum CodingKeys: String, CodingKey {
case chapter, question, answer, reference
}
}

There is a great article by HackingWithSwift on Codable here

How can I convert an array with custom classes to JSON in swift 3

Pretty sure you can accmoplish this with the following:

1) Create a toJSON() function in your object's class

2) Make a dictionary in this object that stores the properties and their values.

Here's an example of a couple of small classes based off your json example:

class Order {

var store: Store!
var products: [Product]!

init(store: Store, products: [Product]) {
self.store = store
self.products = products
}

func toJSON() -> [String : Any] {
var dictionary: [String : Any] = [:]

dictionary["store"] = store.toJSON()

var productsDictionary: [Int : Any] = [:]

for index in 0...self.products.count - 1 {
let product: Product = products[index]
productsDictionary[index] = product.toJSON()
}

dictionary["product"] = productsDictionary

return dictionary
}
}

class Store {

var id: Int!

init(id: Int) {
self.id = id
}

func toJSON() -> [String:Any] {
var dictionary: [String : Any] = [:]

dictionary["id"] = self.id

return dictionary
}
}

class Product {
var id: Int!
var quantity: Int!

init(id: Int, quantity: Int) {
self.id = id
self.quantity = quantity
}

func toJSON() -> [String:Any] {
var dictionary: [String : Any] = [:]

dictionary["id"] = self.id
dictionary["quantity"] = self.quantity

return dictionary
}
}

3) Follow the example link you posted

NSJSONSerialization.dataWithJSONObject(order.toJSON(), options: nil, error: nil)


Related Topics



Leave a reply



Submit