I'm newbie to Xcode and Swift.
This is my first program.
I include the full code.
I get this error and I don't know how to solve it.
The program builds ok, but when I run it I get this error.
Thread 1: Fatal error: init(coder:) has not been implemented
I appreciate if you provide a coded solution.
This is the ResultView Controller.swift file.
//
// ResultsViewController.swift
// PersonalityQuiz
//
// Created by Ricardo E. Marrero Guzmán on 12/16/21.
//
import UIKit
class ResultsViewController: UIViewController {
@IBOutlet var resultAnswerLabel: UILabel!
@IBOutlet var resultDefinitionLabel: UILabel!
var responses: [Answer] // Esto provoca un error. Para quitarlo se añade el siguiente init?...
init?(coder: NSCoder, responses: [Answer]) { // Este init?... provoca otro error. Se le da fix y se crea el siguiente required init?...
self.responses = responses
super.init(coder: coder)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented") // Thread 1: Fatal error: init(coder:) has not been implemented
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
calculatePersonalityResults()
navigationItem.hidesBackButton = true
}
func calculatePersonalityResults() {
let frecuencyOfAnswers = responses.reduce(into: [:]) {
(counts, answer) in counts[answer.type, default: 0] = 1
}
let frequentAnswersStored = frecuencyOfAnswers.sorted(by:
{ (pair1, pair2) in
return pair1.value > pair2.value
})
let mostCommonAnswer = frequentAnswersStored.first!.key
resultAnswerLabel.text = "You are \(mostCommonAnswer.rawValue)!"
resultDefinitionLabel.text = mostCommonAnswer.definition
}
This is de QuestionViewController.swift file
//
// QuestionViewController.swift
// PersonalityQuiz
//
// Created by Ricardo E. Marrero Guzmán on 12/16/21.
//
import UIKit
class QuestionViewController: UIViewController {
@IBOutlet var questionLabel: UILabel!
@IBOutlet var singleStackView: UIStackView!
@IBOutlet var singleButton1: UIButton!
@IBOutlet var singleButton2: UIButton!
@IBOutlet var singleButton3: UIButton!
@IBOutlet var singleButton4: UIButton!
@IBOutlet var multipleStackView: UIStackView!
@IBOutlet var multiLabel1: UILabel!
@IBOutlet var multiLabel2: UILabel!
@IBOutlet var multiLabel3: UILabel!
@IBOutlet var multiLabel4: UILabel!
@IBOutlet var multiSwitch1: UISwitch!
@IBOutlet var multiSwitch2: UISwitch!
@IBOutlet var multiSwitch3: UISwitch!
@IBOutlet var multiSwitch4: UISwitch!
@IBOutlet var rangedStackView: UIStackView!
@IBOutlet var rangedLabel1: UILabel!
@IBOutlet var rangedLabel2: UILabel!
@IBOutlet var rangedSlider: UISlider!
@IBOutlet var questionProgressView: UIProgressView!
var answersChosen: [Answer] = [] // No se donde va esto
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
updateUI()
}
@IBAction func singleAnswerButtonPressed(_ sender: UIButton) {
let currentAnswers = questions[questionIndex].answers
switch sender {
case singleButton1:
answersChosen.append(currentAnswers[0])
case singleButton2:
answersChosen.append(currentAnswers[1])
case singleButton3:
answersChosen.append(currentAnswers[2])
case singleButton4:
answersChosen.append(currentAnswers[3])
default:
break
}
nextQuestion()
}
@IBAction func multipleAnswerButtonPressed() {
let currentAnswers = questions[questionIndex].answers
if multiSwitch1.isOn {
answersChosen.append(currentAnswers[0])
}
if multiSwitch2.isOn {
answersChosen.append(currentAnswers[1])
}
if multiSwitch3.isOn {
answersChosen.append(currentAnswers[2])
}
if multiSwitch4.isOn {
answersChosen.append(currentAnswers[3])
}
nextQuestion()
}
@IBAction func rangedAnswerButtonPressed() {
let currentAnswers = questions[questionIndex].answers
let index = Int(round(rangedSlider.value * Float(currentAnswers.count - 1)))
answersChosen.append(currentAnswers[index])
nextQuestion()
}
func updateUI() {
singleStackView.isHidden = true
multipleStackView.isHidden = true
rangedStackView.isHidden = true
let currentQuestion = questions[questionIndex]
let currentAnswers = currentQuestion.answers
let totalProgress = Float(questionIndex) / Float(questions.count)
navigationItem.title = "Question #\(questionIndex 1)"
questionLabel.text = currentQuestion.text
questionProgressView.setProgress(totalProgress, animated: true)
switch currentQuestion.type {
case .single:
singleStackView.isHidden = false
updateSingleStack(using: currentAnswers)
case .multiple:
multipleStackView.isHidden = false
updateMultipleStack(using: currentAnswers)
case .ranged:
rangedStackView.isHidden = false
updateRangedStack(using: currentAnswers)
}
}
func updateSingleStack(using answers: [Answer]) {
singleStackView.isHidden = false
singleButton1.setTitle(answers[0].text, for: .normal)
singleButton2.setTitle(answers[1].text, for: .normal)
singleButton3.setTitle(answers[2].text, for: .normal)
singleButton4.setTitle(answers[3].text, for: .normal)
}
func updateMultipleStack(using answers: [Answer]) {
multipleStackView.isHidden = false
multiSwitch1.isOn = false
multiSwitch2.isOn = false
multiSwitch3.isOn = false
multiSwitch4.isOn = false
multiLabel1.text = answers[0].text
multiLabel2.text = answers[1].text
multiLabel3.text = answers[2].text
multiLabel4.text = answers[3].text
}
func updateRangedStack(using answers: [Answer]) {
rangedStackView.isHidden = false
rangedSlider.setValue(0.5, animated: false)
rangedLabel1.text = answers.first?.text
rangedLabel2.text = answers.last?.text
}
func nextQuestion() { // Este es el método más importante del programa y lo que hace correr el app bien.
questionIndex = 1
if questionIndex < questions.count {
updateUI()
} else {
performSegue(withIdentifier: "Results", sender: nil)
}
}
@IBSegueAction func showResults(_ coder: NSCoder) -> ResultsViewController? {
return ResultsViewController(coder: coder, responses: answersChosen)
}
This is the Question.swift file.
//
// Question.swift
// PersonalityQuiz
//
// Created by Ricardo E. Marrero Guzmán on 12/17/21.
//
import Foundation
struct Question {
var text: String
var type: ResponseType
var answers: [Answer]
}
enum ResponseType {
case single, multiple, ranged
}
struct Answer {
var text: String
var type: AnimalType
}
enum AnimalType: Character {
case dog = "