Reputation: 95
I'm fetching JSON data online and converting them to NSArray, and to String and class Arrays to manage the data. However, for some reason, the code exits the GetData()
method after the line let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
I've also verified that there was no issues with fetching the data, but it just can't be displayed on the table.
I've attached my project file also for download.
Codes from ViewController.swift
import UIKit
class ViewController: UIViewController, UITableViewDataSource {
var nameList = [NameManager]()
@IBOutlet weak var NameTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
GetData()
// Do any additional setup after loading the view, typically from a nib.
NameTable.dataSource = self
NameTable.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func GetData(){
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: NSURL(string: "http://www.json-generator.com/api/json/get/bPfifKWNaq?indent=2")!)
request.HTTPMethod = "GET"
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let error = error {
print(error)
}
if let data = data{
do{
let resultJSON = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
let resultArray = resultJSON as? NSArray
for jsonObjectString in resultArray!{
let code = jsonObjectString["code"] as! String
let name = jsonObjectString["name"] as! String
let description = jsonObjectString["description"] as! String
self.nameList.append(NameManager(code: code, name: name, description: description))
}
self.nameList.count
}catch _{
print("Received not-well-formatted JSON")
}
}
if let response = response {
let httpResponse = response as! NSHTTPURLResponse
print("response code = \(httpResponse.statusCode)")
}
})
task.resume()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
let count = nameList.count
return count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let myCell = NameTable.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as UITableViewCell
myCell.textLabel?.text = nameList[indexPath.row].name
myCell.detailTextLabel?.text = nameList[indexPath.row].description
return myCell
}
}
Codes from NameManager.swift
import Foundation
class NameManager{
var code:String
var name:String
var description:String
init(code: String, name: String, description: String){
self.code = code
self.name = name
self.description = description
}
}
Upvotes: 0
Views: 116
Reputation: 1066
session.dataTaskWithRequest is asynchronous and is automatically executed in background thread.
The dataTaskWithRequest is started when it sees the task.resume()
and starts executing in background.
So, your program does not wait for its completion and starts to execute the instructions following it. In your example, your code will start to execute
NameTable.dataSource = self
NameTable.reloadData()
which are following GetData() method. Once the background execution is completed, the code you have in the completion handler is executed. So your tableView is not refreshed.
There are different ways you can approach this issue.
one way is to include NameTable.reloadData()
in your completion handler. Another way is to segue from a ViewController when background execution is completed.
Hope it helps.
EDIT:
import UIKit
class ViewController: UIViewController, UITableViewDataSource {
var nameList = [NameManager]()
@IBOutlet weak var NameTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
NameTable.dataSource = self
GetData()
// Do any additional setup after loading the view, typically from a nib.
//NameTable.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func GetData(){
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: NSURL(string: "http://www.json-generator.com/api/json/get/bPfifKWNaq?indent=2")!)
request.HTTPMethod = "GET"
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let error = error {
print(error)
}
if let data = data{
do{
let resultJSON = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
let resultArray = resultJSON as? NSArray
for jsonObjectString in resultArray!{
let code = jsonObjectString["code"] as! String
let name = jsonObjectString["name"] as! String
let description = jsonObjectString["description"] as! String
self.nameList.append(NameManager(code: code, name: name, description: description))
}
self.nameList.count
dispatch_async(dispatch_get_main_queue(), {
self.NameTable.reloadData()
})
}catch _{
print("Received not-well-formatted JSON")
}
}
if let response = response {
let httpResponse = response as! NSHTTPURLResponse
print("response code = \(httpResponse.statusCode)")
}
})
task.resume()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
let count = nameList.count
return count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let myCell = NameTable.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as UITableViewCell
myCell.textLabel?.text = nameList[indexPath.row].name
myCell.detailTextLabel?.text = nameList[indexPath.row].description
return myCell
}
}
Upvotes: 3