Home > Software design >  How to send data in extension to Button function
How to send data in extension to Button function

Time:10-05

I'm trying to make a quiz application using the API, I can take api data and show on app but I cannot transfer data from extension in viewController to button pressed.right now, when click the button, I want the clicked option to be green or red, how can I do it?

QuizManager

  import Foundation
    
    protocol quizManagerDelegate {
        func didUpdateQuiz(_ Quizmanager: QuizManager ,quiz: QuizModel)
    }
    
    struct QuizManager {
        
        var delegate: quizManagerDelegate?
        
        func performRequest(){
            
             let urlString = "https://opentdb.com/api.php?amount=1&type=multiple"        
            if let url = URL(string: urlString){
                
                let session = URLSession(configuration: .default)
                
                let task = session.dataTask(with: url) { data, response, error in
    
                    if error != nil {
                        print(error!)
                        return
                    }
                    if let safeData = data{
                                            
                        if let quiz = self.parseJSON(quizdata: safeData){
                            delegate?.didUpdateQuiz(self, quiz: quiz)
                            
    
                        }
                        
                    }
                }
                task.resume()
            }
        }
        
        func handle(data: Data?, response: URLResponse?, error: Error?) -> Void {
            
            
        }
        
        func parseJSON(quizdata: Data) -> QuizModel? {
            
            let decoder = JSONDecoder()
            
            do{
                let decodedData = try decoder.decode(Welcome.self, from: quizdata)
                
                let correct = decodedData.results?[0].correct_answer ?? "error"
                let quest = decodedData.results?[0].question ?? "error"
                let incorrect = decodedData.results?[0].incorrect_answers ?? ["error"]
                
                let question = QuizModel(correctAnswer: correct, question: quest, falseAnswer: incorrect)
    
             
                return question
            } catch {
                print(error)
                return nil
            }
        }
    }

QuizData

import Foundation


 // MARK: - Welcome
 struct Welcome: Codable {
 let results: [Result]?
 }
 
 // MARK: - Result
 struct Result: Codable {
     
 let category: String?
 let question, correct_answer: String?
 let incorrect_answers: [String]?
 }

QuizModel

    import Foundation
    
    struct QuizModel {
        
        let correctAnswer : String
        let question : String
        let falseAnswer : [String]
    }

ViewController

import UIKit
import GameKit

class ViewController: UIViewController {
 
    
    @IBOutlet weak var ChoiceButton4: UIButton!
    @IBOutlet weak var ChoiceButton3: UIButton!
    @IBOutlet weak var ChoiceButton2: UIButton!
    @IBOutlet weak var ChoiceButton1: UIButton!
    @IBOutlet weak var QuestionTextView: UITextView!
    
    var quizMangager = QuizManager()
    
        
    @IBAction func OptionsButtonPressed(_ sender: UIButton) {
        
        
        
        
    }
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        QuestionTextView.layer.cornerRadius = 15
        quizMangager.delegate = self
        quizMangager.performRequest()
    }

}

extension ViewController : quizManagerDelegate{
    func didUpdateQuiz(_ Quizmanager: QuizManager, quiz: QuizModel) {
        DispatchQueue.main.async { [self] in
            self.QuestionTextView.text = quiz.question
            
            var allOptions = []
            allOptions.append(quiz.falseAnswer[0])
            allOptions.append(quiz.falseAnswer[1])
            allOptions.append(quiz.falseAnswer[2])
            allOptions.append(quiz.correctAnswer)
            
            let generatedValue = Array(allOptions.shuffled().prefix(4))
            print(generatedValue)
            print(quiz.correctAnswer)

            ChoiceButton1.setTitle(generatedValue[0] as? String, for: .normal)
            ChoiceButton2.setTitle(generatedValue[1] as? String, for: .normal)
            ChoiceButton3.setTitle(generatedValue[2] as? String, for: .normal)
            ChoiceButton4.setTitle(generatedValue[3] as? String, for: .normal)

        }
    }
}

ViewController

import UIKit
import GameKit

class ViewController: UIViewController {
 
    
    @IBOutlet weak var ChoiceButton4: UIButton!
    @IBOutlet weak var ChoiceButton3: UIButton!
    @IBOutlet weak var ChoiceButton2: UIButton!
    @IBOutlet weak var ChoiceButton1: UIButton!
    @IBOutlet weak var QuestionTextView: UITextView!
    
    var quizMangager = QuizManager()
    
        
    @IBAction func OptionsButtonPressed(_ sender: UIButton) {
        
        
        
        
    }
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        QuestionTextView.layer.cornerRadius = 15
        quizMangager.delegate = self
        quizMangager.performRequest()
    }

}

extension ViewController : quizManagerDelegate{
    func didUpdateQuiz(_ Quizmanager: QuizManager, quiz: QuizModel) {
        DispatchQueue.main.async { [self] in
            self.QuestionTextView.text = quiz.question
            
            var allOptions = []
            allOptions.append(quiz.falseAnswer[0])
            allOptions.append(quiz.falseAnswer[1])
            allOptions.append(quiz.falseAnswer[2])
            allOptions.append(quiz.correctAnswer)
            
            let generatedValue = Array(allOptions.shuffled().prefix(4))
            print(generatedValue)
            print(quiz.correctAnswer)

            ChoiceButton1.setTitle(generatedValue[0] as? String, for: .normal)
            ChoiceButton2.setTitle(generatedValue[1] as? String, for: .normal)
            ChoiceButton3.setTitle(generatedValue[2] as? String, for: .normal)
            ChoiceButton4.setTitle(generatedValue[3] as? String, for: .normal)

        }
    }
}

CodePudding user response:

You need to "hold onto the quiz data."

So, add a var property to your view controller:

var quizMangager = QuizManager()

// add this
var theQuiz: QuizModel?

then, in your didUpdateQuiz func, set that property:

func didUpdateQuiz(_ Quizmanager: QuizManager, quiz: QuizModel) {
    DispatchQueue.main.async { [self] in

        // add this
        self.theQuiz = quiz
        
        self.QuestionTextView.text = quiz.question
        
        // ... no other changes

Now, connect all your buttons to @IBAction func OptionsButtonPressed and try this:

@IBAction func OptionsButtonPressed(_ sender: UIButton) {
    
    guard let thisQuiz = theQuiz,
          let btnTitle = sender.currentTitle
    else { return }
    
    if btnTitle == thisQuiz.correctAnswer {
        sender.setTitleColor(.systemGreen, for: [])
    } else {
        sender.setTitleColor(.systemRed, for: [])
    }
    
}
  • Related