Error message when running the application with the simulator.
Fatal error: Index out of range, in the line where I try to some value to an array
I really hope you have an answer for me
Here is my code
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var questionTextView: UITextView!
@IBOutlet weak var judgement: UILabel!
@IBOutlet weak var ans1: UIButton!
@IBOutlet weak var ans2: UIButton!
@IBOutlet weak var ans3: UIButton!
@IBOutlet weak var ans4: UIButton!
var question = ""
var CorAns = 0
var quizData: [Any] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
loadJsonFile()
updateQA()
}
func updateQA() {
let index = Int.random(in: 0...10)
let quizObject = quizData[index] as! Dictionary<String,Any> // ===> Thread 1: Fatal error: Index out of range
question = quizObject["question"] as! String
questionTextView.text = question
let correctAns: String = quizObject["correct_answer"] as! String
let wrongAns: [String] = quizObject["incorrect_answers"] as! [String]
let correctIndex: Int = Int.random(in: 0...3)
switch correctIndex {
case 0:
CorAns = 0
ans1.setTitle(correctAns, for: .normal)
ans2.setTitle(wrongAns[0], for: .normal)
ans3.setTitle(wrongAns[1], for: .normal)
ans4.setTitle(wrongAns[2], for: .normal)
case 1:
CorAns = 1
ans2.setTitle(correctAns, for: .normal)
ans1.setTitle(wrongAns[0], for: .normal)
ans3.setTitle(wrongAns[1], for: .normal)
ans4.setTitle(wrongAns[2], for: .normal)
case 2:
CorAns = 2
ans3.setTitle(correctAns, for: .normal)
ans2.setTitle(wrongAns[0], for: .normal)
ans1.setTitle(wrongAns[1], for: .normal)
ans4.setTitle(wrongAns[2], for: .normal)
case 3:
CorAns = 3
ans4.setTitle(correctAns, for: .normal)
ans2.setTitle(wrongAns[0], for: .normal)
ans3.setTitle(wrongAns[1], for: .normal)
ans1.setTitle(wrongAns[2], for: .normal)
default:
print("Error")
}
judgement.text = "Select Any One"
judgement.textColor = UIColor.black
}
private func loadJsonFile() {
do {
if let file = Bundle.main.url(forResource: "quiz", withExtension: "json") {
let data = try Data(contentsOf: file)
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let object = json as? [String: Any] {
// json is a dictionary
print("As Dictionary \(object)")
} else if let object = json as? [Any] {
// json is an array
print("As Array \(object)")
quizData = object
} else {
print("JSON is invalid")
}
} else {
print("no file")
}
} catch {
print(error.localizedDescription)
}
}
func correctAns() {
UIView.animate(withDuration: 1, animations: {
self.judgement.alpha = 0
}) { (complete) in
self.judgement.text = "Correct Answer"
self.judgement.textColor = UIColor.green
UIView.animate(withDuration: 1, animations: {
self.judgement.alpha = 1
}, completion: { (complete) in
DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
self.updateQA()
})
})
}
}
func wrongAns() {
UIView.animate(withDuration: 1, animations: {
self.judgement.alpha = 0
}) { (complete) in
self.judgement.text = "Wrong Answer"
self.judgement.textColor = UIColor.red
UIView.animate(withDuration: 1, animations: {
self.judgement.alpha = 1
}, completion: { (complete) in
DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
self.updateQA()
})
})
}
}
@IBAction func ans1Pressed(_ sender: Any) {
if (CorAns == 0) {
correctAns()
} else {
wrongAns()
}
}
@IBAction func ans2Pressed(_ sender: Any) {
if (CorAns == 1) {
correctAns()
} else {
wrongAns()
}
}
@IBAction func ans3Pressed(_ sender: Any) {
if (CorAns == 2) {
correctAns()
} else {
wrongAns()
}
}
@IBAction func ans4Pressed(_ sender: Any) {
if (CorAns == 3) {
correctAns()
} else {
wrongAns()
}
}
}
Well, that mean you have nothing in the dataArray.
You did not show what the print get on console.
To avoid a crash, you should change as:
func updateQA() {
if quizData.count == 0 { print("No data loaded" ; return }
let index = Int.random(in: 0 ..< quizData.count)
Root cause is probably here:
private func loadJsonFile() {
do {
if let file = Bundle.main.url(forResource: "quiz", withExtension: "json") {
let data = try Data(contentsOf: file)
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let object = json as? [String: Any] {
// json is a dictionary
print("As Dictionary \(object)")
} else if let object = json as? [Any] {
// json is an array
print("As Array \(object)")
quizData = object
} else {
print("JSON is invalid")
}
} else {
print("no file")
}
} catch {
print(error.localizedDescription)
}
}
Line 8, you don't load object into dataArray as you do line 11. Is it intentional ?
Please, once again, show the print outputs.