Dictionary causes index out of range error in Swift - swift

Sorry if this is asked already but I haven't found a solution for it. I'm new to Swift so please bear with me. I can't figure out why I keep getting an error of Thread 1: Fatal Error: Index out of range. I've used the same method before in displaying a txt file to which I never got a problem with before so this is the first time. I'm trying to display coordinates as the text details with the date and time as text in the cells itself.
Date and Time
Latitude, Longitude
Something like the above (Imagine it in a cell)
The following is my code for the program
import UIKit
import MapKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//Array to store the list
var storeCoordinates = [String: String]()
var arrayClient = NSMutableArray()
var readings: [String] = [" "]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Get path of where the file is
let path = Bundle.main.path(forResource: "gps_coords", ofType: "csv")
//Use filemanager to check if the file exist to avoid crashing if it doesn't exist
let fileMgr = FileManager.default
//Display the number of line counts we have
if fileMgr.fileExists(atPath: path!){
do {
let fulltext = try String(contentsOfFile: path!, encoding: String.Encoding.utf8)
readings = fulltext.components(separatedBy: "\n") as [String]
for i in 0..<readings.count{
let listData = readings[i].components(separatedBy: ";") as [String]
storeCoordinates["Latitude"] = "\(listData[0])"
storeCoordinates["Longitude"] = "\(listData[1])"
storeCoordinates["DateAndTime"] = "\(listData[2])"
arrayClient.add(storeCoordinates)
}
} catch let error as NSError {
print("Error: \(error)")
}
}
self.title = "Number of entries: \(arrayClient.count)"
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayClient.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellReuseIdentifier", for: indexPath)
let client = arrayClient[indexPath.row] as AnyObject
cell.textLabel?.text = "\(client.object(forKey: "DateAndTime")!)"
cell.detailTextLabel?.text = "\(client.object(forKey: "Latitude")!) \(client.object(forKey: "Longitude")!)"
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
}
The error I had is on storeCoordinates["Latitude"] = "\(listData[0])"
Using breakpoints, it shows the Latitude value is not empty along with Longitude and DateAndTime but if I try to run the app in the simulator, it gives the error Thread 1: Fatal Error: Index out of range. So far no luck in trying to figure out how to fix this. If you could help me figure it out, it would mean a lot to me. Please and thank you.

I regard the unreliable CSV format as the origin of the issue.
This is a quick tutorial to use a better format (JSON) and a more robust data source.
Part 1: Convert CSV to JSON
Create a new Blank Playground (press ⌥⇧⌘N) platform macOS
Press ⌘0 to show the project navigator of the Playground.
⌥-drag the CSV file from the project navigator of the main project into the Resources folder of the Playground.
Paste the following code into the Playground, it's based on your code to parse the CSV. It converts the CSV to JSON and creates a file gps_coords.json on the desktop. You'll get a fatal error if any field is missing.
struct Coordinate : Encodable {
let latitude, longitude, dateAndTime : String
}
let url = Bundle.main.url(forResource: "gps_coords", withExtension: "csv")!
let fulltext = try! String(contentsOf: url, encoding: .utf8)
let lines = fulltext.components(separatedBy: .newlines)
let coordinates = lines.map { paragraph -> Coordinate in
let components = paragraph.components(separatedBy: ";")
if components.count != 3 { fatalError("Each line must contain all three fields")}
return Coordinate(latitude: components[0], longitude: components[1], dateAndTime: components[2])
}
do {
let data = try JSONEncoder().encode(coordinates)
let homeURL = URL(fileURLWithPath: NSHomeDirectory())
let destinationURL = homeURL.appendingPathComponent("Desktop/gps_coords.json")
try data.write(to: destinationURL)
} catch { print(error) }
Part 2: Implement the new file
Close the Playground. It's not needed anymore.
Drag the new file from the desktop into the project navigator (make sure Copy If Needed is checked).
Change the ViewController class to
import UIKit
import MapKit
struct Coordinate : Decodable {
let latitude, longitude, dateAndTime : String
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var arrayClient = [Coordinate]()
override func viewDidLoad() {
super.viewDidLoad()
let url = Bundle.main.url(forResource: "gps_coords", withExtension: "json")!
let data = try! Data(contentsOf: url)
arrayClient = try! JSONDecoder().decode([Coordinate].self, from: data)
self.title = "Number of entries: \(arrayClient.count)"
tableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayClient.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellReuseIdentifier", for: indexPath)
let client = arrayClient[indexPath.row]
cell.textLabel?.text = client.dateAndTime
cell.detailTextLabel?.text = client.latitude + " " + client.longitude
return cell
}
}
Note: The UITableView outlet is missing and I added the line to reload the data. Make also sure that delegate and datasource is connected in Interface Builder from the table view to the ViewController.
Delete the CSV file.
The new code uses a struct Coordinate as data source and decodes the JSON very conveniently with JSONDecoder. Please note the missing type casts and the cumbersome key subscription to get the values from the dictionary.

