How to parse tree format Hierarchies Level in
ResponseData from API call currently It hold two Level Hierarchies
{
"result" : [
{
"name": "HIERARCHIES LEVELS",
"hierarchies" : [
{
"hierarchy_order" : 1,
"hierarchy_level" : 1,
"name": "LEVEL ONE",
"hierarchies" : [
{
"hierarchy_order" : 1,
"hierarchy_level" : 2,
"name": "LEVEL TWO",
"hierarchies" : [
],
"is_enabled" : true
}
],
"is_enabled" : true
},
{
"hierarchy_order" : 1,
"hierarchy_level" : 1,
"name": "LEVEL ONE",
"hierarchies" : [
{
"hierarchy_order" : 1,
"name" : "LEVEL TWO",
"hierarchy_level" : 2,
"hierarchies" : [
],
"is_enabled" : true
},
{
"hierarchy_order" : 1,
"name" : "LEVEL TWO",
"hierarchy_level" : 2,
"hierarchies" : [
],
"is_enabled" : true
}
],
"is_enabled" : true
}
]
}
]
}
ModelClass
struct AssignedHierarchyLevelModel {
let result: [Result]?
init(_ json: JSON) {
result = json["result"].arrayValue.map { Result($0) }
}
struct Result {
let name: String?
let hierarchies: [Hierarchies]?
init(_ json: JSON) {
name = json["name"].stringValue
hierarchies = json["hierarchies"].arrayValue.map { Hierarchies($0) }
}
}
struct Hierarchies {
let hierarchyOrder: Int?
let hierarchyLevel: Int?
let name: String?
let hierarchies: [Hierarchies]?
let isEnabled: Bool?
init(_ json: JSON) {
hierarchyOrder = json["hierarchy_order"].intValue
hierarchyLevel = json["hierarchy_level"].intValue
name = json["name"].stringValue
hierarchies = json["hierarchies"].arrayValue.map { Hierarchies($0) }
isEnabled = json["is_enabled"].boolValue
}
}
struct Hierarchies {
let hierarchyOrder: Int?
let hierarchyLevel: Int?
let name: String?
let hierarchies: [Hierarchies]?
let isEnabled: Bool?
init(_ json: JSON) {
hierarchyOrder = json["hierarchy_order"].intValue
hierarchyLevel = json["hierarchy_level"].intValue
name = json["name"].stringValue
hierarchies = json["hierarchies"].arrayValue.map { Hierarchies($0) }
isEnabled = json["is_enabled"].boolValue
}
}
}
After Response
var assignedhierarchyResult = [AssignedHierarchyLevelModel.Result]()
func dataBindAccountSettingHierarchyLevel(){
hierarchyParentList.removeAll()
self.assignedhierarchyResult = self.assignedHierarchyLevelModel?.result ?? []
}
// TableView Datasource Delegate Methods
func numberOfChild(assignedhierarchyChilds: [AssignedHierarchyLevelModel.Result]) -> Int {
var arrayCount = [AssignedHierarchyLevelModel.Result.Hierarchies]()
assignedhierarchyChilds.enumerated().forEach { (indexValue,element) in
arrayCount.append(contentsOf: assignedhierarchyChilds[indexValue].hierarchies ?? [])
if arrayCount[indexValue].hierarchies?.count ?? 0 > 0 {
arrayCount[indexValue].hierarchies?.enumerated().forEach({ (subIndex, subElement) in
arrayCount.append(contentsOf: arrayCount[indexValue].hierarchies?[subIndex].hierarchies ?? [])
})
}
}
return arrayCount.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.numberOfChild(assignedhierarchyChilds: assignedhierarchyResult)
}
func numberOfSections(in tableView: UITableView) -> Int {
return assignedhierarchyResult.count
}
Trying to Hierarchy Level for tableview like AccordionLevels unable to wrappe my data set from response date. In normal tableview i display its shown Root-Parent and Child in tableview list. Unable to get sublist of child.
How to get extract data from subChild of [Hierarchies] till the end of subElement of [Hierarchies]?
to easily create Models(class/structs) for your json use Link :- https://app.quicktype.io/
And use json decoder to decode
let decoder = JSONDecoder()
let loadedData = try? decoder.decode(struc.self, from: jsonData)
-> Your Model
struct Welcome: Codable {
var result: [Result]?
}
// MARK: - Result
struct Result: Codable {
var name: String?
var hierarchies: [Hierarchy]?
}
// MARK: - Hierarchy
struct Hierarchy: Codable {
var hierarchyOrder, hierarchyLevel: Int?
var name: String?
var hierarchies: [Hierarchy]?
var isEnabled: Bool?
enum CodingKeys: String, CodingKey {
case hierarchyOrder = "hierarchy_order"
case hierarchyLevel = "hierarchy_level"
case name, hierarchies
case isEnabled = "is_enabled"
}
}
-> now you can easily use it like
let myStrut = Welcome()
myStruct.result[Index].hierarchies[Index].name
Related
I am stuck on parsing JSON. The structure is really hard. I was trying this with a decodable approach.
import UIKit
struct WeatherItem: Decodable {
let title: String?
let value: String?
let condition: String?
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
print("hello")
let jsonUrlString = "http://virtualflight.ddns.net/api/weather.php?icao=ehrd"
guard let url = URL(string: jsonUrlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
var arr = [WeatherItem]()
do {
let res = try JSONDecoder().decode([String:[[String]]].self, from: data)
let content = res["title"]!
content.forEach {
if $0.count >= 3 {
arr.append(WeatherItem(title:$0[0],value:$0[1],condition:$0[2]))
}
}
print(arr)
} catch {
print(error)
}
}
}
}
The json is the following:
{
"temperature": {
"value_c": 11,
"value_f": 285,
"condition": "Good",
"value_app": "11 \u00b0C (285 \u00b0F)"
},
"visibility": {
"value_km": 10,
"value_m": 6.2,
"condition": "Good",
"value_app": "10 KM (6.2 Mi)"
},
"pressure": {
"value_hg": 29.4,
"value_hpa": 996,
"condition": "Good",
"value_app": "29.4 inHg (996 hPa)"
},
"wind": {
"value_kts": 20,
"value_kmh": 37,
"value_heading": 280,
"condition": "Bad",
"value_app": "280\u00b0 at 20 KTS (37 Km\/H)"
},
"station": "EHRD",
"metar": "EHRD 141355Z AUTO 28020KT 250V320 9999 SCT038 BKN043 BKN048 11\/07 Q0996 NOSIG",
"remarks": "NOSIG",
"weather_page_ios_simple": [
[
"Temperature",
"11 \u00b0C (285 \u00b0F)",
"Good"
],
[
"Visibility",
"10 KM (6.2 Mi)",
"Good"
],
[
"Pressure",
"29.4 inHg (996 hPa)",
"Good"
],
[
"Wind",
"280\u00b0 at 20 KTS (37 Km\/H)",
"Bad"
],
[
"Metar",
"EHRD 141355Z AUTO 28020KT 250V320 9999 SCT038 BKN043 BKN048 11\/07 Q0996 NOSIG",
"Unknown"
],
[
"Remarks",
"NOSIG",
"Unknown"
],
[
"Station",
"EHRD",
"Unknown"
],
[
"UICell",
"iOS 12",
"siri_weather_cell"
]
]
}
any ideas how to do this?? I only need the last array, weather_page_ios_simple.
Have a look at https://app.quicktype.io it will give you the data structure for your JSON.
import Foundation
struct Welcome: Codable {
let temperature: Temperature
let visibility: Visibility
let pressure: Pressure
let wind: Wind
let station, metar, remarks: String
let weatherPageIosSimple: [[String]]
enum CodingKeys: String, CodingKey {
case temperature, visibility, pressure, wind, station, metar, remarks
case weatherPageIosSimple = "weather_page_ios_simple"
}
}
struct Pressure: Codable {
let valueHg: Double
let valueHpa: Int
let condition, valueApp: String
enum CodingKeys: String, CodingKey {
case valueHg = "value_hg"
case valueHpa = "value_hpa"
case condition
case valueApp = "value_app"
}
}
struct Temperature: Codable {
let valueC, valueF: Int
let condition, valueApp: String
enum CodingKeys: String, CodingKey {
case valueC = "value_c"
case valueF = "value_f"
case condition
case valueApp = "value_app"
}
}
struct Visibility: Codable {
let valueKM: Int
let valueM: Double
let condition, valueApp: String
enum CodingKeys: String, CodingKey {
case valueKM = "value_km"
case valueM = "value_m"
case condition
case valueApp = "value_app"
}
}
struct Wind: Codable {
let valueKts, valueKmh, valueHeading: Int
let condition, valueApp: String
enum CodingKeys: String, CodingKey {
case valueKts = "value_kts"
case valueKmh = "value_kmh"
case valueHeading = "value_heading"
case condition
case valueApp = "value_app"
}
}
If you only need the bottom array of data, you shouldn't need to put everything into the decoded struct. Just decode the part of the response you want and pull the data from there. Also, that array of data isn't really parsing JSON without keys. Its just an array of strings, you'll have to rely on the fact that index 0 is always title, 1 is always value, and 2 is always condition. Just do some validation to make sure it fits your needs. Something like this (UNTESTED)
struct WeatherItem {
let title: String?
let value: String?
let condition: String?
init(title: String?, value: String?, condition: String?) {
self.title = title
self.value = value
self.condition = condition
}
}
struct WeatherResponse: Decodable {
var weatherItems: [WeatherItem]
private enum CodingKeys: String, CodingKey {
case weatherItems = "weather_page_ios_simple"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let weatherItemArrays = try container.decode([[String]].self, forKey: .weatherItems)
weatherItems = []
for weatherItemArray in weatherItemArrays {
var title: String?
if weatherItemArray.count > 0 {
title = weatherItemArray[0]
}
var value: String?
if weatherItemArray.count > 1 {
value = weatherItemArray[1]
}
var condition: String?
if weatherItemArray.count > 2 {
condition = weatherItemArray[2]
}
weatherItems.append(WeatherItem(title: title, value: value, condition: condition))
}
}
}
And then when you get your api response get the weather items out with something like
do {
let weatherResponse = try JSONDecoder().decode(WeatherResponse.self, from: <YOUR API RESPONSE DATA>)
let weatherItems = weatherResponse.weatherItems
<DO WHATEVER YOU WANT WITH THE WEATHER ITEMS>
} catch let error {
print(error)
}
My response is :
[
{
"menu_code" : "NDS",
"items" : [
{
"unit" : "Nos",
"name" : "Chapathi\/Pulkas",
"quantity" : 2
},
{
"unit" : "Cup",
"name" : "Palya\/Curry",
"quantity" : 1
}
],
"is_active" : 1,
"image" : "nds.jpg",
"menu_name" : "Normal Diet South"
},
{
"menu_code" : "NCCD",
"items" : [
{
"menu_code" : "NDS",
"name" : "Monday"
},
{
"menu_code" : "NDN",
"name" : "Tuesday"
}
],
"is_active" : 1,
"image" : "NCCD.jpg",
"menu_name" : "Normal Combo Corporate Diet"
}
]
Today 2 format i have .In this both format only my data will come from response.And i need to show them in collection view.
My api call :
func getAllCatogory(){
TransportManager.sharedInstance.AllCatogory { (dt, err) in
if let _ = err{
}else{
if let data = dt as? String {
let pro = Mapper<AllCatagories>().map(JSONString: data)
print(data) // getting data
print(pro as Any) // getting nil
}
}
}
}
My model :
class AllCatagories: Mappable{
var menu_code = ""
var items: Array<AllCatProducts> = []
var is_active = 0
var image = ""
var menu_name = ""
required init?(map: Map) {
}
init() {
}
func mapping(map: Map) {
menu_name <- map["menu_name"]
is_active <- map["is_active"]
menu_code <- map["menu_code"]
image <- map["image"]
items <- map["items"]
}
}
Below i have created one more model class for the item inside my json.
class AllCatProducts: Mappable{
var name = ""
var quantity = 0
var unit = ""
var menu_code = ""
required init?(map: Map) {
}
init() {
}
func mapping(map: Map) {
name <- map["name"]
quantity <- map["quantity"]
unit <- map["unit"]
menu_code <- map["menu_code"]
}
}
The issues is i am getting nil in my pro.Not sure when i am doing wrong.
Thanks
You can try
struct AllCatagories: Codable {
let menuCode: String
let items: [AllCatProducts]
let isActive: Int
let image, menuName: String
}
struct AllCatProducts: Codable {
let unit: String?
let name: String
let quantity: Int?
let menuCode: String?
}
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
guard let str = dt as? String else { return }
let res = try decoder.decode([AllCatagories].self, from:str.data(using: .utf8)!)
print(res)
}
catch {
print(error)
}
I have the json list of :
[
{
"title": "Languages",
"name_list": [
{
"title": "Hindi",
"locked": true
},
{
"title": "Hindi1",
"locked": true
},
{
"title": "Hindi2",
"locked": false
},
{
"title": "Hindi3",
"locked": true
},
{
"title": "Hindi4",
"locked": false
}],
},
{
"title": "Subject",
"name_list": [
{
"title": "Hindi4",
"locked": false
},
{
"title": "Hindi4",
"locked": true
},
{
"title": "Hindi4",
"locked": true
}]
}
]
I am using table view and inside table view i have collection view.
Now in my table view i will show the title .And in my collection view i will show the name_list title on each collection view cell. Now it's working fine.
What i needs is, as you can see in the json, that have many locked = true and false.
So, In my table view- which object have less locked == false. that title i needs to show as first. For example.
In my above json, title = subject have only one locked = false, but title = language have 2 locked = false. So in my table view first subject have to display and language.
Same in each collection view, which object have locked = false that needs to display first in my collection view cell.
Any help please.
Here is my code of table view :
cellTitleLabel.text = jsonData?["title"] as? String ?? ""
in my collection view :
if let gamesList = jsonData?["name_list"] as? [[String: Any]] {
let Info = nameList[indexPath.item]
collectionCell.cellTitleLabel.text = Info["title"] as? String ?? ""
}
var Info: [String: Any]?{
didSet {
cellTitleLabel.text = jsonData?["title"] as? String ?? ""
collectionView.reloadData();
guard let gamesList = jsonData?["name_list"] as? [[String: Any]] else {
return
}
}
}
My solution here is to create a function in your tableview cell and call it at cellForRowAt indexPath with the corresponding array. And you can call the function simply by cell. fillCollectionView(array).
class ExampleTableViewCell: UITableViewCell {
#IBOutlet weak var exampleCollectionView: UICollectionView!
var array = [[String:Any]]()
func fillCollectionView(with array: [[String:Any]]) {
self.array = array
exampleCollectionView()
}
In this case, If you want to display locked == false as first then you need to rearrange your dictionary of array(sort by locked). and then load data into UItableview and UIcollectionview
Just use this function and it will work for you without creating any models.
func sortArr(array : [[String:Any]]) -> [[String:Any]]{
var arr = array
for i in 0...arr.count - 1 {
var dict = arr[i]
let name_list = dict["name_list"] as! [[String:Any]]
let lockedItems = name_list.filter { (item) -> Bool in
let locked = item["locked"] as! Bool
if locked == false {
return true
}
return false
}
print(lockedItems.count)
dict["lockedItems"] = lockedItems.count
arr[i] = dict
}
arr = arr.sorted(by: { (item1, item2) -> Bool in
let lockedcount1 = item1["lockedItems"] as! Int
let lockedcount2 = item2["lockedItems"] as! Int
return lockedcount1 < lockedcount2
})
return arr
}
EDITED
import UIKit
var arr = [
[
"title": "Languages",
"name_list": [
[
"title": "Hindi",
"locked": true
],
[
"title": "Hindi1",
"locked": true
],
[
"title": "Hindi2",
"locked": false
],
[
"title": "Hindi3",
"locked": true
],
[
"title": "Hindi4",
"locked": false
]],
],
[
"title": "Subject",
"name_list": [
[
"title": "Hindi4",
"locked": false
],
[
"title": "Hindi4",
"locked": true
],
[
"title": "Hindi4",
"locked": true
]]
]
]
func sortArr(array : [[String:Any]]) -> [[String:Any]]{
var arr = array
for i in 0...arr.count - 1 {
var dict = arr[i]
let name_list = dict["name_list"] as! [[String:Any]]
let lockedItems = name_list.filter { (item) -> Bool in
let locked = item["locked"] as! Bool
if locked == false {
return true
}
return false
}
print(lockedItems.count)
dict["lockedItems"] = lockedItems.count
arr[i] = dict
}
arr = arr.sorted(by: { (item1, item2) -> Bool in
let lockedcount1 = item1["lockedItems"] as! Int
let lockedcount2 = item2["lockedItems"] as! Int
return lockedcount1 < lockedcount2
})
return arr
}
var array = sortArr(array: arr)
print(array)
I used this below json for dummy
[
{
"title": "Languages",
"name_list": [
{
"title": "Sub 1",
"locked": true
},
{
"title": "Sub 2",
"locked": true
},
{
"title": "Sub 3",
"locked": false
},
{
"title": "Sub 4",
"locked": true
},
{
"title": "Sub 5",
"locked": false
}
]
},
{
"title": "Subject",
"name_list": [
{
"title": "Sub 6",
"locked": false
},
{
"title": "Sub 7",
"locked": false
},
{
"title": "Sub 8",
"locked": false
}
]
}
]
Model Struct for this json :
public struct TestModel {
public var nameList : [NameList]
public var title : String
}
public struct NameList {
public var locked : Bool
public var title : String
}
My json is in local project, so I use this below func to
func getLocalData(){
let url = Bundle.main.url(forResource: "testjson", withExtension: "json")!
do {
let jsonData = try Data(contentsOf: url)
let json = try JSONSerialization.jsonObject(with: jsonData) as! [Any]
self.arrData = self.createDataModel(json)
}
catch {
print(error)
}
}
Func to bind the json into model struct
func createDataModel (_ json : [Any]) -> [TestModel] {
var arr = [TestModel]()
for adata in json {
let aDictItems = adata as! [String : Any]
let aNameListData = aDictItems["name_list"] as! [Any]
var arrNameList = [NameList]()
for aName in aNameListData {
let adictname = aName as! [String : Any]
arrNameList.append(NameList.init(locked: adictname["locked"] as! Bool, title: adictname["title"] as! String ))
}
arr.append(TestModel.init(nameList: arrNameList, title: aDictItems["title"] as! String))
}
return arr
}
And in last, func that sort your list into the number of locked count (false) and return back filtered data.
func filterData (_ searchText : String) -> [TestModel] {
if searchText == "" { return arrData }
let s = arrData.sorted { (res1, res2) -> Bool in
var count1 = 0, count2 = 0
for r in res1.nameList {
if !r.locked {
count1 += 1
}
}
for r in res2.nameList {
if !r.locked {
count2 += 1
}
}
return count1 > count2
}
let f = s.filter {
$0.nameList.contains(where: { (aNameRes) -> Bool in
aNameRes.title.contains(searchText)
})
}
return f
}
Edit : To Show data in cell
tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return filtered.Count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
:
// filtered[indexPath.row].title // your tableview cell title
// filtered[indexPath.item].nameList // your collectView Data, Use this array to show data in collectionview
}
Note: Your API json Data and filtered data is always be same. When there is no string in the search bar then you need to toggle filtered data with api original data.
If something change in your requirement then let me know.
struct Root {
let nameList: [NameList]
let title : String
init(dictionary: [String: Any]) {
self.title = dictionary["title"] as? String ?? ""
self.nameList = (dictionary["name_list"] as? [[String:Any]] ?? []).map(NameList.init)
}
}
struct NameList {
let locked: Bool
let title: String
init(dictionary: [String: Any]) {
self.locked = dictionary["locked"] as? Bool == true
self.title = dictionary["title"] as? String ?? ""
}
}
let jsonData = Data("""
[
{
"title" : "Languages",
"name_list" : [
{
"title" : "Hindi",
"locked" : true
},
{
"title" : "Hindi1",
"locked" : true
},
{
"title" : "Hindi2",
"locked" : false
},
{
"title" : "Hindi3",
"locked" : true
},
{
"title" : "Hindi4",
"locked" : false
}
]
},
{
"title" : "Subject",
"name_list" : [
{
"title" : "Hindi4",
"locked" : false
},
{
"title" : "Hindi4",
"locked" : true
},
{
"title" : "Hindi4",
"locked" : true
}
]
}
]
""".utf8)
let dictionaries = (try? JSONSerialization.jsonObject(with: jsonData)) as? [[String:Any]] ?? []
print("\nAll Models", terminator: "\n============\n")
let models = dictionaries.map(Root.init)
for model in models {
print(model.title)
for name in model.nameList {
print(name.title)
}
}
print("\nunlockedModels", terminator: "\n============\n")
let unlockedDictionary: [String: [NameList]] = models.reduce(into: [:]) {
$0[$1.title] = $1.nameList.filter{ $0.locked}
}
for (title, nameList) in unlockedDictionary {
print(title)
for name in nameList {
print(name.title)
}
}
I'm trying to take my JSON from a HTTP POST and put it in a multidimensional array to use for sections / table cells in Swift.
I would like each table section to use these dynamic keys (submitid) and insert the cell data for each:
15302992338145
15301374235890
15302930963080
My JSON:
let swiftyJsonVar = JSON(data!)
{
"data" : {
"15302992338145" : [
{
"date" : "2018-06-27",
"username" : "user1",
"submitid" : 15302992338145,
"notes" : "Testing"
},
{
"date" : "2018-06-28",
"username" : "user1",
"submitid" : 15302992338145,
"notes" : "Testing"
}
],
"15301374235890" : [
{
"date" : "2018-06-21",
"username" : "user2",
"submitid" : 15301374235890,
"notes" : "Comments one two three"
},
{
"date" : "2018-06-22",
"username" : "user2",
"submitid" : 15301374235890,
"notes" : "N/A"
}
],
"15302930963080" : [
{
"date" : "2018-07-03",
"username" : "user3",
"submitid" : 15302930963080,
"notes" : "Hello"
}
]
}
}
I've tried but with no luck:
if let resData = swiftyJsonVar["data"][].arrayObject {
self.arrRes = resData as! [String: [[String:AnyObject]]]
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return arrRes.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath)
// Configure the cell...
var dict = arrRes[indexPath.section][indexPath.row]
cell.dateLabel?.text = dict["date"]
return cell
}
You should stop using SwiftyJSON and move up to Swift 4 and Decodable:
struct User : Decodable {
let date : String
let username : String
let submitid : Int
let notes : String
}
struct Result : Decodable {
let data : [[User]]
struct AnyCodingKey : CodingKey {
var stringValue: String
var intValue: Int?
init(_ codingKey: CodingKey) {
self.stringValue = codingKey.stringValue
self.intValue = codingKey.intValue
}
init(stringValue: String) {
self.stringValue = stringValue
self.intValue = nil
}
init(intValue: Int) {
self.stringValue = String(intValue)
self.intValue = intValue
}
}
init(from decoder: Decoder) throws {
let con = try! decoder.container(keyedBy: AnyCodingKey.self)
let intermediate = try! con.decode([String:[User]].self,
forKey: AnyCodingKey(stringValue:"data"))
var data = [[User]]()
for d in intermediate {
data.append(d.value)
}
self.data = data
}
}
// jsondata is your original JSON data, as you downloaded it
let result = try! JSONDecoder().decode(Result.self, from: jsondata)
After that, result.data is an array of array of User.
[[User(date: "2018-07-03", username: "user3",
submitid: 15302930963080, notes: "Hello")],
[User(date: "2018-06-27", username: "user1",
submitid: 15302992338145, notes: "Testing"),
User(date: "2018-06-28", username: "user1",
submitid: 15302992338145, notes: "Testing")],
[User(date: "2018-06-21", username: "user2",
submitid: 15301374235890, notes: "Comments one two three"),
User(date: "2018-06-22", username: "user2",
submitid: 15301374235890, notes: "N/A")]]
I am Getting a Dynamic Array which Consist (Dictionary with Array ) and want to increase the Index of Array and will go on to Next Dictionary on action.
After Parsing The Value in swapLibs
var currentQuizIndex = 0
func Dataparsed() {
ServiceManager.service(ServiceType.POST, path: urslStr, param: nil, completion: { (sucess, response, error, code) -> Void in
if (code == 200) {
let QuizData = (swapLibs?.valueForKey("quiz") as! NSArray)
let quizData = playInfo.PlayQuizInfo(QuizData[self.currentQuizIndex] as? NSDictionary)
self.playQuizArray.addObject(quizData)
self.playQuizTitle?.text = quizData.quizQuestion
self.playQImage.sd_setImageWithURL(NSURL(string: quizData.quizQImage!))
self.QNumber?.text = "\(self.Qno)/\(self.noofQuestion)"
}
})
}
And The Modal is
class playInfo: NSObject {
var quizId : String? = ""
var quizQId : String? = ""
var quizQImage : String? = ""
var quizQuestion : String? = ""
var quizType : String? = ""
var quizIndex : String? = ""
class func PlayQuizInfo(dict: NSDictionary?) -> playInfo {
let Pinfo = playInfo()
Pinfo.WrapPlayQuiz(dict)
return Pinfo
}
func WrapPlayQuiz(dict: NSDictionary?) {
if dict == nil {
return
}
self.quizId = dict!.objectForKey("quizId") as? String
self.quizIndex = dict!.objectForKey("index") as? String
self.quizQImage = dict!.objectForKey("QuesImage") as? String
self.quizQuestion = dict!.objectForKey("question") as? String
self.quizType = dict!.objectForKey("Type") as? String
self.quizQId = dict!.objectForKey("questionId") as? String
}
}
Here is Structure
{
"quiz":[
{
"quizId":"7295",
"QuesImage":"http:\/\/proprofs.com\/api\/ckeditor_images\/man-approaches-woman1(1).jpg",
"question":"How do you know him?",
"questionId":"216210",
"Type":"PQ",
"index":4,
"keys":[
{
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
},
{ },
{ },
{ },
{ }
]
},
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ }
]
}
Each Dictionary is Containing same Key As above
Any Help Will Be Appreciated.Thanks.
As I don't have ServiceManager at my end so I have created this code hypothetically. It might solve you issue of saving all data in to one array. It also adds keys in to array as an object.
EDIT 1 : correct QuizKey object array formation. Let me know if any kind of error occurs, as I am unable to test it at my end.
Edit 2: I have made a general ViewController its working perfectly.Try running this View Controller file and you will see the results.
class TestVC: UIViewController {
//An Array similar to the response you are getting from the server
var response:[AnyObject] = [
[
"quizId" : "1111",
"QuesImage" : "http://proprofs.com/api/ckeditor_images/man-approaches-woman1(1).jpg",
"question" : "How do you know him?",
"questionId" : "216210",
"Type" : "PQ",
"index" : 4,
"keys":[
[
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
],
[
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
],
[
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
]
]
],
[
"quizId" : "2222",
"QuesImage" : "http://proprofs.com/api/ckeditor_images/man-approaches-woman1(1).jpg",
"question" : "How do you know him?",
"questionId" : "216210",
"Type" : "PQ",
"index" : 4,
"keys":[
[
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
],
[
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
],
[
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
]
]
]
]
var playQuizArray:[playInfo]! = []
override func viewDidLoad() {
super.viewDidLoad()
print(response)
for dict in response {
self.playQuizArray.append(playInfo.PlayQuizInfo(dict as? [String:AnyObject]))
}
print(self.playQuizArray)
let quiz = self.playQuizArray[0]
print("quizId \(quiz.quizId)")
print("keyAnswerId \(quiz.quizKeys![0].keyAnswerId)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
class playInfo: NSObject {
var quizId : String? = ""
var quizQId : String? = ""
var quizQImage : String? = ""
var quizQuestion : String? = ""
var quizType : String? = ""
var quizIndex : String? = ""
//quizKeys will contain quiz array
var quizKeys : [QuizKey]? = []
class func PlayQuizInfo(dict: [String:AnyObject]?) -> playInfo {
let Pinfo = playInfo()
Pinfo.WrapPlayQuiz(dict)
return Pinfo
}
func WrapPlayQuiz(dict: [String:AnyObject]?) {
if dict == nil {
return
}
self.quizId = dict!["quizId"] as? String
self.quizIndex = dict!["index"] as? String
self.quizQImage = dict!["QuesImage"] as? String
self.quizQuestion = dict!["question"] as? String
self.quizType = dict!["Type"] as? String
self.quizQId = dict!["questionId"] as? String
//add key object array to the quizKeys
if let arrKeys = dict!["keys"] as? [AnyObject] {
for arr in arrKeys {
let key:QuizKey = QuizKey.QuizKeyInfo(arr as? [String : AnyObject])
self.quizKeys?.append(key)
}
}
}
}
class QuizKey: NSObject {
var keyAnswerId : String? = ""
var keyOption : String? = ""
var keyAnsImage : String? = ""
class func QuizKeyInfo(dict: [String:AnyObject]?) -> QuizKey {
let QKeys = QuizKey()
QKeys.WrapQuizKeys(dict)
return QKeys
}
func WrapQuizKeys(dict: [String:AnyObject]?) {
if dict == nil {
return
}
self.keyAnswerId = dict!["answerId"] as? String
self.keyOption = dict!["option"] as? String
self.keyAnsImage = dict!["AnsImage"] as? String
}
}