Using SwiftyJSON for subarray with Swift 3.1 - json

I have a json data. I never use SwiftyJSON before. I am trying first time.
My json like this:
[
{
"Id": 1,
"Name": "A",
"SubNames": [
{
"SubId": 1,
"SubName": "A1"
},
{
"SubId": 2,
"SubName": "A2"
}]
},
{
"Id": 2,
"Name": "B",
"SubNames": [
{
"SubId": 1,
"SubName": "B1"
},
{
"SubId": 2,
"SubName": "B2"
}]
}
]
I can handle Name and append a array. But I can't handle SubNames. I tried somethings but doesn't work unfortunately. I want to append SubNames a array. This array will be like this:
[["A1","A2"],["B1","B2"]]
I use this code:
let json = JSON(data: data!)
for (_,subJson):(String, JSON) in json {
self.names.append(subJson["Name"].stringValue
}

try this to access those fields, and you shouldn't do data! here
guard let `data` = data else {
//no data handling
return
}
let dataArray = JSON(data: data).arrayValue
var arrayOfAllSubnames: [[String]] = [[]]
for object in dataArray {
var arrayOfSubnames: [String] = []
if let subnames = object["SubNames"].array {
for subname in subnames {
//here you get `"SubId": 2, "SubName": "B2"` object
let subnameValue = subname["SubName"].stringValue
arrayOfSubnames.append(subnameValue)
}
}
arrayOfAllSubnames.append(arrayOfSubnames)
}

Swift 3.0
1) First declare sub name array.
var subNameArray: [[String]] = []
2) you can access and store this objects as below.
let json = JSON(data: data!).arrayValue
for item in json {
var tempArray: [String] = []
let name = item["Name"].stringValue
for subNameItem in items["SubNames"].arrayValue {
tempArray.append(subNameItem["SubName"].stringValue)
}
subNameArray.append(tempArray)
}

Related

Casting dictionary of sets to JSON Object

I'm trying to build request body like this form:
{
"user": {
"id": 1,
"id": 2,
"id": 4
}
}
My first idea was built json from string and cast it to dictionary String and Any, but this solution have a issue. Some "id" are missing on casting by JSONSerialization step.
I tried to use:
var dictionary: [String : Any] = ["name" : "John"]()
var selectedIDs = Set<NSDictionary>()
// Adding values to selectedIDs set
let userIDDict = ["id" : id] as NSDictionary
selectedIDs.insert(userIDDict)
dictionary.updateValue(selectedIDs, forKey: "user")
But it cannot be cast by JSONSerialization (Invalid type in JSON write).
How can i resolve problem, which i'm facing?
Creating this request is not a problem; it's just not proper JSON, so you shouldn't try to use JSONSerialization. It's just a string, and so you can create that string:
let idKeyValues = ids.map { "\"id\": \($0)" }.joined(separator: ",\n ")
let request = """
{
"user": {
\(idKeyValues)
}
}
"""
===>
{
"user": {
"id": 1,
"id": 2,
"id": 4
}
}
The proper way to express this in JSON would be:
{
"user": {
"ids": [1, 2, 4]
}
}
With that, a Codable implementation should be very straightforward.

How to parse this type of dictionary?

