sssaaan sssaaan - 29 days ago 7
iOS Question

UILabel is not getting updated in ViewController swift3

I am parsing data from json and put them into variables then use those variables to change the value of UILabel but they're(UILabel) not getting updated, I have searched through the internet and they've said it is the result of updating UIlabel from thread other than main thread but here I have put it in viewController but still not getting updated
and here is my code:

import UIKit

class NewsContentViewController: UIViewController {


@IBOutlet weak var nuTitle: UILabel!
var namesArray = String()
var iD = String()
var description1 = String()
var iDArray = [String]()


@IBOutlet weak var tctView: UITextView!


override func viewDidLoad() {
super.viewDidLoad()

parseJSON()



nuTitle.text = self.namesArray
tctView.text = self.description1

// Do any additional setup after loading the view.
}




func parseJSON(){



let requestURL: NSURL = NSURL(string: "XXXXXX" + iD)!
print(requestURL)
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: requestURL as URL)
let session = URLSession.shared
let task = session.dataTask(with: urlRequest as URLRequest) {
(data, response, error) -> Void in


let readableJSON = JSON(data: data! , options: JSONSerialization.ReadingOptions.mutableContainers, error: nil)





if let Name = readableJSON[0]["Title"].string as String! {
var ID = readableJSON[0]["Id"].intValue
var iDString = String (ID)
self.namesArray.append(Name)

var desc = readableJSON[0]["Description"].string as String!
var type = readableJSON[0]["Type_Name"].string

self.iDArray.append(iDString)

self.description1 = desc!
self.namesArray = Name


}
}
task.resume()


}


}

Answer

Issue

The problem here is that the task inside parseJSON() will be executed asynchronously. And by the time that

nuTitle.text = self.namesArray
tctView.text = self.description1

that will be executed, task has not yet returned results.

Please read more about threading in iOS here

Solution

A proper solution on this case is for you to add a completionBlock which will return your data back.

override func viewDidLoad() {
    super.viewDidLoad()

    parseJSON { (description, name) in
        DispatchQueue.main.async {
            self.description1 = description
            self.namesArray = name
            nuTitle.text = self.namesArray
            tctView.text = self.description1
        }
    }
}

func parseJSON(completion: @escaping (_ description: String, _ name: String) -> Void) {
    let requestURL: NSURL = NSURL(string: "XXXXXX" + iD)!
    print(requestURL)
    let urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: requestURL as URL)
    let session = URLSession.shared
    let task = session.dataTask(with: urlRequest as URLRequest) {
        (data, response, error) -> Void in


        let readableJSON = JSON(data: data! , options: JSONSerialization.ReadingOptions.mutableContainers, error: nil)

        if let Name = readableJSON[0]["Title"].string as String! {
            var ID = readableJSON[0]["Id"].intValue
            var iDString = String (ID)
            self.namesArray.append(Name)

            var desc = readableJSON[0]["Description"].string as String!
            var type = readableJSON[0]["Type_Name"].string

            self.iDArray.append(iDString)

            completion(desc!, Name)
        } 
    }
    task.resume()
}
Comments