Core Data Fetch Result Not Convert NsManaged sub class - swift

class DeviceModel: NSManagedObject {
#NSManaged var deviceName: String?;
#NSManaged var devicePrice: String?;
}
class DeviceListController: UIViewController {
var deviceList: [Any] = [];
override func viewDidLoad() {
super.viewDidLoad();
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated);
let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate;
let context = appDelegate.persistentContainer.viewContext;
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Device");
do {
self.deviceList = try context.fetch(request);
} catch {
print(error);
}
}
}
extension DeviceListController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.deviceList.count;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: DeviceItemCell.reuiseIdentifier) as? DeviceItemCell else {
fatalError("Error create tableCell")
}
guard let item = deviceList[indexPath.row] as? DeviceModel else {
fatalError("Item not convertable DeviceModel");
}
cell.deviceName.text = item.value(forKey: "devicePrice") as! String
return cell;
}
}
let item = deviceList[indexPath.row] as? NSManagedObject is work but
when I change NSManagedObject to my DeviceModel class guard return
error why i dont convert item to DeviceModel class? But DeviceModel
class is sub class NsManagedObject

Related

Parsed value from array not displayed in tableview

I need to display value -> "all[0].id" into table row.
This value is id 123456 from JSON file.
Code builded without errors, but still without data in table row.
thanks for some suggestions
I parsed JSON File with this values:
{
"fields": {
"123456": {
"timestampValue": "2019-03-05T23:00:00Z"
},
"7895": {
"timestampValue": "2019-03-02T23:00:00Z"
}
},
"createTime": "2019-03-08T00:14:55.357221Z",
"updateTime": "2019-03-08T17:22:08.398718Z"
}
There is my ViewController file with tableview:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let data = DataLoader().userData
let all = [Item]()
#IBOutlet weak var tableView: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return all.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = all[0].id
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
}
There is my Code in DataLoader.swift:
public class DataLoader
{
#Published var userData = [Root]()
init()
{
load()
}
func load()
{
if let fileLocation = Bundle.main.url(forResource: "mydata", withExtension: "json")
{
// Do catch in case of error
do
{
let data = try Data(contentsOf: fileLocation)
let jsonDecoder = JSONDecoder()
let res = try jsonDecoder.decode(Root.self, from: data)
var all = [Item]()
for (id,item) in res.fields {
all.append(Item(id:id,timestampValue:item.timestampValue))
}
print(all)
}
catch
{
print(error)
}
}
}
}

How to get section of UITableView on a child UICollectionView

