Micgal Micgal - 2 months ago 17
Swift Question

Variable from another class

I have a problem when accessing the variable from another class.

I am initializing and modifying variable here

TheResponse Class

import Foundation
import Alamofire

class TheResponse {

typealias JSONStd = [[String : AnyObject]]
var jsonAnswer = [[String:String]]()

var getRes: [[String : String]] {
return jsonAnswer
}

func callAmo(){
let urladdress = "https://api.github.com/users"
Alamofire.request(urladdress).responseJSON(completionHandler: {
response in
//print(response)
self.parseData(JSONData: response.data!)
})
}

func parseData(JSONData : Data){

do {
var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONStd
let counter = readableJSON.count
//Filling the dictionary
for item in 0...counter - 1 {
let login = readableJSON[item]["login"]
let avatar_url = readableJSON[item]["avatar_url"]
let html_url = readableJSON[item]["html_url"]
let id = String(describing: readableJSON[item]["id"])

var dict:[String:AnyObject] = ["login": login!,
"avatar": avatar_url!,
"profile": html_url!,
"id": id as AnyObject]

jsonAnswer.append(dict as! [String : String])
}
}
catch{
print(error)
}
}
}


If I will print somewhere here the jsonAnswer variable, everything looks fine.
But I want to use this variable in my second class

import UIKit
import Alamofire

class TableViewController: UITableViewController {
var resObj = TheResponse()
var jsonData = [[String:String]]()


override func viewDidLoad() {
super.viewDidLoad()

resObj.callAmo{ (jsonAns) -> () in
self.jsonData = jsonAns
// print(self.jsonData)
}
print(self.jsonData)

}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MainViewCell

return cell
}

}


The problem is that when I want to print the variable in
TableViewController
class, the variable is empty. As print out I am getting only [].

How should I access the variable to have it as it should be?

Answer

The problem is you haven't call callAmo method also, you need to create completion closure with your method, so change your code like this.

func callAmo(completion: ([[String : String]]) -> ()) {
    let urladdress = "https://api.github.com/users"
    Alamofire.request(urladdress).responseJSON(completionHandler: {
        response in
        //print(response)
        let dic = self.parseData(JSONData: response.data!)
        completion(dic)
    })
}

Now return the dictionary from parseData methods like this.

func parseData(JSONData : Data) -> [[String: String]]{

    do {
        var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONStd
        let counter = readableJSON.count
         //Filling the dictionary
        for item in 0...counter - 1 {
            let login = readableJSON[item]["login"]
            let avatar_url = readableJSON[item]["avatar_url"]
            let html_url = readableJSON[item]["html_url"]
            let id = String(describing: readableJSON[item]["id"])

            var dict:[String:AnyObject] = ["login": login!,
                    "avatar": avatar_url!,
                    "profile": html_url!,
                    "id": id as AnyObject]

            jsonAnswer.append(dict as! [String : String])
        } 
    }
    catch{
        print(error)
    }
    return jsonAnswer
}

Now call this method in viewDidLoad of TableViewController like this.

resObj.callAmo{ (jsonAns) -> () in
    print(jsonAns)
}

Edit: To get the data in TableViewController do like this

var jsonData = [[Strin:String]]()

override func viewDidLoad() {
    super.viewDidLoad()

    resObj.callAmo{ (jsonAns) -> () in
        self.jsonData = jsonAns
        self.tableView.reloadData()
    }
}

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.jsonData.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MainViewCell
    return cell
}