zumuha
zumuha

Reputation: 63

How to return value from Swift closure?

I'm new at swift closures. I have this code and i can't extract the values from the forloop into the arrays outside the closure.

Sorry about this question but i have already searched stackflow but without success in this specific case.

Thanks in advance.

var namesArray: [String] = []
var imagesArray: [String] = []
var timesArray: [String] = []
var placesArray: [String] = []

func getData(){
    //DATA SOURCE
    // Create request for user's Facebook data
    let request = FBSDKGraphRequest(graphPath: cmp.pageId, parameters: ["fields": "events"])

    // Send request to Facebook
    request.startWithCompletionHandler {

        (connection, result, error) in

        if error != nil {
            // Some error checking here
            print(error.debugDescription)
        } else
            if let pageData = result["events"] {
                print(result["events"]!!["data"]!![0]["name"])
                if let eventDetails = pageData!["data"] {

                    // EVENT DETAILS FETCH
                    for var i = 0; i < eventDetails!.count; i++
                    {
                        let fetchedEventName = eventDetails![i]["name"] as? String!
                        let fetchedEventTime = eventDetails![i]["start_time"] as? String!

                        if eventDetails?[i]["place"]??["name"] != nil {
                            if let fetchedEventPlace = eventDetails?[i]["place"]??["name"] {
                                self.placesArray.append(fetchedEventPlace! as! String)
                            }
                        } else {
                            self.placesArray.append("Lisbon")
                        }
                        self.namesArray.append(fetchedEventName!)
                        self.timesArray.append(fetchedEventTime!)
                    }
                    print("Name of event: \(self.namesArray)")
                }
            } else {
                print("Error.")
        }
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self

    getData()
}

EDIT: I want to show the fetched result into a tableview that's already set. Heres the tableview code.

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCellWithIdentifier("previewCell") as? PreviewCell {

        var img: UIImage!

        let url = NSURL(string: imagesArray[indexPath.row])!
        if let data = NSData(contentsOfURL: url){
            img = UIImage(data: data)
        } else {
            img = UIImage(named: "ant")
        }

        cell.configureCell(img, title: namesArray[indexPath.row], time: timesArray[indexPath.row], place: placesArray[indexPath.row])

        return cell
    } else {
        return PreviewCell()
    }
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return namesArray.count
}

func addNewEvent(name: String, image: String, time: String, place: String)
{
    namesArray.append(name)
    imagesArray.append(image)
    timesArray.append(time)
    placesArray.append(place)
}

Upvotes: 1

Views: 1098

Answers (2)

Digitech
Digitech

Reputation: 292

In case if you need to return data from closure you can define completion on your getData() method like this

func getData(completion:([DataType]) -> Void) {
    //process data
    let dataArray:DataType = []
    completion(dataArray)
}

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self

    getData { (completionData) -> Void in
        // process returned data 
    }
}

Hope this helps

Upvotes: 0

Moriya
Moriya

Reputation: 7906

You are already getting the number in to the arrays so what you need to do is just reload the tableview after the for loop.

//end of for-loop
self.tableView.reloadData()

The reason for this is the asynchronous execution of the request.startWithCompletionHandler. The code inside that block will most likely execute after your tableView already loaded and it therefor needs a reload after the data has been fetched

Upvotes: 1

Related Questions