Engineeroholic
Engineeroholic

Reputation: 617

swift 2 how to use variable outside the function?

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!

Upvotes: 0

Views: 322

Answers (1)

Anbu.Karthik
Anbu.Karthik

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

Related Questions