0

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,


Update:

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!

8
  • 1
    You defined the methods in your ViewDidLoad method? Commented Mar 8, 2016 at 9:34
  • you can use closures for callback Commented Mar 8, 2016 at 9:38
  • 1
    Could it be because the names doesn,t exists when the tableview is drawn? Maybe it helps to reload data in tableview after viewdidload, or get the names in viewWillAppear? Commented Mar 8, 2016 at 9:39
  • 1
    tableview.reloaddata() ;-) Commented Mar 8, 2016 at 9:43
  • 1
    tableview.reloadData() i think you should use follow this tutorial for API calls and JSON handling github.com/tristanhimmelman/AlamofireObjectMapper Commented Mar 8, 2016 at 9:43

1 Answer 1

2

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")
}
Sign up to request clarification or add additional context in comments.

19 Comments

if I got it right, you want me to put manager = ApiManager() outside viewdidload. I just tried and tested but no output
this is initilization of ApiManager class, where you need add does not a problm
ok, I made tableView.reloadData().. not working am not sure If I did it right! yourtableview = tableview identifier?
your tableview == yourtableviewName ,
so this is the name = mainList @IBOutlet var mainList: UITableView! still not working
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.