How to write model class for json data with dictionary? - ios

In this class already i had written model class but here some of the data has been added newly but i am trying to create for the model class for remaining dictionaries but unable to implement it can anyone help me how to implement it ?
In this already i had implemented model class for items array and here i need to create a model class for search criteria dictionary and inside arrays
func listCategoryDownloadJsonWithURL() {
let url = URL(string: listPageUrl)!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil { print(error!); return }
do {
if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [String:Any] {
let objArr = jsonObj["items"] as? [[String:Any]]
self.list = objArr!.map{List(dict: $0)}
DispatchQueue.main.async {
let itemsCount = self.list.count
for i in 0..<itemsCount {
let customAttribute = self.list[i].customAttribute
for j in 0..<customAttribute.count {
if customAttribute[j].attributeCode == "image" {
let baseUrl = "http://192.168.1.11/magento2/pub/media/catalog/product"
self.listCategoryImageArray.append(baseUrl + customAttribute[j].value)
}
}
}
self.activityIndicator.stopAnimating()
self.activityIndicator.hidesWhenStopped = true
self.collectionView.reloadData()
self.collectionView.isHidden = false
self.tableView.reloadData()
}
}
} catch {
print(error)
}
}
task.resume()
}
struct List {
let name : String
let sku : Any
let id : Int
let attributeSetId : Int
let price : Int
let status : Int
let visibility : Int
let typeId: String
let createdAt : Any
let updatedAt : Any
var customAttribute = [ListAttribute]()
init(dict : [String:Any]) {
if let customAttribute = dict["custom_attributes"] as? [[String: AnyObject]] {
var result = [ListAttribute]()
for obj in customAttribute {
result.append(ListAttribute(json: obj as! [String : String])!)
}
self.customAttribute = result
} else {
self.customAttribute = [ListAttribute]()
}
self.name = (dict["name"] as? String)!
self.sku = dict["sku"]!
self.id = (dict["id"] as? Int)!
self.attributeSetId = (dict["attribute_set_id"] as? Int)!
self.price = (dict["price"] as? Int)!
self.status = (dict["status"] as? Int)!
self.visibility = (dict["visibility"] as? Int)!
self.typeId = (dict["type_id"] as? String)!
self.createdAt = dict["created_at"]!
self.updatedAt = dict["updated_at"]!
}
}
struct ListAttribute {
let attributeCode : String
let value : String
init?(json : [String:String]) {
self.attributeCode = (json["attribute_code"])!
self.value = (json["value"])!
}
}

Related

Nil in OpenWeather API