As in the comment, mentioned by #vadian, It is not possible that you didn't get 0th index. But you add some checks.
Update your code as following:
Some updates are -
Use swift based array [[String: String]] rather NSMutableArray
Initialize the storeCoordinates for each loop cycle and check if your listData have more than 3 items or not
class AViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//Array to store the list
var arrayClient = [[String: String]]()
var readings: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
//Get path of where the file is
let path = Bundle.main.path(forResource: "gps_coords", ofType: "csv")
//Use filemanager to check if the file exist to avoid crashing if it doesn't exist
let fileMgr = FileManager.default
//Display the number of line counts we have
if fileMgr.fileExists(atPath: path!){
do {
let fulltext = try String(contentsOfFile: path!, encoding: String.Encoding.utf8)
readings = fulltext.components(separatedBy: "\n") as [String]
for i in 0..<readings.count {
// Check if you can get data from `readings[i]`
let listData = readings[i].components(separatedBy: ";") as [String]
if listData.count == 3 {
var storeCoordinates = [String: String]()
storeCoordinates["Latitude"] = "\(listData[0])"
storeCoordinates["Longitude"] = "\(listData[1])"
storeCoordinates["DateAndTime"] = "\(listData[2])"
arrayClient.append(storeCoordinates)
}
}
} catch let error as NSError {
print("Error: \(error)")
}
}
self.title = "Number of entries: \(arrayClient.count)"
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayClient.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellReuseIdentifier", for: indexPath)
let client = arrayClient[indexPath.row]
if let dateTime = client["DateAndTime"], let latitude = client["DateAndTime"], let longitude = client["DateAndTime"] {
cell.textLabel?.text = "\(dateTime)"
cell.detailTextLabel?.text = "\(latitude) \(longitude)"
}
return cell
}
}

Related

Index out of range when presenting JSON data in tableview