I create a View Controller that contains a UITableView and each UITableViewCell contains a UICollectionView. My problem is that I can't have a different result on every CollectionView. I parse data with JSON. I have a static array but it looks like its empty.
In cellForItemAt, I get an error: Index out of range.
Here is my ViewController
import UIKit
class HomeScreenCategoriesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var moviesCategories = ["Popular", "Now Playing", "Latest", "Top Rated", "Upcoming"]
var popularMovies = MovieModel()
var nowPlayingMovies = MovieModel()
static var movies: [MovieModel] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = 130
tableView.tableFooterView = UIView()
parsePopularMovies()
parseNowPlayingMovies()
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "\(moviesCategories[section])"
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "HomeScreenMovieTableViewCell", for: indexPath) as? HomeScreenCategoriesTableViewCell
{
return cell
}
return UITableViewCell()
}
func parsePopularMovies() {
let jsonUrlString = "URLwithMyAPIkey"
guard let url = URL(string: jsonUrlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
do {
let tempMovies = try
JSONDecoder().decode(MovieModel.self, from: data)
self.popularMovies.page = tempMovies.page
self.popularMovies.total_results = tempMovies.total_results
self.popularMovies.total_pages = tempMovies.total_pages
self.popularMovies.results = tempMovies.results
for i in 0..<(self.popularMovies.results?.count ?? 0) {
let tempPosterPath = "https://image.tmdb.org/t/p/w500" + (self.popularMovies.results?[i].poster_path)!!
let tempBackDropPath = "https://image.tmdb.org/t/p/w500" + (self.popularMovies.results?[i].backdrop_path)!!
self.popularMovies.results?[i].poster_path = tempPosterPath
self.popularMovies.results?[i].backdrop_path = tempBackDropPath
HomeScreenCategoriesViewController.movies.append(self.popularMovies)
}
} catch let jsonErr {
print("Error serializing json:", jsonErr)
}
}.resume()
}
func parseNowPlayingMovies() {
let jsonUrlString = "URLwithMyAPIkey"
guard let url = URL(string: jsonUrlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
do {
let tempMovies = try
JSONDecoder().decode(MovieModel.self, from: data)
self.nowPlayingMovies.page = tempMovies.page
self.nowPlayingMovies.total_results = tempMovies.total_results
self.nowPlayingMovies.total_pages = tempMovies.total_pages
self.nowPlayingMovies.results = tempMovies.results
for i in 0..<(self.nowPlayingMovies.results?.count ?? 0) {
let tempPosterPath = "https://image.tmdb.org/t/p/w500" + (self.nowPlayingMovies.results?[i].poster_path)!!
//let tempBackDropPath = "https://image.tmdb.org/t/p/w500" + (self.nowPlayingMovies.results?[i].backdrop_path)!!
self.nowPlayingMovies.results?[i].poster_path = tempPosterPath
HomeScreenCategoriesViewController.movies.append(self.nowPlayingMovies)
}
} catch let jsonErr {
print("Error serializing json:", jsonErr)
}
}.resume()
}
}
and here is my TableViewCell
import UIKit
class HomeScreenCategoriesTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
#IBOutlet var collectionView: UICollectionView!
var sectionIndex:Int?
static var movies: [MovieModel] = []
override func awakeFromNib() {
super.awakeFromNib()
self.collectionView.delegate = self
self.collectionView.dataSource = self
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "HomeScreenMovieTableViewCell", for: indexPath) as! HomeScreenCategoriesTableViewCell
cell.sectionIndex = indexPath.section
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeScreenMovieCell", for: indexPath) as! HomeScreenCategoriesCollectionViewCell
cell.test.text = HomeScreenCategoriesTableViewCell.movies[collectionView.tag].results?[indexPath.row].title!
return cell
}
}
My model is this:
struct MovieResults: Codable, Equatable {
let id: Int?
let title: String?
let overview: String?
let adult: Bool?
let original_language: String?
var poster_path: String?
var backdrop_path: String?
let vote_average: Float?
let release_date: String?
}
struct MovieModel: Codable {
var page: Int?
var total_results: Double?
var total_pages: Int?
var results: [MovieResults]?
}
I tried to follow this instruction (How to get section of UITableView from inside a child UICollectionview) but I can't​ find a solution
What am I doing wrong?
There are few issues here:
Model naming
The data model object you use is confusing. MovieModel sounds like it should represent a single movie. But looking at parsing functions,
self.nowPlayingMovies.page = tempMovies.page
self.nowPlayingMovies.total_results = tempMovies.total_results
self.nowPlayingMovies.total_pages = tempMovies.total_pages
self.nowPlayingMovies.results = tempMovies.results
it looks like there are multiple entries in that object. It should probably be called MovieCategoryModel.
HomeScreenCategoriesTableViewCell should have a model that looks like this:
var movieCategory: MovieCategoryModel!
Since you are going to have different movies in
different sections, movieCategory property should not be static.
cellForItemAt indexPath In this method you are trying to configure cell UI with the data about the movie. But the properties of HomeScreenCategoriesTableViewCell was never populated.
numberOfItemsInSection
This should return the number of movies in that section. Your code returns 5 - which is some arbitrary number. That's the issue for the error. You should return movieCategory.total_results
cellForRowAt indexPath
In HomeScreenCategoriesViewController when you dequeue HomeScreenMovieTableViewCell, you need to pass the movies to that cell, so it will have data to present. You need to do something like:
if section == 0 {
cell.movieCategory = popularMovies
} else if section == 1 {
cell.movieCategory = nowPlayingMovies
}
In general, from the parsing code, you need to save the movies separately for each category. That way in the tableView delegate methods you can easily fetch the data you need for the section.
Parsing code also needs some work, as I can see you are cycling through the items contained within the object
for i in 0..<(self.nowPlayingMovies.results?.count ?? 0)
but adding the whole object to the array within that same loop
`HomeScreenCategoriesViewController.movies.append(self.nowPlayingMovies)`
Edit based on extra information provided:
MovieResults is very confusing name for an object that represents a single Movie. I would suggest changing it to just Movie.
Then MovieModel - the object that contains multiple movies, would be a MovieCategory. Maybe it's also a good idea to store the title of that category within the object itself?
Models
struct Movie: Codable, Equatable {
let id: Int?
let title: String?
let overview: String?
let adult: Bool?
let original_language: String?
var poster_path: String?
var backdrop_path: String?
let vote_average: Float?
let release_date: String?
}
struct MovieCategory: Codable {
var title: String?
var page: Int?
var total_results: Double?
var total_pages: Int?
var results: [Movie]?
}
View Controller
import UIKit
class HomeScreenCategoriesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var moviesCategories: [MovieCategory] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = 130
tableView.tableFooterView = UIView()
parsePopularMovies()
parseNowPlayingMovies()
}
func numberOfSections(in tableView: UITableView) -> Int {
return moviesCategories.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let category = moviesCategories[section]
return category.title
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "HomeScreenMovieTableViewCell", for: indexPath) as? HomeScreenCategoriesTableViewCell
{
cell.movieCategory = moviesCategories[indexPath.section]
return cell
}
return UITableViewCell()
}
func parsePopularMovies() {
let jsonUrlString = "URLwithMyAPIkey"
guard let url = URL(string: jsonUrlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
do {
var popularMovies = try
JSONDecoder().decode(MovieCategory.self, from: data)
popularMovies.title = "Popular Movies"
for i in 0..<(popularMovies.results?.count ?? 0) {
let tempPosterPath = "https://image.tmdb.org/t/p/w500" + (popularMovies.results?[i].poster_path)!!
let tempBackDropPath = "https://image.tmdb.org/t/p/w500" + (popularMovies.results?[i].backdrop_path)!!
popularMovies.results?[i].poster_path = tempPosterPath
popularMovies.results?[i].backdrop_path = tempBackDropPath
}
self.moviesCategories.append(popularMovies)
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch let jsonErr {
print("Error serializing json:", jsonErr)
}
}.resume()
}
func parseNowPlayingMovies() {
let jsonUrlString = "URLwithMyAPIkey"
guard let url = URL(string: jsonUrlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
do {
var nowPlayingMovies = try
JSONDecoder().decode(MovieCategory.self, from: data)
for i in 0..<(nowPlayingMovies.results?.count ?? 0) {
let tempPosterPath = "https://image.tmdb.org/t/p/w500" + (nowPlayingMovies.results?[i].poster_path)!!
//let tempBackDropPath = "https://image.tmdb.org/t/p/w500" + (self.nowPlayingMovies.results?[i].backdrop_path)!!
nowPlayingMovies.results?[i].poster_path = tempPosterPath
}
self.moviesCategories.append(nowPlayingMovies)
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch let jsonErr {
print("Error serializing json:", jsonErr)
}
}.resume()
}
}
TableViewCell
class HomeScreenCategoriesTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
#IBOutlet var collectionView: UICollectionView!
var sectionIndex:Int?
var movieCategory: MovieCategory!
override func awakeFromNib() {
super.awakeFromNib()
self.collectionView.delegate = self
self.collectionView.dataSource = self
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeScreenMovieCell", for: indexPath) as! HomeScreenCategoriesCollectionViewCell
if indexPath.row < movieCategory.results?.count ?? 0 {
let movie = movieCategory.results?[indexPath.row]
cell.test.text = movie.title
}
return cell
}
}

