0
    let ref = Database.database().reference(withPath: "items")
            ref.observe(.value) { (snapshot) in
                guard let dict = snapshot.value as? NSArray else { return }
                let decoder = JSONDecoder()
                decoder.keyDecodingStrategy = .convertFromSnakeCase
                dict.forEach { (value) in
                    do {

                        let itemData = try JSONSerialization.data(withJSONObject: value,options: .prettyPrinted)
                        let item = try decoder.decode(Item.self, from: itemData)
                            self.items.append(item)
                    }
                    catch let err {
                    print(err.localizedDescription)
                    }
                }
print(self.items) // This 
print(self.items[0]) // works 
            }

and trying to access items in tableview:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
itemType = String(describing: (self.items[indexPath.section].item_type)) // terminating with index out of range error
            //...
    }

The error occurs because the observe methods work asynchronously and executes later then tableview populates data.

How to solve this ?

3
  • how you are returning number of sections for UITableViewDataSource? Commented Feb 26, 2020 at 5:15
  • @Muhammad Afzal for now its constant int for testing purpose func numberOfSections(in tableView: UITableView) -> Int { return 3 } Commented Feb 26, 2020 at 5:20
  • that's the main reason your app crashing you need to return items.count in numberof section of you want to use sections if you want to use rows return number of rows. Commented Feb 26, 2020 at 5:22

2 Answers 2

1

You need something like this:::

let ref = Database.database().reference(withPath: "items")
        ref.observe(.value) { (snapshot) in
            guard let dict = snapshot.value as? NSArray else { return }
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            dict.forEach { (value) in
                do {

                    let itemData = try JSONSerialization.data(withJSONObject: value,options: .prettyPrinted)
                    let item = try decoder.decode(Item.self, from: itemData)
                        self.items.append(item)
                }
                catch let err {
                print(err.localizedDescription)
                }
            }

            self.yourtableView.reloadData()

            print(self.items) // This 
             print(self.items[0]) // works 
        }

And you need to implement numberOfRows at index path method

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

and return items.count there.

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

     itemType = String(describing: (self.items[indexPath.row].item_type)) // terminating with index out of range error
        //...
}
Sign up to request clarification or add additional context in comments.

1 Comment

@Jay Good.. but pay attention also to whether you want to use rows as the repeating entity or the sections in your table view.
1

if you want to use numberofsections

func numberOfSections(in tableView: UITableView) -> Int {
        return items.count
  }
 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
itemType = String(describing: (self.items[indexPath.section].item_type)) 
    }

if you want to use numberofrows

func numberOfSections(in tableView: UITableView) -> Int {
        return 1
  }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }
 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
itemType = String(describing: (self.items[indexPath.row].item_type)) 
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.