I've just started to learn Swift and iOS and I have problem in my weather app. I'm trying to get weather data and print in console, but there is still nil and I no have idea what could be wrong. I tried to change the model, pasted all url and is still nil. Sometimes app sends data and there is no answer, but at other times is answer or no sending, no answer. In console always nil...
Generated model class:
import Foundation
class CurrentWeather : NSObject, NSCoding{
var base : String!
var clouds : Cloud!
var cod : Int!
var coord : Coord!
var dt : Int!
var id : Int!
var main : Main!
var name : String!
var sys : Sy!
var visibility : Int!
var weather : [Weather]!
var wind : Wind!
/**
* Instantiate the instance using the passed dictionary values to set the properties values
*/
init(fromDictionary dictionary: [String:Any]){
base = dictionary["base"] as? String
cod = dictionary["cod"] as? Int
dt = dictionary["dt"] as? Int
id = dictionary["id"] as? Int
name = dictionary["name"] as? String
visibility = dictionary["visibility"] as? Int
if let cloudsData = dictionary["clouds"] as? [String:Any]{
clouds = Cloud(fromDictionary: cloudsData)
}
if let coordData = dictionary["coord"] as? [String:Any]{
coord = Coord(fromDictionary: coordData)
}
if let mainData = dictionary["main"] as? [String:Any]{
main = Main(fromDictionary: mainData)
}
if let sysData = dictionary["sys"] as? [String:Any]{
sys = Sy(fromDictionary: sysData)
}
if let windData = dictionary["wind"] as? [String:Any]{
wind = Wind(fromDictionary: windData)
}
weather = [Weather]()
if let weatherArray = dictionary["weather"] as? [[String:Any]]{
for dic in weatherArray{
let value = Weather(fromDictionary: dic)
weather.append(value)
}
}
}
/**
* Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
*/
func toDictionary() -> [String:Any]
{
var dictionary = [String:Any]()
if base != nil{
dictionary["base"] = base
}
if cod != nil{
dictionary["cod"] = cod
}
if dt != nil{
dictionary["dt"] = dt
}
if id != nil{
dictionary["id"] = id
}
if name != nil{
dictionary["name"] = name
}
if visibility != nil{
dictionary["visibility"] = visibility
}
if clouds != nil{
dictionary["clouds"] = clouds.toDictionary()
}
if coord != nil{
dictionary["coord"] = coord.toDictionary()
}
if main != nil{
dictionary["main"] = main.toDictionary()
}
if sys != nil{
dictionary["sys"] = sys.toDictionary()
}
if wind != nil{
dictionary["wind"] = wind.toDictionary()
}
if weather != nil{
var dictionaryElements = [[String:Any]]()
for weatherElement in weather {
dictionaryElements.append(weatherElement.toDictionary())
}
dictionary["weather"] = dictionaryElements
}
return dictionary
}
/**
* NSCoding required initializer.
* Fills the data from the passed decoder
*/
#objc required init(coder aDecoder: NSCoder)
{
base = aDecoder.decodeObject(forKey: "base") as? String
clouds = aDecoder.decodeObject(forKey: "clouds") as? Cloud
cod = aDecoder.decodeObject(forKey: "cod") as? Int
coord = aDecoder.decodeObject(forKey: "coord") as? Coord
dt = aDecoder.decodeObject(forKey: "dt") as? Int
id = aDecoder.decodeObject(forKey: "id") as? Int
main = aDecoder.decodeObject(forKey: "main") as? Main
name = aDecoder.decodeObject(forKey: "name") as? String
sys = aDecoder.decodeObject(forKey: "sys") as? Sy
visibility = aDecoder.decodeObject(forKey: "visibility") as? Int
weather = aDecoder.decodeObject(forKey: "weather") as? [Weather]
wind = aDecoder.decodeObject(forKey: "wind") as? Wind
}
/**
* NSCoding required method.
* Encodes mode properties into the decoder
*/
#objc func encode(with aCoder: NSCoder)
{
if base != nil{
aCoder.encode(base, forKey: "base")
}
if clouds != nil{
aCoder.encode(clouds, forKey: "clouds")
}
if cod != nil{
aCoder.encode(cod, forKey: "cod")
}
if coord != nil{
aCoder.encode(coord, forKey: "coord")
}
if dt != nil{
aCoder.encode(dt, forKey: "dt")
}
if id != nil{
aCoder.encode(id, forKey: "id")
}
if main != nil{
aCoder.encode(main, forKey: "main")
}
if name != nil{
aCoder.encode(name, forKey: "name")
}
if sys != nil{
aCoder.encode(sys, forKey: "sys")
}
if visibility != nil{
aCoder.encode(visibility, forKey: "visibility")
}
if weather != nil{
aCoder.encode(weather, forKey: "weather")
}
if wind != nil{
aCoder.encode(wind, forKey: "wind")
}
}
}
WeatherService:
import Foundation
class WeatherSerice {
let weatherAPIKey: String
let weatherBaseURL: URL?
init(APIKey: String) {
self.weatherAPIKey = APIKey
weatherBaseURL = URL(string: "https://api.openweathermap.org/data/2.5/weather?")
}
func getCurrentWeather(city: String, completion: #escaping (CurrentWeather?) -> Void) {
if let weatherURL = URL(string: "\(weatherBaseURL!)q=\(city)&appid=\(weatherAPIKey)") {
let networkProcessor = NetworkProcessor(url: weatherURL)
networkProcessor.downloadJSONFromURL({(jsonDictionary) in
if let currentWeatherDictionary = jsonDictionary?["currently"] as?
[String : Any] {
let currentWeather = CurrentWeather(fromDictionary: currentWeatherDictionary)
completion(currentWeather)
} else {
completion(nil)
}
})
}
}
}
Part of the UIViewController:
let weatherService = WeatherSerice(APIKey: "52e6ff60bba8613b4850e065dcd3d0ac")
weatherService.getCurrentWeather(city: "London") {
(currentWeather) in
print (currentWeather)
}
Please, please drop NSCoding in favor of Codable, you will get rid of all that ugly boilerplate code
struct WeatherData : Decodable {
let coord : Coordinate
let cod, visibility, id : Int
let name : String
let base : String
let weather : [Weather]
let clouds: Clouds
let sys : Sys
let main : Main
let wind : Wind
let dt : Date
}
struct Coordinate : Decodable {
let lat, lon : Double
}
struct Weather : Decodable {
let id : Int
let icon : String
let main : MainEnum
let description: String
}
struct Sys : Decodable {
let type, id : Int
let sunrise, sunset : Date
let message : Double
let country : String
}
struct Main : Decodable {
let temp, tempMin, tempMax : Double
let pressure, humidity : Int
}
struct Wind : Decodable {
let speed : Double
let deg : Int
let gust : Double?
}
struct Clouds: Decodable {
let all: Int
}
enum MainEnum: String, Decodable {
case clear = "Clear"
case clouds = "Clouds"
case rain = "Rain"
}
As you can see the dates are decoded as Date and the main values in Weather are decoded as enum.
I don't know the API NetworkProcessor so I replaced it with traditional URLSession. The added URLComponents provide proper URL encoding for example if the city contains space characters
import Foundation
class WeatherSerice {
let weatherAPIKey: String
let weatherBase = "https://api.openweathermap.org/data/2.5/weather"
init(APIKey: String) {
self.weatherAPIKey = APIKey
}
func getCurrentWeather(city: String, completion: #escaping (WeatherData?) -> Void) {
var urlComponents = URLComponents(string: weatherBase)!
let queryItems = [URLQueryItem(name: "q", value: city),
URLQueryItem(name: "appid", value: weatherAPIKey)]
urlComponents.queryItems = queryItems
if let weatherURL = urlComponents.url {
let task = URLSession.shared.dataTask(with: weatherURL) { (data, response, error) in
if let error = error { print(error); completion(nil) }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .secondsSince1970
let result = try decoder.decode(WeatherData.self, from: data!)
completion(result)
} catch {
print(error)
completion(nil)
}
}
task.resume()
}
}
}
I recommend to use the new Result type in Swift 5 to return the error, too.
func getCurrentWeather(city: String, completion: #escaping (Result<WeatherData,Error>) -> Void) {
var urlComponents = URLComponents(string: weatherBase)!
let queryItems = [URLQueryItem(name: "q", value: city),
URLQueryItem(name: "appid", value: weatherAPIKey)]
urlComponents.queryItems = queryItems
if let weatherURL = urlComponents.url {
let task = URLSession.shared.dataTask(with: weatherURL) { (data, response, error) in
if let error = error { completion(.failure(error)) }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .secondsSince1970
let result = try decoder.decode(WeatherData.self, from: data!)
completion(.success(result))
} catch {
completion(.failure(error))
}
}
task.resume()
}
and use it
weatherService.getCurrentWeather(city: "London") { result in
switch result {
case .success(let result): print(result)
case .failure(let error): print(error)
}
}

