0

I tried a lot of methods from stackoverflow and from googling but I got no luck of reaching what I need.

simply I want to store the response from api request to some variable so that I can use it freely.

here is the code

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var responseLabel: UILabel!
let apiUrlStr = "http://jsonplaceholder.typicode.com/posts"

var resData = NSArray()

override func viewDidLoad() {
    super.viewDidLoad()
    request(.GET, apiUrlStr, encoding: .JSON).responseJSON { (_, _, JSON, _) in
        let arr = JSON as NSArray
        let user = arr[0] as NSDictionary
        self.responseLabel.text = user.objectForKey("title") as? String

        self.resData = JSON as NSArray //i cant get this from outside
    }

    println(resData) //prints nothing but empty parentheses while inside the request it prints the data right
    }
}

because I have multiple classes and every class need to handle the response in a different way I want to create an api class with a response method that will return the response.

something like this maybe:

class api{
    func req(url: String, params: NSDictionary){
        //method goes here
    }

    func res() -> NSDictionary{
        //method goes here
        var response = NSDictionary()
        return response
    }
}

then use it like this in viewdidload

let params = ["aaa","bbb"]
let api = api()
api.req(apiUrlStr, params)
let res = api.res()

***by the way the request method I'm using right now is from Alamofire.swift and I dont mind using another method

here is some of the posts and sites I tried to follow without a luck

proper-way-to-pull-json-api-resoponse

link2

all lead to the same result response only from inside the method.

Community
  • 1
  • 1
iEmad
  • 625
  • 1
  • 7
  • 20

1 Answers1

1

The problem is that the call to the network (looks like you're using alamofire) is asynchronous. So the network request is started and before it completes, your

println(resData)

line executes. At this point the response from the network hasn't returned so resData is still an empty array.

Try doing this instead:

Add a new function

func handleResponse(resData: NSArray) {
    self.resData = resData
    println(resData)
}

Then in the response code replace

self.resData = JSON as NSArray

with

let resData = JSON as NSArray
self.handleResponse(resData)

Assuming you need more than just a println statement to change when the data is loaded, you will also need to inform things like table views or other UI components to reload their data source in this method.

pauln
  • 88
  • 8
  • this solution still didnt fix my problem. I still cant access the response from another function because the(handleResponse) is called within the response code but the (self.resData) still empty when accessed from viewdidload. – iEmad Feb 01 '15 at 14:43
  • to be more specific how can I call println(resData) after the data has been returned ? – iEmad Feb 01 '15 at 14:51
  • 1
    You can call println(resData) after the data has been returned exactly the way I have described. You will not be able to do this in the viewDidLoad method unless you block all program execution while waiting for the server to respond. This would be a bad idea (server could take a long time to respond, for example over a slow network connection). I suggest you have a read of https://github.com/Alamofire/Alamofire#response-handling and read up on asynchronous programming in general. – pauln Feb 01 '15 at 19:22
  • so there is no way to do it in viewdidload except if I do it synchronously ! – iEmad Feb 02 '15 at 04:12