Swift Firebase retrieve data into tableview

My database tree
Hello,
I am trying to retrieve data to to tableview but although I can read data from firebase database, I cannot display them in table view. My code is below, I hope you can help me.
class Calls {
var callType: String?
var callHospital: String?
init(callType: String?, callHospital: String?) {
self.callType = callType
self.callHospital = callHospital
}
}
class myCallsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var ref:DatabaseReference!
var myCallList = [Calls]()
#IBOutlet weak var callListTableView: UITableView!
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myCallList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customcell", for: indexPath) as! myCallsViewControllerTableViewCell
let test = myCallList[indexPath.row]
cell.callType?.text = test.callType
cell.callHospital?.text = test.callHospital
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
callListTableView.dataSource = self
callListTableView.delegate = self
LoadCalls()
}
func LoadCalls() {
ref = Database.database().reference()
let userID = Auth.auth().currentUser?.uid
ref.child("calls").queryOrdered(byChild: "userID").queryEqual(toValue: userID!).observe(.childAdded, with: { (snapshot) in
if snapshot.childrenCount > 0{
self.myCallList.removeAll()
for result in snapshot.children.allObjects as! [DataSnapshot]{
let results = result.value as? [String : AnyObject]
let type = results?["calltype"]
let hospital = results?["hospital"]
let myCalls = Calls(callType: type as! String?, callHospital: hospital as! String?)
self.myCallList.append(myCalls)
}
self.callListTableView.reloadData()
}
})
}
I solved the problem, thank you guys,Blake and Siyavash, so much. I registered the cell and put dispatch main queue and it worked. Here is the latest code:
class Calls {
var callType: String?
var callHospital: String?
init(callType: String?, callHospital: String?) {
self.callType = callType
self.callHospital = callHospital
}
}
class myCallsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var ref:DatabaseReference!
var myCallList = [Calls]()
#IBOutlet weak var callListTableView: UITableView!
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myCallList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customcell", for: indexPath) as! myCallsViewControllerTableViewCell
let test = myCallList[indexPath.row]
cell.callType?.text = test.callType
cell.callHospital?.text = test.callHospital
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
callListTableView.dataSource = self
callListTableView.delegate = self
LoadCalls()
}
func LoadCalls() {
ref = Database.database().reference()
let userID = Auth.auth().currentUser?.uid
ref.child("calls").queryOrdered(byChild: "userID").queryEqual(toValue: userID!).observe(.childAdded, with: { (snapshot) in
let results = snapshot.value as? [String : AnyObject]
let type = results?["calltype"]
let hospital = results?["hospital"]
let myCalls = Calls(callType: type as! String?, callHospital: hospital as! String?)
self.myCallList.append(myCalls)
DispatchQueue.main.async {
self.callListTableView.reloadData()
}
})
}
Your issue probably has to do with the fact that you're calling reloadData() from a closure, which means you're updating the UI from a background thread. Check out this answer:
Swift UITableView reloadData in a closure

