Swift 4 get song for every channel - json

I got the same error when I try to get previous and song that play right now for every channel. I think something is wrong in my struct Root and playlist because data is not in the correct format.I am using Swift 4 and trying to learn JSON, but its hard. Previous struct is same as Song struct. How do I fix my error?
My code looks now:
import UIKit
struct Root : Decodable {
let copyright : String
let channels : [Channel]
let pagination : Pagination
}
struct Channel : Decodable {
let image : String
let imagetemplate : String
let color : String
let tagline : String?
let siteurl : String
let id : Int
let url : URL?
let statkey : String?
let scheduleurl : String
let channeltype : String
let name : String
}
struct Pagination : Decodable {
let page, size, totalhits, totalpages : Int
let nextpage : URL
}
struct Playlist : Decodable{
let id : Int
let name :String
let prev : [previoussong]
let song : [Song]
}
struct previoussong : Decodable {
let title : String
let description : String
let artist : String
let composer :String
let conductor : String
let albumname : String
let recordlabel : String
let lyricist : String
let producer : String
let starttimeutc : String
let stopttimeutc : String
}
struct Song : Decodable {
let title : String
let description : String
let artist : String
let composer :String
let conductor : String
let albumname : String
let recordlabel : String
let lyricist : String
let producer : String
let starttimeutc : String
let stopttimeutc : String
}
import UIKit
class ViewController: UIViewController,UITableViewDataSource {
var auth = SPTAuth.defaultInstance()!
var session:SPTSession!
var loginUrl: URL?
var tests = [Channel]()
//var pl = [Playlist]()
var stationsName:String?
#IBOutlet weak var tableV: UITableView!
#IBOutlet weak var image: UIImageView!
#IBOutlet weak var statLabel: UILabel!
#IBOutlet weak var songLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
tableV.dataSource = self
downloadStations()
}
func downloadStations(){
let test2 = "http://api.sr.se/api/v2/channels?format=json"
let play = "http://api.sr.se/api/v2/playlists/rightnow?format=json"
let url = URL(string: test2)
URLSession.shared.dataTask(with: url!){ (data , response, error) in
do{
let root = try JSONDecoder().decode(Root.self, from: data!)
self.tests = root.channels
for eachStations in self.tests {
self.stationsName = eachStations.name
print(" " + self.stationsName!)
DispatchQueue.main.async {
self.tableV.reloadData()
}
}
}
catch{
print(error.localizedDescription)
}
}.resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tests.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style : .default, reuseIdentifier : nil)
cell.textLabel?.text = tests[indexPath.row].name
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

