簡単なマルバツのクイズアプリを作っています。
ビルドした後、スタートボタンを押すと下記のエラーメッセージが発生しました。
デバックエリアで確認すると変数に値が入っていないことが原因と考えられるのですが、何が原因で値が入らないのかが分かりません。
(5f2600f5e423658e4f212b8f4b57dd0f.png)
発生している問題・エラーメッセージ
Thread 1: Fatal error: Index out of range
該当のソースコード
Swift
1import UIKit 2 3 4 5class QuizViewController: UIViewController { 6 7 //問題表示の接続 8 @IBOutlet weak var numberLabel: UILabel! 9 @IBOutlet weak var questionLabel: UILabel! 10 @IBOutlet weak var circle: UIButton! 11 @IBOutlet weak var cross: UIButton! 12 13 //正誤表示 14 @IBOutlet weak var answerImage: UIImageView! 15 16 //問題を格納 17 var csvArray = [String]() 18 19 // 取り出した問題を格納 20 var questionArray = [String]() 21 22 // 変数 23 var questionCount = 0 // 出題数 24 var correctCount = 0 // 正解 25 26 //定数 27 let total = 3 // 出題数 28 let waitQuestion = 0.8 //表示の間隔 29 30 //ゲーム表示完了後に開くメソッド 31 override func viewDidLoad() { 32 super.viewDidLoad() 33 34 // 問題の読み込み 35 csvArray = loadCSV(filename: "loveswift") 36 37 // 画面の初期化 38 answerImage.isHidden = true 39 40 // 問題表示 41 nextProblem() 42 43 } 44 45 46 47 @IBAction func btnAction(_ sender: UIButton) { 48 // 正解とボタンのタグ番号が同じなら正解 49 if sender.tag == Int(questionArray[1]) { 50 answerImage.image = UIImage(named: "correct.png") 51 correctCount += 1 52 } else { 53 answerImage.image = UIImage(named: "incorrect.png") 54 } 55 56 // 回答表示の有効化(0.8秒間) 57 answerImage.isHidden = false 58 DispatchQueue.main.asyncAfter(deadline: .now() + waitQuestion) { 59 self.answerImage.isHidden = true 60 } 61 62 // 次の問題文呼び出し 63 questionCount += 1 64 nextProblem() 65 66 } 67 68 69 70 71 72 // 問題表示 73 func nextProblem() { 74 // questionArrayの初期化 75 questionArray.removeAll(keepingCapacity: true) 76 if questionCount < total { 77 // questionArrayに新規問題を格納 78 questionArray = csvArray[questionCount].components(separatedBy: ",") 79 //ここにThread 1: Fatal error: Index out of rangeというエラーメッセージが表示されます。 80 81 // 表示内容をセット 82 numberLabel.text = "第(questionCount+1)問" 83 questionLabel.text = questionArray[0] 84 circle.setTitle(questionArray[2], for: .normal) 85 cross.setTitle(questionArray[3], for: .normal) 86 87 } else { 88 // Storyboard Segue の Identifier を引数に定義して画面遷移 89 DispatchQueue.main.asyncAfter(deadline: .now() + waitQuestion) { 90 self.performSegue(withIdentifier: "toResultViewController", sender: nil) 91 } 92 } 93 } 94 95 96 97 // Segue で値を渡す 98 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 99 let sVC: ResultViewController = (segue.destination as? ResultViewController)! 100 sVC.correct = correctCount 101 } 102 103 104 105 // CSVファイルの読み込み 106 func loadCSV(filename : String)->[String] { 107 // 返却値の初期化 108 var csvStr:[String] = [] 109 110 // CSVを読み込んでArrayに 111 if let csvPath = Bundle.main.path(forResource: filename, ofType: "csv") { 112 do { 113 var csvData = try String(contentsOfFile: csvPath, 114 encoding: String.Encoding.utf8) 115 csvData = csvData.replacingOccurrences(of: "\n", with: "") 116 csvStr = csvData.components(separatedBy: .newlines) 117 } catch let error as NSError { 118 print(error.localizedDescription) 119 } 120 } 121 return csvStr 122 } 123 124 125 126 127 128} 129
試したこと
CSVデータ確認やcsvArreyの初期化が上手く行えていないのかなと検索したり、コードをみて試行錯誤してましたが、なかなか上手く行かないので質問しました。よろしくお願いします。
補足情報(FW/ツールのバージョンなど)
Xcode Version 10.2.1 (10E1001)
return csvStr のところでブレークポイント止めてArrayの中身を見せてもらってもいいでしょうか?
3elementsちゃんとあるのか気になります。
回答ありがとうございます。
ブレークポイント止めるまではわかりますが、Arreyの中身の表示の仕方が分かりません。
ちなみにCSVのデータは下記の通りです。
Swift,1,丸,罰
Swifta,2,丸,罰
Swiftb,2,丸,罰
初学者で分からないことだらけで申し訳ありません。
Xcodeのデバックエリアを表示して左側の欄でcsvStrを確認します。あるいはreturn csvStr の前でprint(String(csvStr.count))で何個Arrayに要素があるか確認してください。
ありがとうございます。
csvStr [String] 0 values
という表示が出ました。
Arreyに要素がない原因はどのようなことが考えられますか??
質問内の不要な文章を削除して下さい。
質問内の不要な文章がどこを指しているのか分かりません。。。。。
「前提・実現したいこと」がテンプレのまま残っています。
ご指摘ありがとうございます。訂正しました。
回答のコメントを汚すのもあれなのでこっちに書きます。
まず、用意するファイルは loveswift.csv じゃないとダメです。(loadCSV(filename:) の中で拡張子を追加しています)
次に、このファイルのTarget Membershipにチェックが入っているかどうか確認して下さい。File inspectorで確認できます。
細かなアドバイスに感謝しています。
Target Membershipにチェックが入っていることを確認しました。
読み込めていない前提でコメントが進んでいたので勘違いしていました。ファイルが読めていることは最初に確認していますね。【追記】勘違いでした
questionArray = csvArray[questionCount]....
の上の行に、
print(questionCount, total, csvArray.count)
を追加して、起動〜エラーが出るまでの出力を教えて下さい。
2019-07-31 17:57:18.410018+0900 FireLowQuiz[31305:3038288] libMobileGestalt MobileGestalt.c:890: MGIsDeviceOneOfType is not supported on this platform.
0 3 0
Fatal error: Index out of range
2019-07-31 17:57:19.598690+0900 FireLowQuiz[31305:3038288] Fatal error: Index out of range
(lldb)
このような出力となりました。
もしかして「スタートボタン」って前の画面のボタンのことですか?(この画面でボタンを押したら落ちるのかと思ってました)
ビルド後の一番最初の画面のボタンのことです!
「一番最初の画面」と言われてもこちらには分からないのですけどね‥。(QuizViewControllerが一番最初の画面かも知れないわけで)
loveswift.csv を一度プロジェクトから削除して、追加し直してもらえますか?(それで直りそうな気が)
たぶんですが、現在のloveswift.csvのファイル名は、頭にスペースが入ってます。そのスペースを削除して下さい。
ありがとうございます。
恥ずかしいですが、loveswiftの頭にスペースが入っていたことが原因でした。
また違うエラーが出てますが、自分で調べながらやってみようと思います。笑
これでやっと前に進むことができました。
わざわざ初心者に付き合っていただきありがとうございます。
またお願いします。笑
次からでいいですが、コードはテキストでお願いします。コピペや検索が出来ませんので。
あと、解決できたら質問をクローズしておいて下さい。
回答1件
あなたの回答
tips
プレビュー