Bill Headrick
Bill Headrick

Reputation: 179

iOS Swift passing data in Seque following NSSUrlSession Completion Handler

I know that there have been many variations of this question ("passing data between views in swift?") asked but I have not been able to find one that is specific to my situation. This worries me because I am afraid that I am not using proper design patterns. I would love suggestions for design patterns as well as tips on how to solve my specific problem.

Problem Background:

I am creating an app that relies on the users location data. The user pushes a button and when they do I take their latitude and longitude and pass it to a singleton instance that runs a NSURLSession to my web hosted API. The API returns a JSON response that my NSURLSession completion handler translates into a NSDictionary object which it then returns to completion handler of my button as well as a status code. If the status code signals that the data received from my web API was good then I want to pass that data to a new view controller via a segue so the new view controller can format and output the info to the user. However, if the status shows that there was an error or w/e I want to output an appropriate message to the user, and keep them on the same map page so they can select a valid location (I haven't implemented this but assume it shouldn't be too difficult).

My problem:

I know when I want to call a segue and I know what NSDictionary object that I want to pass to that segue. I just don't know how to send it.

Here is my code for the button and its completion handler:

// MARK: ACTIONS
@IBAction func scheduleAppointmentButton(sender: UIButton) {
   //grab async manager singleton
    let theAsyncManager = AsyncManager.sharedAsyncManager
    //Send HTTP Request to API to Get all available Appointments
    if let lon = selectedPin?.coordinate.longitude, lat = selectedPin?.coordinate.latitude{
        theAsyncManager.httpGetAppointments(lat, lon: lon)
            {
                (appointments, status) -> () in
                if(status == "All Good"){
                    //Want to trigger segue here and send it appointments object
                }
            }
    } else{
        //there was an error here getting the lat and lon
    }
}

Thanks in advance for any help. Let me know if you need any other information from me.

Upvotes: 0

Views: 127

Answers (2)

ConfusedByCode
ConfusedByCode

Reputation: 1730

I'll assume appointments is the dictionary returned by your API. You should create a property for your view controller where you store the appointments in your completion handler. Then you should call performSegueWithIdentifier:sender. Finally, in prepareForSegue:sender, assign the dictionary to a property of the segue's destinationViewController. Something like:

class YourViewController: UIViewController {

    var appointments: NSDictionary?

    @IBAction func scheduleAppointmentButton(sender: UIButton) {
        //grab async manager singleton
        let theAsyncManager = AsyncManager.sharedAsyncManager
        //Send HTTP Request to API to Get all available Appointments
        if let lon = selectedPin?.coordinate.longitude, lat = selectedPin?.coordinate.latitude{
            theAsyncManager.httpGetAppointments(lat, lon: lon) {
                (appointments, status) -> () in
                if(status == "All Good"){
                    //Want to trigger segue here and send it appointments object
                    self.appointments = appointments

                    // Remember to perform the segue on the main thread
                    dispatch_async(dispatch_get_main_queue(), {
                        self.performSegueWithIdentifier("NameOfYourSegue", sender: nil)
                    })
                }
            }
        } else{
            //there was an error here getting the lat and lon
        }
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        let destination = segue.destinationViewController as! YourDestinationClassName
        destination.appointments = appointments
    }
}

Upvotes: 1

pbush25
pbush25

Reputation: 5248

It's not exactly the way that the sender argument should be used here... But, all you have to do is call self.performSegueWithIdentifier("identifier", sender: appointments) right where the comment is your code to segue is. Then in your prepareForSegue the sender argument will have your appointments and you can pass that along to the next view controller.

Upvotes: 1

Related Questions