How to call a Struct of variable or constant to include to Dictionary in Alamofire Get Request

I am new in using Swift I created an APIService using Alamofire, I tried to check whether I can retrieve data from API and it turn out well. My problem now, how can the data reflect to the variables in my Event Struct, so I could perform some validation base on the data read. I tried to check thru breakpoint but variable can't read data or either " " value. Please help me. Thank you
Event Struct
struct Event: Codable {
let id: String?
let name: String
let location: String
let startDateTime: Date
let endDateTime: String
let deleteFlag: Bool?
let deleteDateTime: String?
let dateCreated: String?
let hasRaffle: Bool?
let registrationReq: Bool?
let participantCount: Int
let closedFlag: Bool?
let closedDateTime: String?
let reopenFlag: Bool?
let reopenDateTime: String?
init?(JSON: [String: AnyObject]) {
guard let eventID = JSON["event_id"] as? String,
let eventName = JSON["event_name"] as? String,
let eventLocation = JSON["event_location"] as? String,
let startDateTime = JSON["start_datetime"] as? String,
let endDateTime = JSON["end_datetime"] as? String,
let participantCount = JSON["participant_count"] as? Int else {
return nil
}
self.id = eventID
self.name = eventName
self.location = eventLocation
self.endDateTime = endDateTime
self.participantCount = participantCount
if let formattedStartDateTime = getDateFromString(dateString: startDateTime, formatString: "yyyy-MM-dd'T'HH:mm:ss.SSS") {
self.startDateTime = formattedStartDateTime
}else {
self.startDateTime = Date()
}
if let deleteFlag = JSON["delete_flag"] as? Bool {
self.deleteFlag = deleteFlag
}else {
self.deleteFlag = nil
}
if let deletedDateTime = JSON["deleted_datetime"] as? String {
self.deleteDateTime = deletedDateTime
}else {
self.deleteDateTime = nil
}
if let dateCreated = JSON["date_created"] as? String {
self.dateCreated = dateCreated
}else {
self.dateCreated = nil
}
if let hasRaffle = JSON["hasRaffle"] as? Bool {
self.hasRaffle = hasRaffle
}else {
self.hasRaffle = nil
}
if let registrationReq = JSON["registration_req"] as? Bool {
self.registrationReq = registrationReq
}else {
self.registrationReq = nil
}
if let closedFlag = JSON["closed_flag"] as? Bool {
self.closedFlag = closedFlag
}else {
self.closedFlag = nil
}
if let closedDateTime = JSON["closed_datetime"] as? String {
self.closedDateTime = closedDateTime
}else {
self.closedDateTime = nil
}
if let reopenFlag = JSON["reopen_flag"] as? Bool {
self.reopenFlag = reopenFlag
}else {
self.reopenFlag = nil
}
if let reopenDateTime = JSON["reopen_datetime"] as? String {
self.reopenDateTime = reopenDateTime
}else {
self.reopenDateTime = nil
}
}
}
APIService
class APIService
{
let eventAPIKey: String
let eventBaseURL: URL?
//static let kEventID = "id"
init(APIKey: String)
{
self.eventAPIKey = APIKey
eventBaseURL = URL(string: BASE_URL)
}
func validatePasscode(passcode: String, completion: #escaping (Event?) -> Void)
{
let passcodeURL = URL (string: "\(PASSCODE_CHECKER_URL)/\(passcode)")
Alamofire.request(passcodeURL!, method: .get).responseJSON { (response) in
switch response.result{
case .success:
if let passcodeJSON = response.result.value{
print(passcodeJSON)
completion(Event(JSON: json as [String : Any]))
}
case .failure(let error):
print("\(error)")
}
}
}
}
You need to try and initialize the Event struct with the data you received passcodeJSON. As you can see your Event initializer is init?(JSON: [String: AnyObject])
if let passcodeJSON = response.result.value{
// print(passcodeJSON)
completion(Event(JSON: passcodeJSON))
}
and where you call your API service:
apiServiceClient.validatePasscode(passcode: "testing") { eventDetails in
// do something with eventDetails here
}

Unable to parse Json in swift 3?

Here I tried to parse the data from my local server but unable to parse it and it returning empty data and below are my model classes from which the data I was passing to an table view which can anyone help me what's wrong in implementing it?
Here I had attached my image which follows the Json format:
Code:
var homePageModel = [HomeBanner]()
func HomeBannerDownloadJsonWithURL(){
let url = URL(string: homePageUrl)!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil { print(error!); return }
do {
if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]] {
for item in jsonObj {
print(item)
for dict in item {
print(dict)
let dict = HomeBanner(json: item)
self.homePageModel.append(dict!)
print(self.homePageModel)
}
}
print(self.homePageModel)
DispatchQueue.main.async {
self.homeTableView.delegate = self
self.homeTableView.dataSource = self
self.homeTableView.reloadData()
}
}
} catch {
print(error)
}
}
task.resume()
}
struct HomeBanner {
let title : String?
let titleInArabic : String?
let showTitle : String?
var banner = [ChildrenBanners]()
init?(json : [String:Any]) {
if let customAttribute = json["childran_banners"] as? [[String: AnyObject]] {
var result = [ChildrenBanners]()
for obj in customAttribute {
result.append(ChildrenBanners(json: obj as! [String : String])!)
}
self.banner = result
} else {
self.banner = [ChildrenBanners]()
}
self.title = json["title"] as? String ?? ""
print(self.title)
self.titleInArabic = json["title_in_arabic"] as? String ?? ""
self.showTitle = json["show_title"] as? String ?? ""
}
}
struct ChildrenBanners {
let bannerId : String?
let name : String?
let status : String?
let sliderId : String?
let desktopImage : String?
let mobileImage : String?
let imageAlt : String?
let sortOrder : String?
let startTime : String?
let endTime : String?
init?(json : [String:Any]) {
self.bannerId = json["banner_id"] as? String ?? ""
print(self.bannerId)
self.name = json["name"] as? String ?? ""
self.status = json["status"] as? String ?? ""
self.sliderId = json["slider_id"] as? String ?? ""
self.desktopImage = json["desktop_image"] as? String ?? ""
self.mobileImage = json["mobile_image"] as? String ?? ""
self.imageAlt = json["image_alt"] as? String ?? ""
self.sortOrder = json["sort_order"] as? String ?? ""
self.startTime = json["start_time"] as? String ?? ""
self.endTime = json["end_time"] as? String ?? ""
}
}
Just try these lines of code
if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]] {
self.homePageModel = jsonObj.map{HomeBanner(json: $0)}
print(self.homePageModel)
DispatchQueue.main.async {
self.homeTableView.delegate = self
self.homeTableView.dataSource = self
self.homeTableView.reloadData()
}
}
} catch {
print(error)
}
and there is no necessity of making optional initializer for HomeBanner and ChildrenBanners just use init(json : [String : Any]){} for both struct
Root of json is an array and then second level is dictionary with keys list1, list2 etc. You are missing that in your code. Should be something like this (I haven't compiled it).
if let data = data, let jsonObj = try JSONSerialization.jsonObject(with: data) as? [[String:[String:Any]]] {
for item in jsonObj {
for (_, dict) in item {
if let obj = HomeBanner(json: dict) {
self.homePageModel.append(obj)
}
}
}
}
There are lot of other issues in your code. Like force unwrapping optional. Using same parameters again within a scope. For example.
for dict in item {
let dict = HomeBanner(json: item)
// ....
}
You shouldn't use same param names like you are using dict it hides the scope of the outer dict.

How to get the attribute from model class and pass to collection view in swift 3

Here I am having collection view in which data will be passing from model class here I need to get special_price key value pair from CustomAttribute and need to pass for collection view in which only some products will have special price and some products won't have special price how to pass the data to collection view I am unable to implement it can anyone help me how to pass data new to swift 3 if anything wrong in declaring or writing model class please correct me ?
var listClassModel : ModelClass?
var items = [List]()
func listCategoryDownloadJsonWithURL(listUrl: String) {
print(listUrl)
let url = URL(string: listUrl)!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil { print(error!); return }
do {
if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [String:AnyObject] {
let objArr = jsonObj["items"] as? [[String:Any]]
let objAdd = objArr!.map{List(dict: $0)}
self.items.append(contentsOf: objAdd)
self.listClassModel = ModelClass(dict: jsonObj as [String : AnyObject])
DispatchQueue.main.async {
guard let obj = self.listClassModel else { return }
let itemsCount = obj.items.count
print(itemsCount)
for i in 0..<itemsCount {
let customAttribute = obj.items[i].customAttribute
print(customAttribute.count)
for j in 0..<customAttribute.count {
if customAttribute[j].attributeCode == "image" {
let baseUrl = "http://192.168.1.11/magento2/pub/media/catalog/product"
self.listCategoryImageArray.append(baseUrl + customAttribute[j].value)
}
if customAttribute[j].attributeCode == "special_price" {
self.specialPrice.append(customAttribute[j].value)
}
}
}
print(self.specialPrice)
self.activityIndicator.stopAnimating()
self.activityIndicator.hidesWhenStopped = true
self.collectionView.reloadData()
self.collectionView.delegate = self
self.collectionView.dataSource = self
self.collectionView.isHidden = false
self.tableView.reloadData()
}
}
} catch {
print(error)
}
}
task.resume()
}
Here is my model class
struct ModelClass {
var items : [List]
var totalCount : Int
var searchCriteria : SearchCriteria
init(dict:[String:AnyObject]) {
totalCount = dict["total_count"] as! Int
let searchDict = dict["search_criteria"] as? [String:AnyObject]
searchCriteria = SearchCriteria(dict: searchDict!)
let arr = dict["items"] as? [[String:AnyObject]]
var listArr = [List]()
for obj in arr! {
listArr.append(List(dict: obj))
}
items = listArr
}
}
struct List {
let name : String
let sku : Any
let id : Int
let attributeSetId : Int
let price : Int
let status : Int
let visibility : Int
let typeId: String
let createdAt : Any
let updatedAt : Any
var customAttribute = [ListAttribute]()
init(dict : [String:Any]) {
if let customAttribute = dict["custom_attributes"] as? [[String: AnyObject]] {
var result = [ListAttribute]()
for obj in customAttribute {
result.append(ListAttribute(json: obj)!)
}
self.customAttribute = result
} else {
self.customAttribute = [ListAttribute]()
}
self.name = (dict["name"] as? String)!
self.sku = dict["sku"]!
self.id = (dict["id"] as? Int)!
self.attributeSetId = (dict["attribute_set_id"] as? Int)!
self.price = (dict["price"] as? Int)!
self.status = (dict["status"] as? Int)!
self.visibility = (dict["visibility"] as? Int)!
self.typeId = (dict["type_id"] as? String)!
self.createdAt = dict["created_at"]!
self.updatedAt = dict["updated_at"]!
}
}
struct ListAttribute {
let attributeCode : String
let value : String
init?(json : [String:AnyObject]) {
self.attributeCode = (json["attribute_code"])! as! String
self.value = (json["value"])! as! String
}
}
Here is my image how my Json looks

