Kevin
Kevin

Reputation: 67

Index Out Of Range Error in Xcode

I am creating an app that uses a database, and am using labels to display the information. I first created a label that has date information, and when I ran the app it worked properly. When I added a second label for the away team information, I ran it and got an error that said : "Thread 1 Fatal Error : Index Out Of Range." Would this be related to the database, or the table view itself?

Here is the code :

import UIKit
import Firebase

class srFootballViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var ref = DatabaseReference()
    var Date = [String]()
    var awayTeam = [String]()
    var databaseHandle:DatabaseHandle = 0
    var databaseHandle2:DatabaseHandle = 0

    @IBOutlet var footballTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        ref = Database.database().reference()
        databaseHandle = ref.child("Dates").observe(.childAdded) { (snapshot) in

            let post = snapshot.value as? String
            if let actualPost = post {
                self.Date.append(actualPost)
                self.footballTableView.reloadData()
            }
        }

        databaseHandle2 = ref.child("awayTeams").observe(.childAdded) { (snapshot) in

            let post2 = snapshot.value as? String
            if let actualPost2 = post2 {
                self.awayTeam.append(actualPost2)
                self.footballTableView.reloadData()
            }
        }

    }


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return Date.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let footballCell = tableView.dequeueReusableCell(withIdentifier: "footballCell") as! srFootballCell
        footballCell.date.text = Date[indexPath.row]
        footballCell.awayTeam.text = awayTeam[indexPath.row]

        return(footballCell)
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }




}

Upvotes: 1

Views: 485

Answers (3)

vadian
vadian

Reputation: 285069

First of all do not use Date as a variable name. Date is a reserved word for a Swift struct. Swift variable names are supposed to start with a lowercase letter anyway.

The error occurs because the observe methods work asynchronously and you are using two different arrays at data source.

At the moment you are calling reloadData in the first observe completion block awayTeam is still empty and accessing item 0 causes the crash.

The solution is to call reloadData() only in the second ovserver or – more reliable – use DispatchGroup to notify when all database operations are completed. Apart from that it's highly recommended to use a custom struct as data source rather than multiple arrays.

Upvotes: 1

Miknash
Miknash

Reputation: 7948

Your awayTeam and Date arrays have different count of items - be sure to have same amount in order to prevent this crash - even better, create an object that will contain both of them.

Also, do NOT name your variable Date as it would conflict with Date class.

Upvotes: 1

DionizB
DionizB

Reputation: 1507

First you don't name a variable starting with capital letter. Second since you're using two different arrays for loading data in table view, awayTeam is crashing your app, because it doesn't have as many elements as Date array, because you're using Date.count for number of rows in section.

Change

databaseHandle = ref.child("Dates").observe(.childAdded) { (snapshot) in

        let post = snapshot.value as? String
        if let actualPost = post {
            self.Date.append(actualPost)
            self.footballTableView.reloadData()
        }
    }

to

databaseHandle = ref.child("Dates").observe(.childAdded) { (snapshot) in

    let post = snapshot.value as? String
    if let actualPost = post {
        self.Date.append(actualPost)
    }
}

So you won't reload table view data before loading awayTeam data.

Upvotes: 1

Related Questions