How to parse "interestpolls" dictionary, I want to append this poll_id in array.
I was trying by this way but it's not been working; suggest the way for parsing this dictionary.
if let result = JSON?["result"] as? String
{
if result == "success"
{
if let n=JSON?["interestpolls"] as? [String:Any]
{
//parsing code
}
}
}
How to parse this dictionary in Swift:
{
"result": "success",
"err_message": "Polls found successfully",
"err_code": "E100",
"interestpolls": [
{
"rank": 4,
"poll_id": 49,
"poll_text": "Video Image Poll ?",
"poll_type": "S",
"user_id_creator": 29,
"user_full_name": "Sam",
"profile_pic": "https://pollyscrackers.s3.amazonaws.com/users/profile_pic_29_1503498846.jpg",
"poll_visibility": "W",
"dt_created": 1503988510696,
"poll_media_url": "https://pollyscrackers.s3.amazonaws.com/polls/poll_49_1503988510.jpg",
"poll_results": {
"poll_results_vote_based": {
"totalvotes": 3,
"Yes": 3,
"No": 0
}
}
},
{
"rank": 1,
"poll_id": 6,
"poll_text": "New Poll",
"poll_type": "S",
"user_id_creator": 10,
"user_full_name": "Mohan Roy vaghela",
"profile_pic": "https://pollyscrackers.s3.amazonaws.com/users/profile_pic_10_1504077441.gif",
"poll_visibility": "W",
"dt_created": 1501746922046,
"poll_media_url": "https://pollyscrackers.s3.amazonaws.com/polls/poll_6_1501746922.jpg",
"poll_results": {
"poll_results_vote_based": {
"totalvotes": 14,
"Answer1": 7,
"Answer2": 6
}
}
},
{
"rank": 2,
"poll_id": 28,
"poll_text": "What is the way to become enterprenur",
"poll_type": "S",
"user_id_creator": 1,
"user_full_name": "Akshay",
"profile_pic": "https://pollyscrackers.s3.amazonaws.com/users/profile_pic_1_1504503078.jpg",
"poll_visibility": "W",
"dt_created": 1501746922046,
"poll_media_url": "https://pollyscrackers.s3.amazonaws.com/polls/poll_8_1502198168.jpg",
"poll_results": {
"poll_results_vote_based": {
"totalvotes": 4,
"Startup with job": 1,
"Startup without job": 3
}
}
},
{
"rank": 3,
"poll_id": 29,
"poll_text": "Who is best prgrammer in world",
"poll_type": "S",
"user_id_creator": 1,
"user_full_name": "Akshay",
"profile_pic": "https://pollyscrackers.s3.amazonaws.com/users/profile_pic_1_1504503078.jpg",
"poll_visibility": "W",
"dt_created": 1501746922046,
"poll_media_url": "https://pollyscrackers.s3.amazonaws.com/polls/poll_8_1502198168.jpg",
"poll_results": {
"poll_results_vote_based": {
"totalvotes": 4,
"AKS": 2,
"SASK": 2
}
}
}
]
}
You are casting it as interest polls as Dictionary, cast it as an array. Try the following code.
var pollIDList = [String]()
if let result = JSON?["result"] as? String {
if result == "success" {
let array = JSON?["interestpolls"] as? Array
pollIDList.append(array["poll_id"])
}
}
Try this :
if let result = JSON?["result"] as? String
{
if result == "success"
{
if let n=JSON?["interestpolls"] as? [[String:Any]]
{
for data in n {
if let id = data["poll_id"] as? String {
self.pollIDList.append(id)
}
}
}
}
}
As "as diu" points out, your interestpolls key/value pair contains an array, not a dictionary.
Another point is that you can create a complex if statement rather than nesting a whole bunch of ifs:
if let result = JSON?["result"] as? String,
result == "success",
let polls = JSON?["interestpolls"] as? [[String: Any]] {
for aPollDict in polls {
//your code to parse a poll here
}
}

Creating Model using Swifty JSon Model

[
{
"_id": "1212323",
"row": 1,
"column": 1,
"displayType": 0,
"item": {
"type": "category_",
"data": {
"_id": "595a1446cb91951900b0b4b0",
"title": "something",
"fullImage": "http://assets.something.mobi/curated/something (2).jpg",
"halfImage": "http://assets.something.mobi/curated/something (1).jpg"
}
}
},
{
"_id": "595a148ccb91951900b0b4b5",
"row": 2,
"column": 1,
"displayType": 1,
"item": {
"type": "curatedlist",
"data": {
"_id": "595b34abcb9195190c0ae378",
"active": "true",
"title": "sample something list",
"fullImage": "http://assets.something.mobi/curated/something (2).jpg",
"halfImage": "http://assets.something.mobi/curated/something (2).jpg"
}
}
}
]
very new to SwiftyJSON and Alamofire some one please help me to create a model for it im able get JSON responce using almofire but not able to create a proper swifty json model for this
I have done this using two separate model classes, one to directly map all the values and other used to fetch directly as an array from it.
For some who just starting or stuck with creating model and mapping values can try these or someone is an expert can suggest a better solution to improve the implementation
1.CategoryModel: NSObject
import UIKit
import SwiftyJSON
class CategoryModel: NSObject {
var resultArray : NSArray!
var _id : String!
var row : NSInteger!
var column : NSInteger!
var displayType : NSInteger!
var type : String?
var _id1 : String?
var title : String?
var fullImage : String?
var halfImage : String?
// var item
required init(JsonDashBoard: JSON) {
_id = JsonDashBoard["_id"].stringValue
row = JsonDashBoard["row"].intValue
column = JsonDashBoard["column"].intValue
displayType = JsonDashBoard["displayType"].intValue
//MARK:- Inside Item Dictionary
type = JsonDashBoard["item"]["type"].stringValue
//MARK:- Inside Item/dataDictionary
_id1 = JsonDashBoard["item"]["data"]["_id"].stringValue
title = JsonDashBoard["item"]["data"]["title"].stringValue
fullImage = JsonDashBoard["item"]["data"]["fullWidthImage"].stringValue
halfImage = JsonDashBoard["item"]["data"]["halfWidthImage"].stringValue
}
}
2.CategoryListModel:NSObject
import UIKit
class CategoryListModel: NSObject {
var items : NSArray? = nil;
required init(_items: NSMutableArray) {
self.items = _items
}
}
and using these model classes you can map values using the below code snipet
manager.request(routeUrl, method: .get).responseJSON { (responseObject) -> Void in
if responseObject.result.isSuccess {
let resJson = JSON(responseObject.result.value!)
let categoryList = NSMutableArray()
for (_,subJson):(String, JSON) in resJson {
let model = CategoryModel(JsonDashBoard: subJson)
categoryList.add(model)
//Do something you want
print(subJson)
}
let categoryListModel = CategoryListModel(_items: categoryList)
success(categoryListModel)
}
if responseObject.result.isFailure {
let error : Error = responseObject.result.error!
failure(error)
}
}

