-
Notifications
You must be signed in to change notification settings - Fork 4
/
QuizVC.swift
185 lines (169 loc) · 6.45 KB
/
QuizVC.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//
// QuizVC.swift
// Conjugar
//
// Created by Joshua Adams on 6/18/17.
// Copyright © 2017 Josh Adams. All rights reserved.
//
import UIKit
class QuizVC: UIViewController, UITextFieldDelegate, QuizDelegate {
private let settings: Settings
private let quiz: Quiz
private let analyticsService: AnalyticsServiceable
private let gameCenter: GameCenterable
var quizView: QuizView {
if let castedView = view as? QuizView {
return castedView
} else {
fatalError(fatalCastMessage(view: QuizView.self))
}
}
init(settings: Settings, quiz: Quiz, analyticsService: AnalyticsServiceable, gameCenter: GameCenterable) {
self.settings = settings
self.quiz = quiz
self.analyticsService = analyticsService
self.gameCenter = gameCenter
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
UIViewController.fatalErrorNotImplemented()
}
override func loadView() {
let quizView: QuizView
quizView = QuizView(frame: UIScreen.main.bounds)
quizView.startRestartButton.addTarget(self, action: #selector(startRestart), for: .touchUpInside)
navigationItem.titleView = UILabel.titleLabel(title: "Quiz")
quizView.conjugationField.delegate = self
view = quizView
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
quiz.delegate = self
switch quiz.quizState {
case .notStarted, .finished:
quizView.hideInProgressUI()
quizView.startRestartButton.setTitle("Start", for: .normal)
case .inProgress:
quizView.showInProgressUI()
quizView.startRestartButton.setTitle("Restart", for: .normal)
let verb = quiz.verb
quizView.verb.text = verb
let translationResult = Conjugator.shared.conjugate(infinitive: verb, tense: .translation, personNumber: .none)
switch translationResult {
case let .success(value):
quizView.translation.text = value
default:
fatalError("translation not found.")
}
quizView.tenseLabel.text = quiz.tense.displayName
quizView.pronoun.text = quiz.currentPersonNumber.pronoun
quizView.score.text = String(quiz.score)
quizView.progress.text = String(quiz.currentQuestionIndex + 1) + " / " + String(quiz.questionCount)
}
quizView.startRestartButton.pulsate()
authenticate()
analyticsService.recordVisitation(viewController: "\(QuizVC.self)")
}
private func authenticate() {
if !gameCenter.isAuthenticated && settings.userRejectedGameCenter {
if !settings.didShowGameCenterDialog {
showGameCenterDialog()
} else {
gameCenter.authenticate(analyticsService: analyticsService, completion: nil)
}
}
}
private func showGameCenterDialog() {
settings.didShowGameCenterDialog = true
let gameCenterController = UIAlertController(title: "Game Center", message: "Would you like Conjugar to upload your future scores to Game Center after your quiz? See how you stack up against the global community of conjugators.", preferredStyle: UIAlertController.Style.alert)
let noAction = UIAlertAction(title: "No", style: UIAlertAction.Style.destructive) { _ in
SoundPlayer.play(.sadTrombone)
self.settings.userRejectedGameCenter = true
}
gameCenterController.addAction(noAction)
let yesAction = UIAlertAction(title: "Yes", style: UIAlertAction.Style.default) { _ in
self.gameCenter.authenticate(analyticsService: self.analyticsService, completion: nil)
}
gameCenterController.addAction(yesAction)
present(gameCenterController, animated: true, completion: nil)
}
@objc func startRestart() {
SoundPlayer.play(.gun)
quiz.start()
quizView.startRestartButton.setTitle("Restart", for: .normal)
[quizView.lastLabel, quizView.correctLabel, quizView.last, quizView.correct].forEach {
$0.isHidden = true
}
quizView.showInProgressUI()
quizView.startRestartButton.pulsate()
quizView.conjugationField.becomeFirstResponder()
analyticsService.recordQuizStart()
}
func scoreDidChange(newScore: Int) {
quizView.score.text = String(newScore)
}
func timeDidChange(newTime: Int) {
quizView.elapsed.text = newTime.timeString
}
func progressDidChange(current: Int, total: Int) {
quizView.progress.text = String(current + 1) + " / " + String(total)
}
func questionDidChange(verb: String, tense: Tense, personNumber: PersonNumber) {
quizView.verb.text = verb
let translationResult = Conjugator.shared.conjugate(infinitive: verb, tense: .translation, personNumber: .none)
switch translationResult {
case let .success(value):
quizView.translation.text = value
default:
fatalError()
}
quizView.tenseLabel.text = QuizView.tenseString + " " + tense.displayName
quizView.pronoun.text = personNumber.pronoun
quizView.conjugationField.becomeFirstResponder()
}
func quizDidFinish() {
quizView.hideInProgressUI()
quizView.startRestartButton.setTitle("Start", for: .normal)
let applauseIndex = Int.random(in: 1...Sound.applauseCount)
switch applauseIndex {
case 1:
SoundPlayer.play(.applause1)
case 2:
SoundPlayer.play(.applause2)
case 3:
SoundPlayer.play(.applause3)
default:
break
}
let resultsVC = ResultsVC(quiz: quiz, analyticsService: analyticsService)
navigationController?.pushViewController(resultsVC, animated: true)
analyticsService.recordQuizCompletion(score: quiz.score)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
guard let text = quizView.conjugationField.text else { return false }
guard text != "" else { return false }
quizView.conjugationField.resignFirstResponder()
let (result, correctConjugation) = quiz.process(proposedAnswer: text)
quizView.conjugationField.text = nil
switch result {
case .totalMatch:
SoundPlayer.play(.chime)
case .partialMatch:
SoundPlayer.play(.chirp)
case .noMatch:
SoundPlayer.play(.buzz)
}
if let correctConjugation = correctConjugation, quiz.quizState == .inProgress {
[quizView.lastLabel, quizView.last, quizView.correctLabel, quizView.correct].forEach {
$0.isHidden = false
}
quizView.last.attributedText = text.coloredString(color: Colors.blue)
quizView.correct.attributedText = correctConjugation.conjugatedString
} else {
[quizView.lastLabel, quizView.last, quizView.correctLabel, quizView.correct].forEach {
$0.isHidden = true
}
}
return true
}
}