my JSON :
{
"id": "70",
"bname": "Municipal Corporation - Water",
"bcategoryname": "Water",
"bcustomerparms": "[{\"paramName\":\"Consumer Number\",\"dataType\":\"NUMERIC\",\"optional\":\"false\",\"minLength\":\"1\",\"maxLength\":\"10\" . },
{\"paramName\":\"Mobile Number\",\"dataType\":\"NUMERIC\",\"optional\":\"false\",\"minLength\":\"10\",\"maxLength\":\"10\"},
{\"paramName\":\"Email . Id\",\"dataType\":\"ALPHANUMERIC\",\"optional\":\"false\",\"minLength\":\"5\",\"maxLength\":\"100\"}]",
}
{
"id": "68",
"bname": "Municipal Corporation - 12",
"bcategoryname": "Water",
"bcustomerparms": "[{\"paramName\":\"K No\",\"dataType\":\"ALPHANUMERIC\",\"optional\":\"false\",\"minLength\":\"7\",\"maxLength\":\"20\"}]",
}
I am unable to create struct from get api, i need bname and its paramNamew according to its bcategoryname, i need to disply bname in table and if i select i need its all paramNames.
Here is code:
struct JsonDataBiller{
var bname: String?
var bcategoryname: String?
var bcustomerparms: [cDetails]
init(bname: String, bcategoryname: String, bcustomerparms: [cDetails]){
self.bname = bname
self.bcategoryname = bcategoryname
self.bcustomerparms = bcustomerparms
}
}
struct cDetails{
var paramName: String?
var minLength: String?
var maxLength: String?
init(paramName: String, minLength: String, maxLength: String)
{
self.paramName = paramName
self.minLength = minLength
self.maxLength = maxLength
}
}
Code:
class AllMakePaymentViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var jsonData = [JsonDataBiller]()
var minLength: String?
var maxLength: String?
var bName: String?
var category: Category?
var categoryName: String?
var paramName: String?
var ParamArray = [String]()
var labelText: String?
override func viewDidLoad() {
super.viewDidLoad()
allPaymentService()
}
func allPaymentService(){
let urlStr = "https://dev.anyemi.com/webservices/anyemi/api.php?rquest=billermdm"
let url = URL(string: urlStr)
URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
guard let respData = data else {
return
}
guard error == nil else {
print("error")
return
}
do{
let jsonObj = try JSONSerialization.jsonObject(with: respData, options: .allowFragments) as! [String: Any]
//print("the all make payment json is \(jsonObj)")
let billerdetailsArray = jsonObj["billerdetails"] as! [[String: Any]]
for billerdetail in billerdetailsArray {
self.categoryName = billerdetail["bcategoryname"] as? String
let customrParams = billerdetail["bcustomerparms"] as! String
let res = try JSONSerialization.jsonObject(with:Data(customrParams.utf8)) as! [[String: Any]]
for item in res {
self.paramName = item["paramName"] as? String
self.minLength = item["minLength"] as? String
self.maxLength = item["maxLength"] as? String
if self.categoryName == "Water"{
let bName = billerdetail["bname"] as? String
self.jsonData.append(JsonDataBiller(bname: bName ?? "", bcategoryname: self.categoryName ?? "", bcustomerparms: [paramName: paramName, minLength: minLength, maxLength: maxLength]))
}
if self.categoryName == "Electricity"{
let bName = billerdetail["bname"] as? String
self.jsonData.append(JsonDataBiller(bname: bName ?? "", bcategoryname: self.categoryName ?? "", bcustomerparms: [paramName: paramName, minLength: minLength, maxLength: maxLength]))
}
}
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}catch {
print("catch error")
} }).resume()
}
}
error:
Contextual type '[cDetails]' cannot be used with dictionary literal
Here i need to add bnam
according to its bcategoryname
and paramName
according to bname
please help me in the above code please, i am unable to solve this issue, i got stuck from long time.
You are getting close...
The key step issue is that you are looping through the "customer params" and adding a new customer object for each param, instead of adding one customer object that includes an array of params.
Take a look at this - it should run without any edits. After parsing the data, it will print the list of Water customers, along with their associated params.
The debug output should look like this:
Water count: 18
Electricity count: 71
Name: Bhopal Municipal Corporation - Water
Cat: Water
Param: Connection ID / minLength: 8 / maxLength: 8
Name: Bangalore Water Supply and Sewerage Board
Cat: Water
Param: RR Number / minLength: 8 / maxLength: 8
Name: Delhi Jal Board
Cat: Water
Param: K No / minLength: 10 / maxLength: 10
...
Name: Municipal Corporation Jalandhar
Cat: Water
Param: Account No / minLength: 1 / maxLength: 1
Param: Consumer Mobile No / minLength: 10 / maxLength: 10
Param: Consumer Email ID / minLength: 5 / maxLength: 5
Param: UID / minLength: 1 / maxLength: 1
Name: Municipal Corporation Ludhiana - Water
Cat: Water
Param: Consumer Number / minLength: 1 / maxLength: 1
Param: Mobile Number / minLength: 10 / maxLength: 10
Param: Email Id / minLength: 5 / maxLength: 5
Name: New Delhi Municipal Council (NDMC) - Water
Cat: Water
Param: Consumer Number / minLength: 7 / maxLength: 7
...
Here is the source:
//
import UIKit
struct JsonDataBiller{
var bname: String?
var bcategoryname: String?
var bcustomerparms: [cDetails]
init(bname: String, bcategoryname: String, bcustomerparms: [cDetails]){
self.bname = bname
self.bcategoryname = bcategoryname
self.bcustomerparms = bcustomerparms
}
}
struct cDetails{
var paramName: String?
var minLength: String?
var maxLength: String?
init(paramName: String, minLength: String, maxLength: String)
{
self.paramName = paramName
self.minLength = minLength
self.maxLength = maxLength
}
}
class AllMakePaymentViewController: UIViewController {
// arrays of JsonDataBiller objects for each category
var jsonWaterData = [JsonDataBiller]()
var jsonElectricityData = [JsonDataBiller]()
// ...
override func viewDidLoad() {
super.viewDidLoad()
allPaymentService()
}
func allPaymentService(){
let urlStr = "https://dev.anyemi.com/webservices/anyemi/api.php?rquest=billermdm"
let url = URL(string: urlStr)
URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
guard let respData = data else {
return
}
guard error == nil else {
print("error")
return
}
do{
let jsonObj = try JSONSerialization.jsonObject(with: respData, options: .allowFragments) as! [String: Any]
//print("the all make payment json is \(jsonObj)")
let billerdetailsArray = jsonObj["billerdetails"] as! [[String: Any]]
for billerdetail in billerdetailsArray {
// make these local vars --- no need for the confusing self. properties
let localBName = billerdetail["bname"] as? String ?? ""
let localCName = billerdetail["bcategoryname"] as? String ?? ""
let customrParams = billerdetail["bcustomerparms"] as! String
let res = try JSONSerialization.jsonObject(with:Data(customrParams.utf8)) as! [[String: Any]]
// create new array of cDetails objects
var aParams = [cDetails]()
// for each param item
for item in res {
if let pn = item["paramName"] as? String,
let minL = item["minLength"] as? String,
let maxL = item["maxLength"] as? String {
// create new cDetails object
let cd = cDetails(paramName: pn, minLength: minL, maxLength: maxL)
// append it to the aParams array
aParams.append(cd)
}
}
// create new JsonDataBiller object with
// bname
// bcategoryname
// array of bcustomerparms
let jdBiller = JsonDataBiller(bname: localBName,
bcategoryname: localCName,
bcustomerparms: aParams)
// append the JsonDataBiller object to the appropriate category array
if localCName == "Water" {
self.jsonWaterData.append(jdBiller)
}
if localCName == "Electricity" {
self.jsonElectricityData.append(jdBiller)
}
// if localCName == ...
}
// finished parsing the data into arrays of jdBiller objects
print("Water count: \(self.jsonWaterData.count)")
print("Electricity count: \(self.jsonElectricityData.count)")
print()
// for quick debugging...
self.jsonWaterData.forEach {
obj in
print("Name: \(obj.bname ?? "")")
print("Cat: \(obj.bcategoryname ?? "")")
obj.bcustomerparms.forEach {
param in
print("Param: \(param.paramName ?? "") / minLength: \(param.minLength ?? "") / maxLength: \(param.minLength ?? "")")
}
print()
}
// DispatchQueue.main.async {
// self.tableView.reloadData()
// }
}catch {
print("catch error")
} }).resume()
}
}