Why is JSON data from local path shows incorrectly in the UITableView?

I want to parse JSON data from a local file that is available in the project and then populate these data to UITableView.
My Requirements
parse the json data from local path not from URL
Populate the json data to UITableView
Facing problems
Unable to display the parsed data, ( bracket is displaying in the table view.
I am able to print the data in console using dump() but unable to print data in tableView
Updated view controller for passing data to another controller.
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return lookArrayModel.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cells = myTableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let displayData = lookArrayModel[indexPath.row]
cells.textLabel?.text = String(describing: displayData.Lookname!)
cells.detailTextLabel?.text = String(describing: displayData.Lookdetails!)
// print(displayData.shadeModel)
return cells
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.row)!")
// Get Cell Label
let indexPath = myTableView.indexPathForSelectedRow;
let currentCell = myTableView.cellForRow(at: indexPath!) as UITableViewCell!;
lookNameValue = currentCell?.textLabel?.text
lookDetailValue = currentCell?.detailTextLabel?.text
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//let lookShade = LookModelData()
if (segue.identifier == "segueToLook") {
let destController:DetailsViewController = segue.destination as! DetailsViewController
//Set the selecte row index value
destController.LabelText = String(describing: lookNameValue)
destController.DetailText = String(describing: lookDetailValue)
// destController.arrayData = lookShade.shadeModel as! NSMutableArray
}
}
}
Destination view controller. Swift
class DetailsViewController:UIViewController,UITableViewDataSource,UITableViewDelegate {
var lookArrayModel = [LookModelData]()
var arrayData: NSMutableArray = []
#IBOutlet weak var secondView: UITableView!
var LabelText = String()
var DetailText = String()
var shadeText = String()
#IBOutlet weak var LookLabel: UILabel!
#IBOutlet weak var LookName: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
print(arrayData)
LookName?.text = LabelText
LookLabel?.text = DetailText
secondView.dataSource = self
secondView.delegate = self
secondView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayData.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cells = secondView.dequeueReusableCell(withIdentifier: "secondCell", for: indexPath)
let displayData = arrayData
// cells.textLabel?.text = String(describing: (displayData as AnyObject))
// print(arrayData)
return cells
}
}
Please check my code :
Changed lookArrayModel type NSMutableArray to [LookModelData]. Like those I did some changes. Please check.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var lookArrayModel = [LookModelData]()
#IBOutlet weak var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
guard let Path = Bundle.main.path(forResource: "ColorShade", ofType: "json") else { return }
let url = URL(fileURLWithPath: Path)
do {
let data = try Data(contentsOf: url)
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
myTableView.dataSource = self
myTableView.delegate = self
//Calling the function for adding look
createLooks(dictionary: json as! NSArray)
myTableView.reloadData()
} catch {
print(error)
}
}
func createLooks(dictionary:NSArray) {
for item in dictionary {
let item1 = item as! NSDictionary
let lookModal = LookModelData()
lookModal.Lookname = item1.value(forKey: "Lookname") as? String
lookModal.LookId = item1.value(forKey: "LookId") as? String
lookModal.Lookdetails = item1.value(forKey: "Lookdetails") as? String
lookModal.shadeModel = createshade(shades: item1.value(forKey: "shades") as! NSArray)
lookArrayModel.append(lookModal)
}
}
func createshade(shades: NSArray) -> [ShadeDescription] {
var arrayShade = [ShadeDescription]()
for item in shades
{
let item1 = item as! NSDictionary
let shadeModal = ShadeDescription()
shadeModal.comboID = item1.value(forKey: "comboID") as? String
shadeModal.shadeName = item1.value(forKey: "shadeName") as? String
shadeModal.ShadeType = item1.value(forKey: "ShadeType") as? String
shadeModal.ShadeCode = item1.value(forKey: "shadeCode") as? String
arrayShade.append(shadeModal)
}
return arrayShade
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return lookArrayModel.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cells = myTableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let displayData = lookArrayModel[indexPath.row]
// You will get like this
// print(displayData.LookId!)
// print(displayData.Lookname!)
// print(displayData.Lookdetails!)
// print(displayData.shadeModel!)
// This is the way to get shade model data
if let shadeModels = displayData.shadeModel {
for var shadeModel in shadeModels {
print(shadeModel.comboID)
print(shadeModel.ShadeType)
print(shadeModel.shadeName)
print(shadeModel.ShadeCode)
}
}
cells.textLabel?.text = String(describing: displayData.Lookname!)
return cells
}
}
class LookModelData
{
var Lookname:String?
var LookId:String?
var Lookdetails:String?
//Shades Array
var shadeModel : [ShadeDescription]?
}
class ShadeDescription {
var ShadeType:String?
var shadeName:String?
var comboID:String?
var ShadeCode:String?
}

