I’m learning Swift and working on an English quiz app. I’ve managed to fetch questions and options from Airtable, but I’m stuck on how to check answers. Here’s what I’ve got so far:
func fetchQuizData() {
let endpoint = "https://api.airtable.com/v0/myBaseID/QuizTable?maxRecords=10&view=MainView"
let authToken = "myAuthToken"
guard let apiURL = URL(string: endpoint) else { return }
var apiRequest = URLRequest(url: apiURL)
apiRequest.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization")
URLSession.shared.dataTask(with: apiRequest) { (responseData, _, error) in
guard let data = responseData else { return }
do {
let quizContent = try JSONDecoder().decode(QuizResponse.self, from: data)
DispatchQueue.main.async {
self.updateUI(with: quizContent)
}
} catch {
print("Error: \(error)")
}
}.resume()
}
The problem is when I try to check the answer:
func validateAnswer(_ selectedOption: String) -> Bool {
// This crashes because 'quizContent' is nil
if selectedOption == quizContent.records[currentQuestionIndex].fields.correctAnswer {
score += 1
return true
}
return false
}
How can I properly check the answer without making another API call? Any help would be appreciated!
Hey there, FlyingLeaf! I’ve been down this road before with quiz apps, and I think I can help you out. The issue you’re facing is pretty common when dealing with asynchronous data fetching.
Here’s what I’d suggest: Instead of trying to access the quiz content directly in validateAnswer(), you should store the fetched data in a property of your view controller or wherever your main logic resides. This way, you’ll have access to it throughout your class.
Declare a property like this at the top of your class:
var quizData: [QuizQuestion] =
Then, in your fetchQuizData() function, after decoding the data, populate this array:
self.quizData = quizContent.records
Now, your validateAnswer() function can safely access this data:
if selectedOption == quizData[currentQuestionIndex].fields.correctAnswer {
// Correct answer logic
}
This approach ensures your data persists beyond the fetch function and is available when you need to validate answers. Just remember to handle potential out-of-bounds errors if currentQuestionIndex exceeds the array size. Hope this helps, and good luck with your app!
I encountered a similar issue when developing a language learning app. The solution is to store the quiz data as a property of your view controller or view model so that the data persists beyond the scope of the fetch function.
Declare a property at the class level:
var quizContent: QuizResponse?
Then, in your fetchQuizData() function, assign the decoded data to this property:
self.quizContent = quizContent
This way, validateAnswer() can access the quiz content directly. Remember to implement proper nil checks, for example:
guard let currentQuestion = quizContent?.records[safe: currentQuestionIndex] else {
return false
}
return selectedOption == currentQuestion.fields.correctAnswer
This approach avoids repeated API calls and helps improve overall app performance.
hey FlyingLeaf, looks like ur issue is with the scope of quizContent. try making it a property of ur class instead of a local var in fetchQuizData(). that way validateAnswer() can access it. also, make sure to handle cases where quizContent might be empty or nil to avoid crashes. good luck with ur app!