0

Here i assigned the value of the number of elements in eventDetails to the variable x inside the Alamofire completion handler. But, i'm not able to use it elsewhere in the code. I tried using the value of x for numberofrowsinsection but it returned 0 though it had a value.

Alamofire.request(some_url, method: .post, parameters: data, encoding: URLEncoding.default, headers: nil).responseJSON {
    response in

    let json = JSON(response.result.value)

    for eves in json.arrayValue {
        self.eventDetails.append(eves["EventName"].stringValue)
        self.regids.append(eves["EventRegID"].stringValue)
    }
    self.x = self.eventDetails.count
}
Rob
  • 392,368
  • 70
  • 743
  • 952
Rohit Dulam
  • 105
  • 6
  • This is duplicate (with prior version of Alamofire): http://stackoverflow.com/a/31498553/1271826 – Rob Jan 29 '17 at 18:00

2 Answers2

0

Remember this completion handler closure runs asynchronously (i.e. later than the code that appears immediately after the closure). You're probably checking x before it had a chance to be set. Add a self.tableView.reloadData() inside your completion handler closure to have your app reload the table when the request is done.

Alamofire.request(some_url, method: .post, parameters: data).responseJSON { response in
    let json = JSON(response.result.value)

    for eves in json.arrayValue {
        self.eventDetails.append(eves["EventName"].stringValue)
        self.regids.append(eves["EventRegID"].stringValue)
    }
    self.x = self.eventDetails.count
    self.tableView.reloadData()
}
Rob
  • 392,368
  • 70
  • 743
  • 952
  • The above code is present in viewdidload(), so where do i put self.tableview.reloadData() ? I'm new to iOS app dev so please do bear with me. – Rohit Dulam Jan 29 '17 at 17:46
  • Put it _inside_ the completion handler closure of `responseJSON`. I've added code snippet above. – Rob Jan 29 '17 at 18:02
  • Thanks Rob, you saved my day. – Rohit Dulam Jan 30 '17 at 04:26
  • No problem. If I answered your question, consider accepting my answer. See [What should I do when someone answers my question?](http://stackoverflow.com/help/someone-answers) – Rob Jan 30 '17 at 04:30
0

By the way, completely unrelated to your question at hand, you might want to use a custom type to capture these details:

struct Event {
    let name: String
    let regId: String
}

Then rather than separate eventDetails and regids arrays, have a single array of events:

var events = [Event]()

This more accurately captures the actual model (you're dealing with an array of events, not completely unrelated arrays of names and identifiers). It also enables certain features. For example, let's assume that your events were returned in chronological order and you wanted to sort them alphabetically, if you encapsulate all of the details associated with a single event into a custom type, when you sort, the whole object will be sorted and you don't have to worry about how to keep those disparate arrays synchronized.

Regardless, when using a custom type, the responseJSON might look like:

Alamofire.request(some_url, method: .post, parameters: data).responseJSON { response in
    let json = JSON(response.result.value)

    for eves in json.arrayValue {
        let event = Event(name: eves["EventName"].stringValue, regId: eves["EventRegID"].stringValue)
        self.events.append(event)
    }

    self.tableView.reloadData()
}

I'd also, excise the use of x, because that's just another variable that could get out of sync with this array. Just have numberOfRowsForSection return events.count directly.


Now, I've typed the above in without running it through the compiler, so I apologize if I introduced any typos. But I don't want you to focus on the details of my code snippets, but rather the basic idea that one generally wants to have arrays of custom objects, not completely separate arrays for the individual properties of the objects.

Rob
  • 392,368
  • 70
  • 743
  • 952