I am having issue identifying and changing the color of tableview rows that contain the same name value in both [ListStruct] which contains the inital data for the tableview rows, and [HighlightStruct] which contains the name that need to be highlighted.
Initially I have the following JSON array populate my tableview:
private func fetchJSON() {
guard let url = URL(string: "www.test.com")
else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = "test=test1".data(using: .utf8)
URLSession.shared.dataTask(with: request) { data, _, error in
guard let data = data else { return }
do {
self.structure = try JSONDecoder().decode([ListStruct].self,from:data)
DispatchQueue.main.async {
self.tableView.reloadData()
}}catch {print(error)}}.resume()}
struct ListStruct: Codable {
let id: String
let wo: String
let name: String
let type: String
}
Then the same view controller has a second JSON array that is decoded below for highlighting:
func processJSON(_ json: String) {
do{
let mydata = Data(json.utf8)
let decoded = try JSONDecoder().decode(Set<HighlightStruct>.self,from: mydata)
print(decoded)
} catch {
print(error)
}
}
struct HighlightStruct: Codable, Hashable {
var id: Int
var name: String
}
Applying Highlight
var mySet: Set<HighlightStruct> = []
var highlightedStructure = [HighlightStruct]()
var structure = [ListStruct]()
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell") as! myCell
let portfolio: ListStruct
portfolio = structure[indexPath.row]
let highlight: HighlightStruct
highlight = highlightedStructure[indexPath.row]
//Highlight those that match in both arrays
if highlight.wo == portfolio.wo {
cell.backgroundColor = .yellow
}
Getting index out of range
You are getting index out of range error because your arrays are empty or there is no index that exist in your arrays. Maybe you can check your service call, the arrays could not be filled properly.
Make sure ur two list count is same size, or process data to one list.
You need to handle exceptions when structure does not have same wo to compare.
struct ListStruct: Codable {
let id: String
let wo: String
let name: String
let type: String
let hightlight:HighlightStruct!
}
func processJSON(_ json: String) {
do{
let mydata = Data(json.utf8)
let decoded = try JSONDecoder().decode(Set<HighlightStruct>.self,from: mydata)
print(decoded)
for hl in decoded{
var filter = structure.filter({$0.wo == hl.wo})
filter.hightlight = hl
}
} catch {
print(error)
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell") as! myCell
let portfolio: ListStruct
portfolio = structure[indexPath.row]
//Highlight those that match in both arrays
if portfolio.hightlight?.wo == portfolio.wo {
cell.backgroundColor = .yellow
}

How do I delete a cell from tableview

im trying to delete a cell from a tableview, and from Firestore too.
This how I declared my cart :
struct Cart
{
var photoKeyCart: String
var foodCart: String
var priceCart: Int
}
var cart: [Cart] = [] // This is in the cart controller
This is my tableview where I have my cart items :
extension CartViewController: UITableViewDelegate, UITableViewDataSource
{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var sum = 0
for item in cart{
sum += item.priceCart
}
priceTotalLabel.text = "\(sum) lei"
return cart.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = cartTableView.dequeueReusableCell(withIdentifier: "CartTableViewCell", for: indexPath) as! CartTableViewCell
let carts = cart[indexPath.row]
let storageRef = Storage.storage().reference()
let photoRef = storageRef.child(carts.photoKeyCart)
cell.foodInCartPrice.text = " \(carts.priceCart) lei "
cell.foodInCartName.text = carts.foodCart
cell.foodInCartImage.sd_setImage(with: photoRef)
cell.foodInCartImage.layer.borderWidth = 1
cell.foodInCartImage.layer.masksToBounds = false
cell.foodInCartImage.layer.borderColor = UIColor.black.cgColor
cell.foodInCartImage.layer.cornerRadius = cell.foodInCartImage.frame.height/2
cell.foodInCartImage.clipsToBounds = true
return cell
}
This is how im getting the data from the Firestore into the cart. This is called in the view did load.
func getCartProducts() {
let db = Firestore.firestore()
let userID = (Auth.auth().currentUser?.uid)!
db.collection("CartDatabase").document(userID).collection("CartItems").getDocuments { (document, error) in
if let error = error {
print(error)
return
} else {
for document in document!.documents {
let data = document.data()
let newEntry = Cart(photoKeyCart: data["photoKeyCart"] as! String, foodCart: data["foodCart"] as! String , priceCart: data["priceCart"] as! Int
)
self.cart.append(newEntry)
}
}
DispatchQueue.main.async {
// self.datas = self.filteredData
self.cartTableView.reloadData()
}
}
}
And, this is how im trying to delete the cell from the tableview, and from the Firestore too.
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
let carts = cart[indexPath.row]
let storageRef = Storage.storage().reference()
let photoRef = storageRef.child(carts.photoKeyCart)
photoRef.delete { error in
if let error = error {
print(error.localizedDescription)
} else {
print("File deleted successfully")
}
}
let db = Firestore.firestore()
let userID = (Auth.auth().currentUser?.uid)!
db.collection("CartDatabase").document(userID).collection("CartItems").getDocuments { (document, error) in
if let error = error {
print(error.localizedDescription)
} else {
for document in document!.documents {
//print("\(document.documentID) => \(document.data())")
db.collection("CartDatabase").document(userID).collection("CartItems").document(document.documentID).delete()
//self.db.collection("users").document((user?.uid)!).collection("children").document("\(document.documentID)").delete()
}
}}
cart.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
I have the following problem. When im trying to delete the cell, it works, but when im closing the cart and coming back again to the cart, it deletes all the items into the cart, not just the one I tried to delete.
What I want to achieve : to delete just only the cell selected.
Help :D
UPDATE:
I have a tableview with which contains a food, each cell is aa different king of food. I have a plus button, when the plus button is tapped, ill send the datas of the food into the Firestore, and in the cart I retrieve the data.
This is how im sending the data to the cart :
func updateDocument(collection: String, newValueDict: [String : Any], completion:#escaping (Bool) -> Void = {_ in }) {
let db = Firestore.firestore()
let userID = (Auth.auth().currentUser?.uid)!
db.collection(collection).document(userID).collection("CartItems").document().setData(newValueDict, merge: true){ err in
if let err = err {
print("Error writing document: \(err)")
completion(false)
}else{
completion(true)
}
}
}
And when I tapped the cell :
cell.didTapButton = {
self.updateDocument(collection: "CartDatabase",newValueDict: ["foodCart" : mancare.foodName, "photoKeyCart": mancare.photoKeyRestaurant, "priceCart": mancare.priceFood])
}
Check the photos
Photo1
Photo2
Without seeing all of the code it's hard to provide a specific example but let me cover this at a high level.
Suppose we have a posts class object
class PostsClass {
var docId = ""
var post = ""
}
and an class array (aka a 'dataSource') to store them in
var postsArray = [PostsClass]()
The first step is to load all of the posts from Firebase, storing the docId and post text in each class and then store the class in the dataSource array.
myFirebase.getDocuments { doc...
for doc in documents { //iterate over the documents and populate the array
let post = PostClass(populate with data from firebase)
self.postsArray.add(post)
}
}
the dataSouce array will look like this
postsArray[0] = some post
postsArray[1] = another post
etc, and all of that is displayed in a tableView.
The user then decides to delete the post at row 1. So they swipe row one, which fires a tableView delegate event letting the app know the index of the swiped row.
Step 1: You then get that post from the array based on the swiped row index
let postToDelete = self.postsArray[swiped index]
let docIdToDelete = postsToDelete.docID
Step 2: then remove it from the array
self.postsArray.deleteRow(atIndex: swiped index)
Step 3: then delete it from Firebase.
self.my_firebase.collection("posts").document(docIdToDelete).delete {....
Note that the func tableView:tableView:commit editingStyle will present the editing style of .delete when the row is supposed to be deleted and also provide the index in indexPath.row

How to write my Struct to Firebase

I have this struct:
struct Info {
var name: String = ""
var number = Int()
}
var infoProvided : [Info] = []
I display desired data in a tableView:
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "InfoCell") as! InfoTableViewCell
let name = infoProvided[indexPath.row].name
let number = infoProvided[indexPath.row].number
cell.infoLabelLabel.text = "\(name) with \(number)"
return cell
}
I am trying to write data to firebase like this:
self.ref?.child(gotLokasjon).child(location).child(dateAndTime).updateChildValues(["Signed up:" : infoProvided])
This returns the error:
Cannot store object of type _SwiftValue at 0. Can only store objects of type NSNumber, NSString, NSDictionary, and NSArray.'
How can I write my Struct to Firebase?. I would like to write it equal to how its displayed in the tableView:
cell.infoLabelLabel.text = "\(name) with \(number)"
I haven't understood where you want the upload to happen(before or after they are displayed on tableView) so adjust it to suit your needs.
guard let name = infoProvided.name else {return}
guard let number = infoProvided.number else {return}
let data = [ "name": name, "number": number] as [String : Any]
self.ref?.child(gotLokasjon).child(location).child(dateAndTime).updateChildValues(data, withCompletionBlock: { (error, ref) in
if error != nil{
print(error!)
return
}
print(" Successfully uploaded")
})
After a bit of fiddling I did this:
let infoArray = infoProvided.map { [$0.number, $0.name] }
let items = NSArray(array: infoArray)
Then implemented that in the above solution. This seams to work.
I don't know if this is a good solution?

Can any one help me to solve this error using Swift

would you please help me to solve this error .I'am trying to download an Image From Firebase Database, this is my code and I put a snapshot for the error . ThanksThis is a snapshot for the error in Xcode
import UIKit
import FirebaseDatabase
class ViewController: UIViewController , UITableViewDataSource , UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var ref:FIRDatabaseReference?
var Handle:FIRDatabaseHandle?
var myClass = [Post]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
ref=FIRDatabase.database().reference()
Handle = ref?.child("Posts").observe(.childAdded, with: { (snapshot) in
let post = snapshot.valueInExportFormat()
for url in post! as! [Post] { // Error Here
self.myClass.append(url)
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return myClass.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)as? TableViewCell{
cell.MyImage.alpha = 0
cell.textLabel?.text = PostData[indexPath.row]
DispatchQueue.main.async(execute: {
let imgurl = URL(string : self.myClass [(indexPath as NSIndexPath).row].url)
let imgdata = NSData(contentsOf: imgurl!)
cell.MyImage.image = UIImage(data: imgdata as! Data)
UIView.animate(withDuration: 0.5, animations: {
cell.MyImage.alpha = 1
})
})
return cell
} else {
let cell = TableViewCell()
DispatchQueue.main.async(execute: {
let imgurl = URL(string : self.myClass [(indexPath as NSIndexPath).row].url)
let imgdata = NSData(contentsOf: imgurl!)
cell.MyImage.image = UIImage(data: imgdata as! Data)
})
return cell
}
}
}
})
}
Sometimes simple is the way to go.
assume you have a Firebase structure
Planets
planet_4
some_text = "My post about Mars"
image_url = "images/mars.jpg"
planet_2
some_text = "My post about Venus"
image_url = "images/venus.jpg"
and suppose we want to load each text and image and display in a tableview. We can do it one of two ways, one at a time with .childAdded or all at once with .value. In this example, we'll walk through them one at a time.
let planetsRef = myRootRef.child("Planets")
planetsRef.observe(.childAdded, with: { snapshot in
let dict = snapshot.value as! [String: AnyObject]
let text = dict["text"]
let imageUrl = dict["image_url"]
// Create a reference to the file you want to download
let planetRef = storageRef.child(imageUrl) //storageRef is defined elsewhere
// Download in memory with a maximum allowed size
// of 1MB (1 * 1024 * 1024 bytes)
planetRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in
if (error != nil) {
// Got an error so handle it
} else {
// Data for "images/some planet.jpg" is returned
// let planetImage: UIImage! = UIImage(data: data!)
// then add the text and the image to your dataSource array
// and reload your tableview.
}
})
})
This is not tested but will provide the general idea
Maybe you want:
for url in post! {
var wrappedPost = Post()
wrappedPost.url = url
... use wrappedPost for whatever you need a Post object for
}