I am unable to get the child names from given url in swift 3?

In the api am getting global array but in this I am unable to get the children names as separate array only the last loaded array name has been getting in the array how to get the all children names in the array please help me how to get all the names in it and here is my code already tried
var detailsArray = NSArray()
var globalArray = NSMutableArray()
let url = "http://www.json-generator.com/api/json/get/cwqUAMjKGa?indent=2"
func downloadJsonWithURL() {
let url = NSURL(string: self.url)
URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary
{
self.detailsArray = (jsonObj?.value(forKey: "data") as? [[String: AnyObject]])! as NSArray
print(self.detailsArray)
for item in self.detailsArray
{
let majorDic = NSMutableDictionary()
let detailDict = item as! NSDictionary
print(detailDict["name"]!)
majorDic .setValue(detailDict["name"]!, forKey: "name")
print(detailDict["children"]!)
if !(detailDict["children"]! is NSNull)
{
let children = detailDict["children"]! as! NSArray
let childrenstring = NSMutableString()
if children.count > 0 {
for item in children{
let chilDic = item as! NSDictionary
print(chilDic["name"]!)
print(chilDic["products"]!)
majorDic.setValue(chilDic["name"]!, forKey: "Childernname")
let products = chilDic["products"]! as! NSArray
if products.count > 0
{
for item in products
{
var sr = String()
sr = (item as AnyObject) .value(forKey: "name") as! String
childrenstring.append(sr)
childrenstring.append("*")
}
majorDic.setValue(childrenstring, forKey: "Childernproducts")
}
else
{
print("products.count\(products.count)")
majorDic.setValue("NO DATA", forKey: "Childernproducts")
}
}
}
else
{
print("childernw.count\(children.count)")
majorDic.setValue("NO DATA", forKey: "Childernname")
}
}
else
{
majorDic.setValue("NO DATA", forKey: "Childernname")
majorDic.setValue("NO DATA", forKey: "Childernproducts")
}
self.globalArray.add(majorDic)
}
print("TOTAL ASSECTS\(self.globalArray)")
OperationQueue.main.addOperation({
self.tableView.reloadData()
print(self.globalArray)
print(self.detailsArray)
})
}
}).resume()
}
Try this:
var detailsArray = [DataList]()
func downloadJsonWithURL() {
let url = NSURL(string: "http://www.json-generator.com/api/json/get/cwqUAMjKGa?indent=2")
URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary
{
let objArr = (jsonObj?["data"] as? [[String: AnyObject]])! as NSArray
for obj in objArr {
self.detailsArray.append(DataList(json: obj as! [String : AnyObject]))
}
print(self.detailsArray)
}
}).resume()
}
Model Class
class DataList: NSObject {
var count: Int
var category_id: Int
var childern:[Children]
var name:String
init (json: [String: AnyObject]){
if let childrenList = json["children"] as? [[String: AnyObject]] {
var result = [Children]()
for obj in childrenList {
result.append(Children(json: obj))
}
self.childern = result
} else {
self.childern = [Children]()
}
if let count = json["count"] as? Int { self.count = count }
else { self.count = 0 }
if let category_id = json["category_id"] as? Int { self.category_id = category_id }
else { self.category_id = 0 }
if let name = json["name"] as? String { self.name = name }
else { self.name = "" }
}
}
class Children:NSObject{
var count:Int
var category_id:Int
var products:[Products]
var name:String
init (json: [String: AnyObject]){
if let productList = json["products"] as? [[String: AnyObject]] {
var result = [Products]()
for obj in productList {
result.append(Products(json: obj))
}
self.products = result
} else {
self.products = [Products]()
}
if let count = json["count"] as? Int { self.count = count }
else { self.count = 0 }
if let category_id = json["category_id"] as? Int { self.category_id = category_id }
else { self.category_id = 0 }
if let name = json["name"] as? String { self.name = name }
else { self.name = "" }
}
}
class Products:NSObject{
var product_id:Int
var name:String
init (json: [String: AnyObject]){
if let product_id = json["product_id"] as? Int { self.product_id = product_id }
else { self.product_id = 0 }
if let name = json["name"] as? String { self.name = name }
else { self.name = "" }
}
}
NOTE: Please check your data type while parsing
I too had the same problem. Instead of using for loop try using flatMap() and then extract the value using value(forKey: " ") function
let productNames = productValues.flatMap() {$0.value}
let names = (productNames as AnyObject).value(forKey: "name")
It had worked for me for my json. My Json was similar to yours.
I got separate values in array.

Resources