初心者です。よろしくお願いいたします。
前提・実現したいこと
swift3を使って本を参考に簡単なクイズアプリを作成しています。
エラーが出ないようにしたいです。
発生している問題・エラーメッセージ
スタート画面から問題表示画面に移行するときに以下のエラーが出てしまう
以下ソースコードになります。
エラーメッセージ
unexpectedly found nil while unwrapping an Optional value
以下の部分でEXC_BAD_INSTRUCTION(code=EXC_INVOP,subcode=0x0)と表示され、アプリが停止してしまいます。
swift
1questionNoLabel.text = "Q.(questionData.questionNo)"
該当のソースコード
問題画面とスタート画面とデータベースのコードを置いておきます。よろしくお願いいたします。
問題画面
swift
1import UIKit 2import AudioToolbox 3 4 5class QuestionViewController: UIViewController{ 6 7 var questionData: QuestionData! 8 9 @IBOutlet weak var questionNoLabel: UILabel! 10 @IBOutlet weak var questionTextView: UITextView! 11 @IBOutlet weak var answer1Button: UIButton! 12 @IBOutlet weak var answer2Button: UIButton! 13 @IBOutlet weak var answer3Button: UIButton! 14 @IBOutlet weak var answer4Button: UIButton! 15 @IBOutlet weak var correctImageView: UIImageView! 16 @IBOutlet weak var incorrectImageView: UIImageView! 17 18 override func viewDidLoad() { 19 super.viewDidLoad() 20 21 questionNoLabel.text = "Q.(questionData.questionNo)" 22 questionTextView.text = questionData.question 23 answer1Button.setTitle(questionData.answer1,for: UIControlState.normal) 24 answer2Button.setTitle(questionData.answer2,for: UIControlState.normal) 25 answer3Button.setTitle(questionData.answer3,for: UIControlState.normal) 26 answer4Button.setTitle(questionData.answer4,for: UIControlState.normal) 27 } 28 29 override func didReceiveMemoryWarning() { 30 super.didReceiveMemoryWarning() 31 } 32 @IBAction func tapAnswer1Button(_ sender: Any) { 33 questionData.userChoiceAnswerNumber = 1 34 goNextQuestionWithAnimation() 35 } 36 @IBAction func tapAnswer2Button(_ sender: Any){ 37 questionData.userChoiceAnswerNumber = 2 38 goNextQuestionWithAnimation() 39 } 40 41 @IBAction func tapAnswer3Button(_ sender: Any) { 42 questionData.userChoiceAnswerNumber = 3 43 goNextQuestionWithAnimation() 44 } 45 46 @IBAction func tapAnswer4Button(_ sender: Any) { 47 questionData.userChoiceAnswerNumber = 4 48 goNextQuestionWithAnimation() 49 50 } 51 func goNextQuestionWithAnimation(){ 52 if questionData.isCorrect(){ 53 goNextQuestionWithCorrectAnimation() 54 } else{ 55 goNextQuestionWithInCorrectAnimation() 56 } 57 } 58 func goNextQuestionWithCorrectAnimation(){ 59 AudioServicesPlayAlertSound(1025) 60 UIView.animate(withDuration: 2.0, animations:{ 61 self.correctImageView.alpha = 1.0 62 }){(Bool) in self.goNextQuestion() 63 } 64 } 65 func goNextQuestionWithInCorrectAnimation(){ 66 AudioServicesPlayAlertSound(1006) 67 UIView.animate(withDuration: 2.0, animations:{ 68 self.correctImageView.alpha = 1.0 69 }){(Bool) in self.goNextQuestion() 70 } 71 } 72 func goNextQuestion(){ 73 guard let nextQuestion = QuestionDataManager.sharedInstance.nextQuestion() else{ 74 if let resultViewController = storyboard?.instantiateViewController(withIdentifier: "result") as? ResultViewController{ 75 present(resultViewController, animated: true, completion: nil) 76 } 77 return 78 } 79 if let nextQuestionViewController = storyboard?.instantiateViewController(withIdentifier: "question") 80 as? QuestionViewController{ 81 82 nextQuestionViewController.questionData = nextQuestion 83 present(nextQuestionViewController, animated: true,completion: nil) 84 } 85 } 86} 87 88
スタート画面
import UIKit class StartViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning(){ super.didReceiveMemoryWarning() } override func prepare(for segue: UIStoryboardSegue, sender:Any?){ QuestionDataManager.sharedInstance.loadQuestion() guard let nextViewController = segue.destination as? QuestionViewController else { return } guard let questionData = QuestionDataManager.sharedInstance.nextQuestion() else { return } nextViewController.questionData = questionData } @IBAction func goToTitle(_ segue: UIStoryboardSegue){ } }
データベース
import Foundation class QuestionData { var question: String var answer1: String var answer2: String var answer3: String var answer4: String var correctAnswerNumber: Int var userChoiceAnswerNumber: Int? var questionNo: Int = 0 init(questionSourceDataArray: [String]){ question = questionSourceDataArray[0] answer1 = questionSourceDataArray[1] answer2 = questionSourceDataArray[2] answer3 = questionSourceDataArray[3] answer4 = questionSourceDataArray[4] correctAnswerNumber = Int(questionSourceDataArray[5])! } func isCorrect() -> Bool{ if correctAnswerNumber == userChoiceAnswerNumber{ return true } return false } } class QuestionDataManager{ static let sharedInstance = QuestionDataManager() var questionDataArray = [QuestionData]() var nowQuestionIndex: Int = 0 private init(){ } func loadQuestion(){ questionDataArray.removeAll() nowQuestionIndex = 0 guard let csvFilePath = Bundle.main.path(forResource: "question", ofType: "csv") else { print("csvファイルが存在しません") return } do { let csvStringData = try String(contentsOfFile: csvFilePath, encoding: String.Encoding.utf8) csvStringData.enumerateLines(invoking:{ (line, stop) in let questionSourceDataArray = line.components(separatedBy: ",") let questionData = QuestionData (questionSourceDataArray: questionSourceDataArray) self.questionDataArray.append(questionData) questionData.questionNo = self.questionDataArray.count }) } catch let error{ print("csvファイル読み込みエラーが発生しました:(error)") return } } func nextQuestion() -> QuestionData? { if nowQuestionIndex < questionDataArray.count { let nextQuestion = questionDataArray[nowQuestionIndex] nowQuestionIndex += 1 return nextQuestion } return nil } }
試したこと
読み込み部分のコードでおかしい部分がないか確認しましたが間違えていないと思います。。
https://yutahand.com/coffeequiz/
またこのブログを参考に自分でナンバーを設定もしたのですおなじようなエラーが出てしまいます。
またこのブログではバグと書いてあり、再起動で治ると書いてありましたが再起動しても治りませんでした。
補足情報(FW/ツールのバージョンなど)
swift 3
xcode 8.2.1
参考にしている本:本気ではじめるiPhoneアプリ作り 黒帯エンジニアがしっかり教える基本テクニック Xcode8.X+Swift3.X対応
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/12/07 08:23
2018/12/07 08:27
2018/12/07 08:30
2018/12/07 08:39
2018/12/08 15:53