Remote Data won't show on tableView

I'm clueless as to what is wrong. My console doesn't give me any errors, my code seems fine but nothing is showing up. Could someone check my code, see why it doesn't want to work? My tableView is connected with its delegates and source. Not sure what is the problem.
Here is my code:
private let cellIdentifier = "cell"
private let apiURL = "api link"
class TableView: UITableViewController {
//TableView Outlet
#IBOutlet weak var LegTableView: UITableView!
//API Array
var legislatorArray = [congressClass]()
func getLegislators (fromSession session: NSURLSession) {
//Calling url
if let jsonData = NSURL(string: apiURL) {
// Requesting url
let task = session.dataTaskWithURL(jsonData) {(data, response, error) -> Void in
//Check for errors
if let error = error {print(error)
} else {
if let http = response as? NSHTTPURLResponse {
if http.statusCode == 200 {
//Getting data
if let data = data {
do {
let legislatorData = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers)
//Get API data
if let getData = legislatorData as? [NSObject:AnyObject],
findObject = getData["results"] as? [AnyObject]{
//Return data
for cellFound in findObject{
if let nextCell = cellFound["results"] as? [NSObject:AnyObject],
name = nextCell["first_name"] as? String,
lastName = nextCell["last_name"] as? String,
title = nextCell["title"] as? String,
partyRep = nextCell["party"] as? String,
position = nextCell ["position"] as? String,
id = nextCell ["bioguide_id"] as? String
{
//Add data to array
let addData = congressClass(name: name, lastName: lastName, title: title, party: partyRep, position: position, bioID: id)
self.legislatorArray.append(addData)
}
}//end cellFound
//Adding data to table
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.tableView.reloadData()
}
}
}
//end do
catch {print(error)}
}//end data
}//end statusCode
}//end http
}//else
}//end task
//Run code
task.resume()
}//end jsonData
}
override func viewDidLoad() {
super.viewDidLoad()
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let urlSession = NSURLSession(configuration: sessionConfig)
getLegislators(fromSession: urlSession)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
//TableView Rows
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return legislatorArray.count
//return 5
}
//Cell Configuration
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! CellTableView
cell.lesName?.text = legislatorArray[indexPath.row].name + " " + legislatorArray[indexPath.row].lastName
cell.lesTitle?.text = legislatorArray[indexPath.row].title
cell.lesParty?.text = legislatorArray[indexPath.row].party
//These tests worked fine.. the tableView is working. But the data doesn't seem to pass.
//cell.lesName.text = "Name" + " " + "lastName"
//cell.lesTitle.text = "Title goes here"
//cell.lesParty.text = "D"
return cell
}
}
You're not reloading the tableView
The problem is in this piece of code
//-----------------------------
//New empty array for api data
var indexPath:[NSIndexPath] = []
//Adding data to new array
for i in 0..<self.legislatorArray.count{
let secondIndexPath = NSIndexPath(forRow: i, inSection: 0)
indexPath.append(secondIndexPath)
}
//Adding data to table
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.tableView.insertRowsAtIndexPaths(indexPath, withRowAnimation: .Left)
}
You don't need any of that. You can just reload the tableView as follows:
//Adding data to table
dispatch_async(dispatch_get_main_queue()) { () -> Void in
//You only need to reload it and that should do the trick
self.tableView.reloadData()
}
I know you said your tableView is connected to the delegate and dataSource but it's not showing in your code.
You conformed the ViewController to the correct protocols but you need something like this in your viewDidLoad.
self.tableView.deletage = self
self.tableView.dataSource = self
//I don't know if this was a typo but in your cellForRowAtIndexPath you are using CellTableView
let nibName = UINib(nibName: "CellTableView", bundle:nil)
self.tableView.registerNib(nibName, forCellReuseIdentifier: cellIdentifier)
I created an example of a better design for your implementation
This is for the WebService and your Custom Class
https://github.com/phantomon/Stackoverflow/blob/master/SO1/MyTableView/MyTableView/Models/WebServiceManager.swift
This is for the ViewController with your tableView
https://github.com/phantomon/Stackoverflow/blob/master/SO1/MyTableView/MyTableView/ViewController.swift
You just need to modify the UITableViewCell with your custom one.
And of course review your custom class data.