You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift iOS固定题库实现及API题目解析技术问询

Hey there! Let's work through your Swift iOS addition app requirements one by one. I'll show you how to build a non-repeating question bank (fixed or dynamic from API) and assign values to your labels properly.


1. Implement a Non-Repeating Fixed Question Bank

First, let's fix the core issue of non-repeating questions. Instead of using two separate arrays for numbers, we'll use a structured approach to track full questions (both a and b values) so we can manage which ones we've already used.

Step 1: Define a Question Structure

Create a simple struct to hold each addition question's two numbers:

struct Question {
    let a: Int
    let b: Int
}

Step 2: Manage Question Banks in Your View Controller

We'll maintain two arrays: one for your original fixed questions, and one for currently available (unused) questions. When the available array is empty, we'll reset it to the original bank to start over.

class MathGameViewController: UIViewController {
    @IBOutlet weak var lbNum1: UILabel!
    @IBOutlet weak var lbNum2: UILabel!
    
    // Your fixed question bank (can be replaced with API data later)
    private var originalQuestions: [Question] = [
        Question(a: 1, b: 2),
        Question(a: 3, b: 2),
        Question(a: 8, b: 2),
        Question(a: 7, b: 9),
        Question(a: 6, b: 3)
    ]
    // Tracks questions that haven't been used yet
    private var availableQuestions: [Question] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Initialize available questions with the fixed bank
        resetAvailableQuestions()
        // Load the first question
        setNextQuestion()
    }
}

Step 3: Add Logic to Fetch Non-Repeating Questions

Add these helper methods to handle resetting the bank and loading the next unique question:

extension MathGameViewController {
    private func resetAvailableQuestions() {
        availableQuestions = originalQuestions
    }
    
    private func setNextQuestion() {
        // If all questions are used, reset the bank
        guard !availableQuestions.isEmpty else {
            resetAvailableQuestions()
        }
        
        // Pick a random unused question
        let randomIndex = Int(arc4random_uniform(UInt32(availableQuestions.count)))
        let selectedQuestion = availableQuestions.remove(at: randomIndex)
        
        // Assign values to your labels
        lbNum1.text = String(selectedQuestion.a)
        lbNum2.text = String(selectedQuestion.b)
        
        // Call your existing result calculation function
        setResult(randomA: selectedQuestion.a, randomB: selectedQuestion.b)
    }
    
    // Your existing result function (adjust as needed)
    private func setResult(randomA: Int, randomB: Int) {
        let sum = randomA + randomB
        print("Current sum: \(sum)")
        // Add your logic to display or check the result here
    }
}

2. Parse API Response to Generate Dynamic Question Bank

Now let's update your Alamofire request to pull questions from the API and replace your fixed bank. We'll safely parse the desc field's questions array to extract a and b values.

Add this method to your view controller:

extension MathGameViewController {
    private func fetchDynamicQuestionBank() {
        Alamofire.request("test", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil)
            .responseJSON { [weak self] response in
                guard let self = self else { return }
                
                switch response.result {
                case .success(let value):
                    // Parse the API response layer by layer (safe optional binding)
                    guard let responseArray = value as? [[String: Any]],
                          let homeworkItem = responseArray.first,
                          let descDict = homeworkItem["desc"] as? [String: Any],
                          let questionsArray = descDict["questions"] as? [[String: Int]] else {
                        print("Failed to parse API response structure")
                        return
                    }
                    
                    // Convert parsed JSON into Question objects
                    let dynamicQuestions = questionsArray.compactMap { questionDict in
                        guard let a = questionDict["a"], let b = questionDict["b"] else { return nil }
                        return Question(a: a, b: b)
                    }
                    
                    // Update the original bank with dynamic questions
                    self.originalQuestions = dynamicQuestions
                    self.resetAvailableQuestions()
                    
                    // Load the first dynamic question
                    self.setNextQuestion()
                    print("Successfully loaded dynamic question bank!")
                    
                case .failure(let error):
                    print("API request failed: \(error.localizedDescription)")
                }
            }
    }
}

Use the Dynamic Bank

To switch from fixed to dynamic questions, just call fetchDynamicQuestionBank() in viewDidLoad() instead of initializing with the fixed bank:

override func viewDidLoad() {
    super.viewDidLoad()
    fetchDynamicQuestionBank()
}

Key Fixes & Improvements

  • Replaced two separate number arrays with a single Question struct to keep pairs synchronized
  • Added availableQuestions to ensure no repeats until all questions are used
  • Safe JSON parsing with optional binding to avoid crashes from malformed API data
  • Clean separation between fixed and dynamic question bank logic

内容的提问来源于stack exchange,提问作者user9683424

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:31:06