Reputation: 617
I have a class ApiManager() that make request to JSON data in which I learned from this tutorial, which used protocol delegate approach to pass the data to ViewController class
The data is acquired fine but I am not sure how to use it around?! in this case I am trying to use it inside TableView
class ViewController: UITableViewController, ApiManagerDelegate{
var names:[String] = [] // the variable which will hold the JSON data
override func viewDidLoad() {
super.viewDidLoad()
//instantiate the ApiManager Class
//Set the ViewController as its delegate
//perform request to Restaurants info
let manager = ApiManager()
manager.delegate = self
manager.getRestaurantsData()
func didReceiveResponse (info: [String : AnyObject]){
//Read name property from data dictionary (JSON)
if let restaurantsData = info["restaurants"] as? [[String: AnyObject]]{
for restaurant in restaurantsData{
let name = restaurant["name"] as? String
self.names.append(name!)
}
}
print("Data1: \(names)") // prints the data perfectly
}
func didFailToReceiveResponse() {
print("There was an error in recieving API data")
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print (names) //no data here
return names.count //not working
}
I am a bit confused how to work around this, I tried to make return value to didReieveResponse(), but the issue is when I call the function it needs the argument (which is passed to it in the Delegator class "dictionary").. I am completely confused.
Here is the delegator class and protocol for reference:
import UIKit
//Custom Protocol Declaration
@objc protocol ApiManagerDelegate {
optional func didReceiveResponse(info: [ String : AnyObject ])
optional func didFailToReceiveResponse()
}
class ApiManager: NSObject, NSURLSessionDelegate {
//open restaurant web API
private let requestURL = NSURL(string:"http://some-url-here.com")
var delegate: ApiManagerDelegate?
override init() {
super.init()
}
func getRestaurantsData() {
let defaultConfigObject = NSURLSessionConfiguration.defaultSessionConfiguration()
let defaultSession = NSURLSession (configuration: defaultConfigObject, delegate: self, delegateQueue: NSOperationQueue.mainQueue ())
let request = NSMutableURLRequest(URL: requestURL!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringCacheData, timeoutInterval: 60 )
request.HTTPMethod = "POST"
request.setValue( "application/x-www-form-urlencoded" , forHTTPHeaderField: "Content-Type" )
let dataTask = defaultSession.dataTaskWithRequest(request, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) in
if let responseError = error {
self.delegate?.didFailToReceiveResponse?()
print("Reponse Error: \( responseError )" )
} else {
do {
let dictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! [String: AnyObject]
self.delegate?.didReceiveResponse?(dictionary)
//print( "Response: \( dictionary )" )
print("Response: Success")
} catch let jsonError as NSError {
// Handle parsing error
self.delegate?.didFailToReceiveResponse?()
print( "JSONError: \(jsonError.localizedDescription)")
}
}
})
dataTask.resume()
}
}
thanks,
For future Developers who might suffer like me, the solution is to use TableViewName.reloadData() as mentioned below.. But please notice, it did only worked with me when I placed DidRecieveResponse() function outside ViewDidLoad, not sure why Hopefully one of the experts can explain it later.
Enjoy!
Upvotes: 0
Views: 322
Reputation: 82759
do like
class ViewController: UITableViewController, ApiManagerDelegate{
var names:[String] = []
let manager = ApiManager()
override func viewDidLoad() {
super.viewDidLoad()
manager.delegate = self
manager.getRestaurantsData()
}
func didReceiveResponse (info: [String : AnyObject]){
//Read name property from data dictionary (JSON)
if let restaurantsData = info["restaurants"] as? [[String: AnyObject]]{
for restaurant in restaurantsData{
let name = restaurant["name"] as? String
self.names.append(name!)
}
print("Data1: \(names)") // prints the data perfectly
if (self.names.count>0)
{
yourtableview.reloadData()
}
}
}
func didFailToReceiveResponse() {
print("There was an error in recieving API data")
}
Upvotes: 2