Get JSON element swift

I am working receiving the following JSON file in Swift and I cant figure out how get the details elements in the JSON
[
{
"id": 143369,
"history": "jd2",
"details": [
{
"name": "Su 1",
"color": "#ffffff"
},
{
"name": "Stu 1",
"color": "#ffffff"
}
]
},
{
"id": 143369,
"history": "musa 2",
"details": [
{
"name": "Stu 1",
"color": "#ffffff"
},
{
"name": "Stu 2",
"color": "#ffffff"
}
]
}
]
I have created this class with which I am able to retrieve id and history but not the details. How do I include the details with the id and history?
public class students {
let id: Int32
let history: String?
init(id:Int32, history:String) {
self.id = id
self.history = name
}
}
Below is my web service code.
var dataArray = [students]()
Alamofire.request(.GET, url)
.responseJSON { response in
if let value: AnyObject = response.result.value {
let json = JSON(value)
if let items = json.array {
for item in items {
self.dataArray.append(students(
id: item["id"].int32!,
history: item["history"].string!))
let cItems = item["details"].array
for citem in citems {
//here
}
}
}
}
}
your student model should be like this.
let id: Int32
let history: String?
let details: Array<[String:AnyObject]>
init(id:Int32, history:String,details:Array<[String:AnyObject]>) {
self.id = id
self.history = name
self.details= details //need a cast here!
}
here is a simple parser for i used for a project to cast your Array<[String:AnyObject]> as you
func collection(data:[[String:AnyObject]]) -> [yourModel] {
var objectArray: [yourModel] = []
for d in data {
let obj = yourModel(data: d as [String: AnyObject]) // i created a initializer for this object here on my project.
objectArray.append(obj)
}
return objectArray
}
hope gives an idea!

How to parse JSON in Swift?

I have some JSON data that looks like this which I am trying to parse in Swift.
[
[
{
a: "1",
b: "2"
},
[
{
c: "3",
},
{
d: "4",
}
]
]
]
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
if let myArray = json[0] as? [[AnyObject]] {
for myObject in myArray {
print("This works!\(myObject)")
}
}
However nothing I try seems to work - any help would be appreciated.
you can use SwiftyJSON - https://github.com/SwiftyJSON/SwiftyJSON
or create a class based on your JSON scheme try to parse with it.
like:
class object
{
let data = Array<subObject>()
}
class subObject
{
let subData = Array<Dictionary<AnyObject,AnyObject>>()
}
This snippet is not JSON. If it was JSON, the keys would be strings, like this:
[
[
{
"a": "1",
"b": "2"
},
[
{
"c": "3",
},
{
"d": "4",
}
]
]
]
And anyway in your screenshot we see that your JSON has already been parsed!
What you show in the image is not JSON either, but an array containing arrays and dictionaries...
But let's say your JSON is actually valid and the missing quotes are just a copy/paste problem.
Then to achieve your goal you have to cast the result of NSJSONSerialization to the correct JSON format, then you can access the inner objects.
Like this, for example:
do {
if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [[AnyObject]] {
if let myArray = json.first {
for myObject in myArray {
print("This works!\(myObject)")
}
}
}
} catch let error as NSError {
print(error.localizedDescription)
}