why is my data not showing in the tableview?

Printing out the data in the console works just fine. In viewdidload method the array count is also fine. But if i use any of the code outside viewdidload its not working. Im trying to populate a table with two labels in each cell (airline and price) but none of the data is displaying and when i try out in the console arrayOfFlights.price.count (for example) it prints out 0 as if its empty.
Data:
import Foundation
class FlightDataModel {
var airline: String?
var price: String?
init(airline: String?, price: String?) {
self.airline = airline
self.price = price
}
}
controller.swift
import Foundation
import UIKit
class FlightsController: UITableViewController, UITableViewDataSource {
var arrayOfFlights : [FlightDataModel] = [FlightDataModel]()
var startpoint:String!
var endpoint:String!
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.arrayOfFlights.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as myCustomTableViewCell
cell.airlineLabel.text = arrayOfFlights[indexPath.row].airline
cell.priceLabel.text = arrayOfFlights[indexPath.row].price
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
// json request to api
let qpxRequest = Router.QPXRequest()
request(qpxRequest).responseJSON { (request, response, json, error) -> Void in
if json != nil {
//insert airline data into arrayOfFlights
if let myJSON = json as? [String:AnyObject] {
if let trips = myJSON["trips"] as? [String:AnyObject] {
if let data = trips["data"] as? [String:AnyObject] {
if let carriers = data["carrier"] as? [[String:String]] {
for (index, carrierName) in enumerate(carriers) {
var myFlight = FlightDataModel(airline: carrierName["name"] as String!, price:nil)
self.arrayOfFlights.append(myFlight)
}
}
}
if let tripOptions = trips["tripOption"] as? [[String:AnyObject]] {
for (index, tripOption) in enumerate(tripOptions) {
self.arrayOfFlights[index].price = tripOption["saleTotal"] as String!
}
}
}
}
}
} // end api request
} //end viewdidload
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
}
Make sure your class is set as dataSource of your tableView
And call the method tableView.reloadData() when you are done with the data parsing.