skip to Main Content

I am currently having trouble with the pickerview as when I click play quiz on the app the picker view is not loading from the web service at all. The picker view should display the array of answers from the web service. The picker view is empty any ideas? Also the question is not loading from the web service as a text label?

class QuestionsViewController: UIViewController, UIPickerViewDelegate {

@IBOutlet weak var usernamelabel: UILabel!
@IBOutlet weak var itemlabel: UILabel!
@IBOutlet weak var Question: UILabel!
@IBOutlet weak var pickerview: UIPickerView!

public var totalQuestions: Int = 0
public var currentQuestion = 0
public var totalCorrect: Int = 0
var itemSelected: String = ""
@IBOutlet weak var share: UIButton!
var LabelText = String()


var listQuestions = [[String: Any]]()
var titles: [String] = []
var qnames: String = ""

@IBOutlet weak var Next: UIButton!
var quiz = QuestionList()

override func viewDidLoad() {
    super.viewDidLoad() //when the app is loaded


    let url:String =     "https://api.mlab.com/api/1/databases/quiz/collections/question?apiKey=NT28RNl6jX3Ys0x5GJZ6mMSRQEcb_6KA"

    let urlRequest = URL(string: url)

    URLSession.shared.dataTask(with: urlRequest!, completionHandler: {
        (data, response, error) in
        if(error != nil){
            print(error.debugDescription)
        }
        else{
            do{
                self.listQuestions = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [[String:AnyObject]]
                print(self.listQuestions)

                for elements in self.listQuestions {
                    for object in elements {
                        if object.key == "Answers" {
                            if let answers = object.value as? [String] {
                                self.titles = answers
                            }
                            if object.key == "Questions" {
                                if let questions = object.value as? String {
                                    self.qnames = questions
                                }
                            }
                        }
                    }
                }
                self.pickerview.reloadAllComponents()

            }catch let error as NSError{
                print(error)
            }
        }
    }).resume()


}


func numberOfComponents(in pickerView: UIPickerView) -> Int {

    return 1 //return one component from the picker
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{

    return titles.count
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) ->String?{


    return self.titles[row]


}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int){

    itemSelected = QuestionList.getDummyQuestions()[currentQuestion].answers[row]

}

@IBAction func btnShareClicked(_ sender: Any) {
    if SLComposeViewController.isAvailable(forServiceType: SLServiceTypeFacebook) {

        let fbShare:SLComposeViewController = SLComposeViewController(forServiceType:SLServiceTypeFacebook)
        fbShare.setInitialText("You Scored " + itemlabel.text! + " on the IT Quiz")
        self.present(fbShare, animated:true, completion:nil)

    } else {
        let alert = UIAlertController(title: "Account", message: "Please login to Facebook",
                                      preferredStyle: UIAlertControllerStyle.alert)

        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler:nil))
        self.present(alert, animated: true, completion: nil)

    }


}





}

2

Answers


  1. Your ViewController is missing the UIPickerViewDataSource protocol:

    class QuestionsViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {}
    

    Make sure pickerView’s delegate and datasource is set to the current viewController.

    override func viewDidLoad() {
        super.viewDidLoad() //when the app is loaded
    
        pickerview.delegate = self
        pickerview.dataSource = self
    }
    

    The dataTask is an async task, you should update the UI on the main thread.

    DispatchQueue.main.async {
        self.pickerview.reloadAllComponents()
    }
    

    The final code should like this:

    class QuestionsViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    
        @IBOutlet weak var usernamelabel: UILabel!
        @IBOutlet weak var itemlabel: UILabel!
        @IBOutlet weak var Question: UILabel!
        @IBOutlet weak var pickerview: UIPickerView!
    
        public var totalQuestions: Int = 0
        public var currentQuestion = 0
        public var totalCorrect: Int = 0
        var itemSelected: String = ""
        @IBOutlet weak var share: UIButton!
        var LabelText = String()
    
    
        var listQuestions = [[String: Any]]()
        var titles: [String] = []
        var qnames: String = ""
    
        @IBOutlet weak var Next: UIButton!
        var quiz = QuestionList()
    
        override func viewDidLoad() {
            super.viewDidLoad() // when the app is loaded
    
            pickerview.delegate = self
            pickerview.dataSource = self
    
            let url:String = "https://api.mlab.com/api/1/databases/quiz/collections/question?apiKey=NT28RNl6jX3Ys0x5GJZ6mMSRQEcb_6KA"
    
            let urlRequest = URL(string: url)
    
            URLSession.shared.dataTask(with: urlRequest!, completionHandler: {
                (data, response, error) in
                if(error != nil){
                    print(error.debugDescription)
                }
                else{
                    do{
                        self.listQuestions = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [[String:AnyObject]]
                        print(self.listQuestions)
    
                        for elements in self.listQuestions {
                            for object in elements {
                                if object.key == "Answers" {
                                    if let answers = object.value as? [String] {
                                        self.titles = answers
                                    }
                                }
                                if object.key == "Questions" {
                                    if let questions = object.value as? String {
                                        self.qnames = questions
                                    }
                                }
                            }
                        }
    
                        DispatchQueue.main.async {
                            self.pickerview.reloadAllComponents()
                            self.Question.text = self.qnames
                        }
    
                    }catch let error as NSError{
                        print(error)
                    }
                }
            }).resume()
        }
    
    
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1 //return one component from the picker
        }
    
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
            return titles.count
        }
    
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) ->String? {
            return self.titles[row]
        }
    
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int){
    
            itemSelected = QuestionList.getDummyQuestions()[currentQuestion].answers[row]
    
        }
    
        @IBAction func btnShareClicked(_ sender: Any) {
            if SLComposeViewController.isAvailable(forServiceType: SLServiceTypeFacebook) {
    
                let fbShare:SLComposeViewController = SLComposeViewController(forServiceType:SLServiceTypeFacebook)
                fbShare.setInitialText("You Scored " + itemlabel.text! + " on the IT Quiz")
                self.present(fbShare, animated:true, completion:nil)
    
            } else {
                let alert = UIAlertController(title: "Account", message: "Please login to Facebook",
                                              preferredStyle: UIAlertControllerStyle.alert)
    
                alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler:nil))
                self.present(alert, animated: true, completion: nil)
    
            }
        }
    }
    
    Login or Signup to reply.
  2. To get question label:

    for object in elements {
    
          if let result = object["Questions"] as? [String: AnyObject] {
    
               print(result)
    
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search