The data you're getting from api.sr.se/api/v2/playlists/rightnow?format=json does not always have the correct structure. Notice that sometimes you will get json that starts with a copyright field, while other times you get something like this:
{
"playlist": {
"previoussong": {
"title": "Stir Fry",
"description": "Migos - Stir Fry",
"artist": "Migos",
"composer": "Quavious Marshall/Pharrell Williams",
"recordlabel": "Universal",
"starttimeutc": "\/Date(1521137326000)\/",
"stoptimeutc": "\/Date(1521137510000)\/"
},
...
When you attempt to decode into Root, the decoder looks in the json for something that looks like your Root class, something like this:
{
"copyright": "Copyright Sveriges Radio 2018. All rights reserved.",
"channels": [{
"id": 4540,
"name": "Ekot",
"playlists": {
"playlist": {
"channel": {
"id": 4540,
"name": "Ekot sänder direkt"
}
If it can't find something like that in the json, it says the data is missing. You will have to figure out a way to tell when to decode into Root, and when the data isn't appropriate for Root.

Related

How to decode custom type inside dictionary value with JSON?

my JSON:
https://www.cbr-xml-daily.ru/daily_json.js
my code:
struct CoinData: Decodable {
let Valute: [String: CoinInfo]
}
struct CoinInfo: Decodable {
let Name: String
let Value: Double
}
if let safeData = data {
if let coinData = self.parseJSON(safeData) {
print(coinData)
}
}
func parseJSON(_ data: Data) -> [String: CoinInfo]? {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(CoinData.self, from: data)
return decodedData.Valute
} catch {
delegate?.didFailWithError(error: error)
return nil
}
}
In debug console following gets printed:
["PLN": CurrencyConverter.CoinInfo(Name: "X", Value: 19.6678), ...]
This way I can't reach Name and Value properties of a coin. What's wrong?
I am going to do for-loop to check if a key contains certain symbols. If it does - I will need to be able to access to both Name and Value
You don't actually need a for loop. Since coinData is a dictionary, you can use its subscript, together with optional binding to do this. For example, to check if the key "PLN" exists, and access its name and value:
if let coinInfo = coinData["PLN"] {
print(coinInfo.Name)
print(coinInfo.Value)
} else {
// "PLN" does not exist
}
StoyBoard
Code
import UIKit
import Alamofire
// MARK: - CoinData
struct CoinData: Codable {
let date, previousDate: String
let previousURL: String
let timestamp: String
let valute: [String: Valute]
enum CodingKeys: String, CodingKey {
case date = "Date"
case previousDate = "PreviousDate"
case previousURL = "PreviousURL"
case timestamp = "Timestamp"
case valute = "Valute"
}
}
// MARK: - Valute
struct Valute: Codable {
let id, numCode, charCode: String
let nominal: Int
let name: String
let value, previous: Double
enum CodingKeys: String, CodingKey {
case id = "ID"
case numCode = "NumCode"
case charCode = "CharCode"
case nominal = "Nominal"
case name = "Name"
case value = "Value"
case previous = "Previous"
}
}
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
var getCoinData = [CoinData]()
var coinNameArr = [String]()
var coinDataArr = [Valute]()
#IBOutlet weak var tblDataList: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
getData()
}
func getData()
{
let url = "https://www.cbr-xml-daily.ru/daily_json.js"
AF.request(url, method: .get, encoding: URLEncoding.default).responseJSON { response in
let json = response.data
do{
let decoder = JSONDecoder()
self.getCoinData = [try decoder.decode(CoinData.self, from: json!)]
let response = self.getCoinData[0]
if response.valute.count != 0 {
self.coinNameArr.removeAll()
self.coinDataArr.removeAll()
for (coinName, coinData) in response.valute {
self.coinNameArr.append(coinName)
self.coinDataArr.append(coinData)
}
self.tblDataList.reloadData()
} else {
}
}catch let err{
print(err)
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return coinDataArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:coinTblCell = tableView.dequeueReusableCell(withIdentifier: "CellID", for: indexPath as IndexPath) as! coinTblCell
cell.accessoryType = .disclosureIndicator
cell.tintColor = .black
let rowData = coinDataArr[indexPath.row]
cell.lblName.text = rowData.name
cell.lblValue.text = String(rowData.value)
return cell
}
}
class coinTblCell: UITableViewCell {
#IBOutlet weak var lblName: UILabel!
#IBOutlet weak var lblValue: UILabel!
}

I can't open the image. Parsing doesn't work

I can't open "url" in "images".
Parsing doesn't work. Please help. Thank you.
"images": [
{
"url": "https://ktar.com/wp-content/uploads/2020/03/ap_27df5153e3bf48198ebcfd40900446d6.jpg",
"width": 1280,
"height": 853,
"title": "Arizona reports 124 new coronavirus cases, five additional deaths",
"attribution": null
=======================================================
=======================================================
API
{
"path": "_news/2020-04-01-arizona-reports-124-new-coronavirus-cases-five-additional-deaths.md",
"title": "Arizona reports 124 new coronavirus cases, five additional deaths",
"excerpt": "The Arizona health department reported 124 new cases of coronavirus and five additional deaths on Wednesday morning, a day after the state's \"stay at home\" order went into effect.",
"heat": 145,
"tags": [
"US"
],
"type": "article",
"webUrl": "https://ktar.com/story/3056413/arizona-reports-124-new-coronavirus-cases-five-additional-deaths/",
"ampWebUrl": "https://ktar.com/story/3056413/arizona-reports-124-new-coronavirus-cases-five-additional-deaths/amp/",
"cdnAmpWebUrl": "https://ktar-com.cdn.ampproject.org/c/s/ktar.com/story/3056413/arizona-reports-124-new-coronavirus-cases-five-additional-deaths/amp/",
"publishedDateTime": "2020-04-01T09:09:00-07:00",
"updatedDateTime": null,
"provider": {
"name": "KTAR News",
"domain": "ktar.com",
"images": null,
"publishers": null,
"authors": null
},
"images": [
{
"url": "https://ktar.com/wp-content/uploads/2020/03/ap_27df5153e3bf48198ebcfd40900446d6.jpg",
"width": 1280,
"height": 853,
"title": "Arizona reports 124 new coronavirus cases, five additional deaths",
"attribution": null
}
],
"locale": "en-us",
"categories": [
"news"
],
"topics": [
"Coronavirus in US",
"Coronavirus",
"New Cases"
]
}
======================================================
======================================================
// SPORTNEWSVC.swift
// Hero
import Alamofire
import Kingfisher
import UIKit
class NewsVC: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var news = [Article]()
override func viewDidLoad() {
super.viewDidLoad()
getArticles()
}
func getArticles() {
let parameters: Parameters = ["Subscription-Key": "3009d4ccc29e4808af1ccc25c69b4d5d"]
Alamofire.request("https://api.smartable.ai/coronavirus/news/US", parameters: parameters).responseData { (response) in
guard let data = response.data else { return }
do {
// let json = try JSONSerialization.jsonObject(with: data, options: [])
// print(json)
let topHeadlinesResponse = try JSONDecoder().decode(TopHeadlinesResponse.self, from: data)
self.news = topHeadlinesResponse.news
self.collectionView?.reloadData()
} catch {
print(error)
}
}
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return news.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ArticleCell", for: indexPath) as? ArticleCell else { return UICollectionViewCell ()}
let article = news[indexPath.item]
cell.populate(with: article)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let height: CGFloat = 277
let width = (collectionView.frame.width / 2) - 2
let size = CGSize(width: width, height: height)
return size
}
}
======================================================
======================================================
// Article.swift
// Hero
//
import Foundation
struct Article: Decodable {
let headline: String
let url: String?
private enum CodingKeys: String, CodingKey {
case headline = "title"
case url
}
}
======================================================
======================================================
//
// ArticleCell.swift
// Hero
import UIKit
import Kingfisher
class ArticleCell: UICollectionViewCell {
#IBOutlet weak var articleImageView: UIImageView!
#IBOutlet weak var headlieLabel: UILabel!
func populate(with article: Article){
headlieLabel.text = article.headline
if let url = article.url {
let url = URL(string: url)
articleImageView.kf.setImage(with: url)
}
}
}
======================================================
======================================================
import Foundation
struct TopHeadlinesResponse: Decodable {
let news: [Article]
}
The idea is that "images" in the JSON response you get is an array and you need to reflect this fact in Codable structure. The Decoding magic needs you to follow JSON data structure and namings: so if you meet field 'width' inside 'image' dictionary - you need to have a field named 'width' inside an 'image' field (e.g. having image as a separate struct)
you can read more about Decodables here
struct NewsApiResponse : Decodable {
let status : String
let updatedDateTime : Date?
let news : [Article]
}
struct Article : Decodable {
let id : Int
let title : String
let excerpt : String
let webUrl : String
let publishedDateTime : Date?
let images : [Image]
}
struct Image : Decodable {
let url : String
let width : Int
let height : Int
let title : String
}
*struct TopHeadLinesResponse: Codable {
let path, title, excerpt: String
let heat: Int
let tags: [String]
let type: String
let webURL, ampWebURL, cdnAmpWebURL: String
let publishedDateTime: Date
let updatedDateTime: JSONNull?
let provider: Provider
let images: [Image]
let locale: String
let categories, topics: [String]
enum CodingKeys: String, CodingKey {
case path, title, excerpt, heat, tags, type
case webURL
case ampWebURL
case cdnAmpWebURL
case publishedDateTime, updatedDateTime, provider, images, locale, categories, topics
}
}
// MARK: - Image
struct Image: Codable {
let url: String
let width, height: Int
let title: String
let attribution: JSONNull?
}
// MARK: - Provider
struct Provider: Codable {
let name, domain: String
let images, publishers, authors: JSONNull?
}
// MARK: - Encode/decode helpers
class JSONNull: Codable, Hashable {
public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
return true
}
public var hashValue: Int {
return 0
}
public init() {}
public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encodeNil()
}
}
extension UIImageView {
func loadImagee(_ urlString: String?, onSuccess: ((UIImage) -> Void)? = nil) {
self.image = UIImage()
guard let string = urlString else { return }
guard let url = URL(string: string) else { return }
self.sd_setImage(with: url) { (image, error, type, url) in
if onSuccess != nil, error == nil {
onSuccess!(image!)
}
}
}
}
// try using SD Web library code is above install SDweb instead of // king fisher
// check your struct also check this answer
https://stackoverflow.com/questions/60310054/im-having-troubles-displaying-an-image-from-json-in-a-table-view*

Swift 4 download Swedens radio channels

I got the same error when I try to get previous and song that play right now for every channel. I think something is wrong in my struct Root and playlist because data is not in the correct format.I am using Swift 4 and trying to learn JSON, but its hard. Previous struct is same as Song struct.
How do I fix my error?
My code looks now:
*struct Root : Decodable {
let copyright : String
let channels : [Channel]
let pagination : Pagination
//let playlists : [Playlist]
}
struct Channel : Decodable {
let image : String
let imagetemplate : String
let color : String
let tagline : String?
let siteurl : String
let id : Int
let url : URL?
let statkey : String?
let scheduleurl : String
let channeltype : String
let name : String
}
struct Pagination : Decodable {
let page, size, totalhits, totalpages : Int
let nextpage : URL
}
struct Playlist : Decodable{
let id : Int
let name :String
let prev : [previoussong]
let song : [Song]
}
struct Song : Decodable {
let title : String
let description : String
let artist : String
let composer :String
let conductor : String
let albumname : String
let recordlabel : String
let lyricist : String
let producer : String
let starttimeutc : String
let stopttimeutc : String
}
var tests = [Channel]()
var pl = [Playlist]()
func downloadStations(){
let test2 = "http://api.sr.se/api/v2/channels?format=json"
let play = "http://api.sr.se/api/v2/playlists/rightnow?format=json"
let url = URL(string: test2) /// play instead of test2
URLSession.shared.dataTask(with: url!){ (data , response, error) in
do{
let root = try JSONDecoder().decode(Root.self, from: data!)
self.tests = root.channels
//self.pl = root.playlists
for eachStations in self.tests {
DispatchQueue.main.async {
self.tableV.reloadData()
}
}
} catch {
print(error.localizedDescription)
}
}.resume()*
It doesn't return the array of channels. It returns an object:
{
"copyright": "somestring",
"pagination": {},
"channels": []
}
So, copyright is not a part of channel and you have an object with field channels.
Please read the JSON carefully. In the root object there is the key copyright and a key channels which contains the channel array.
You need to add an umbrella struct for the root object.
Please name the channel struct in singular form and with starting uppercase letter (Channel). Further some keys in the struct are optional.
struct Root : Decodable {
let copyright : String
let channels : [Channel]
let pagination : Pagination
}
struct Channel : Decodable {
let image : String
let imagetemplate : String
let color : String
let tagline : String?
let siteurl : String
let id : Int
let url : URL?
let statkey : String?
let scheduleurl : String
let channeltype : String
let name : String
}
struct Pagination : Decodable {
let page, size, totalhits, totalpages : Int
let nextpage : URL
}
var tests = [Channel]()
let root = try JSONDecoder().decode(Root.self, from: data!)
self.tests = root.channels
I got the same error when I try to get previous and song that play right now for every channel. How do I fix this?
My code looks now:
struct Root : Decodable {
let copyright : String
let channels : [Channel]
let pagination : Pagination
//let playlists : [Playlist]
}
struct Channel : Decodable {
let image : String
let imagetemplate : String
let color : String
let tagline : String?
let siteurl : String
let id : Int
let url : URL?
let statkey : String?
let scheduleurl : String
let channeltype : String
let name : String
}
struct Pagination : Decodable {
let page, size, totalhits, totalpages : Int
let nextpage : URL
}
struct Playlist : Decodable{
let id : Int
let name :String
let prev : [previoussong]
let song : [Song]
}
struct previoussong : Decodable {
let title : String
let description : String
let artist : String
let composer :String
let conductor : String
let albumname : String
let recordlabel : String
let lyricist : String
let producer : String
let starttimeutc : String
let stopttimeutc : String
}
struct Song : Decodable {
let title : String
let description : String
let artist : String
let composer :String
let conductor : String
let albumname : String
let recordlabel : String
let lyricist : String
let producer : String
let starttimeutc : String
let stopttimeutc : String
}
var tests = [Channel]()
var pl = [Playlist]()
var stationsName:String?
#IBOutlet weak var tableV: UITableView!
#IBOutlet weak var image: UIImageView!
#IBOutlet weak var statLabel: UILabel!
#IBOutlet weak var songLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
tableV.dataSource = self
downloadStations()
}
func downloadStations(){
let test2 = "http://api.sr.se/api/v2/channels?format=json"
let play = "http://api.sr.se/api/v2/playlists/rightnow?format=json"
let url = URL(string: test2) /// play instead of test2
URLSession.shared.dataTask(with: url!){ (data , response, error) in
do{
let root = try JSONDecoder().decode(Root.self, from: data!)
self.tests = root.channels
//self.pl = root.playlists
for eachStations in self.tests {
self.stationsName = eachStations.name
print(" " + self.stationsName!)
DispatchQueue.main.async {
self.tableV.reloadData()
}
}
} catch {
print(error.localizedDescription)
}
}.resume()

parsing json xcode swift 4

Problem. I want to parse the json from here and show on a table view, i am using swift 4 and Decodable. but i am getting a type mismatch error. Link to json:
https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=50fb91212a47432d802b3b1ac0f717a3
My Struct looks like this.
struct Root : Decodable {
let status : String
// let totalResults : Int
let articles : [Article]
}
struct Article : Decodable {
let source: Source
let author, title, description: String
let url: URL
// let publishedAt: Date
let urlToImage: String
}
struct Source: Decodable {
let id, name: String
}
My ViewDidLoad Looks like this :
var articles : [Article]? = []
override func viewDidLoad() {
super.viewDidLoad()
tableview.delegate = self
tableview.dataSource = self
fetchArticles()
}
func fetchArticles(){
let jsonURLString = "https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=50fb91212a47432d802b3b1ac0f717a3"
guard let url = URL(string: jsonURLString) else { return }
URLSession.shared.dataTask(with: url) { (data,response,err) in
guard let data = data else { return }
self.myArticles = [Article]()
do{
let decoder = JSONDecoder()
decoder.dataDecodingStrategy = .base64
let root = try decoder.decode(Root.self, from: data)
self.myArticles = root.articles
DispatchQueue.main.async {
self.tableview.reloadData()
}
} catch let error{
print(error)
}
}.resume()
}
My cellForRowAtIndexPath
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let myCell = tableView.dequeueReusableCell(withIdentifier: "articleCell", for: indexPath) as! ArticleCell
let article = self.myArticles[indexPath.row]
myCell.title.text = article.title
myCell.body.text = article.description
myCell.author.text = article.author
myCell.imgView.downloadImage(from: ("https://tctechcrunch2011.files.wordpress.com/2017/04/uber-vs-waymo.png"))
return myCell
}
Error i am getting.
No errors, nothing loads to the table view.
The error is clear. You are going to decode an array but the object is a dictionary.
This decodes the JSON including the special decoding to URL and Date.
The root object is a dictionary, the key articles contains the articles and source is a dictionary, not an array
struct Root : Decodable {
let status : String
let articles : [Article]
}
struct Article : Decodable {
let source: Source
let author, title, description: String
let url: URL
let publishedAt: Date
let urlToImage: String
}
struct Source: Decodable {
let id, name: String
}
var articles = [Article]()
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let root = try JSONDecoder().decode(Root.self, from: data)
self.articles = root.articles
DispatchQueue.main.async {
self.tableview.reloadData()
}
} catch { print(error) }
There is no need to use classes inheriting from NSObject
And do not declare the data source object as optional and get the same item a couple of times in cellForRow and it's indexPath.row
...
let article = self.articles[indexPath.row]
myCell.title.text = article.title
myCell.body.text = article.description
myCell.author.text = article.author
...

reload UICollectionview using swiftyJSON & TRON

i am having trouble to reload my UICollectionview after i got my json data using TRON pod (it is like alamofire but in different structure i think)
and i parsed it using swiftyJSON
i am searching for the answer about three days and i dont know what i am missing
...
import UIKit
import SwiftyJSON
import TRON
class FeaturedAppViewController: UICollectionViewController ,
UICollectionViewDelegateFlowLayout {
private let cellID = "cellId"
var appCategories : [AppCategory]?
override func viewDidLoad() {
super.viewDidLoad()
fetchHomeApps()
collectionView?.backgroundColor = .white
collectionView?.register(CategoryCell.self, forCellWithReuseIdentifier: cellID)
}
class Home : JSONDecodable{
var apps : [App]
required init(json: JSON) throws {
print("now ready to parse :\n", json)
var apps = [App]()
let catJSON = json["categories"]
let array = json["categories"].array
for app in array!{
for index in 0...catJSON.count - 1 {
let name = app["apps"][index]["Name"].stringValue
let id = app["apps"][index]["Id"].intValue
let imageName = app["apps"][index]["ImageName"].stringValue
let category = app["apps"][index]["Category"].stringValue
let price = app["apps"][index]["Price"].doubleValue
let appsIdentification = App(iD: id, name: name, category: category, price: price, imageName: imageName)
apps.append(appsIdentification)
}
}
self.apps = apps
}
}
class JSONError : JSONDecodable {
required init(json: JSON) throws {
print("josn Error")
}
}
fileprivate func fetchHomeApps() {
print("123")
let request : APIRequest<AppCategory , JSONError> = tron.request("/appstore/featured")
request.perform(withSuccess: { (AppCategory) in
print("Successfully Fetched")
print(AppCategory.apps.count)
self.collectionview.reloaddata()
}) { (err) in
print("couldnt Fetch babe \n" , err)
}
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let count = appCategories?.count {
return count
}else{
return 0
}
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! CategoryCell
cell.appCategory = appCategories?[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width , height: 230)
}
let tron = TRON(baseURL: "http://www.statsallday.com")
}
this is my view controller and there is a models page
import UIKit
import SwiftyJSON
import TRON
class AppCategory : NSObject , JSONDecodable {
var name : String?
var type : String?
let Url = "http://www.statsallday.com/appstore/featured"
var apps : [App]
required init(json: JSON) throws {
print("now ready to parse :\n", json)
var apps = [App]()
let catJSON = json["categories"]
let array = json["categories"].array
for app in array!{
for index in 0...catJSON.count - 1 {
let name = app["apps"][index]["Name"].stringValue
let id = app["apps"][index]["Id"].intValue
let imageName = app["apps"][index]["ImageName"].stringValue
let category = app["apps"][index]["Category"].stringValue
let price = app["apps"][index]["Price"].doubleValue
let appsIdentification = App(iD: id, name: name, category: category, price: price, imageName: imageName)
apps.append(appsIdentification)
}
}
self.apps = apps
}
}
struct App {
let iD : Int
let name : String
let category : String
let price : Double
let imageName : String
}
i think i should add something in fetchHomeApps function but i dont know what...
actually i started programming since 34 days age and sorry if i my code is silly.
You should call self.yourCollectionView.reloadData() when you fetched data from API and parse with swiftyJson. Only when appCategories have data not empty array object.