2016-04-24 7 views
0

Ich weiß, dass es viele Variationen dieser Frage ("Daten zwischen Ansichten in swift?") Gefragt, aber ich habe nicht in der Lage, einen zu finden, der spezifisch für meine ist Lage. Das beunruhigt mich, weil ich befürchte, dass ich nicht die richtigen Designmuster verwende. Ich würde gerne Vorschläge für Designmuster sowie Tipps zur Lösung meines spezifischen Problems erhalten.iOS Swift übergeben Daten in Seque folgenden NSSUrlSession Completion Handler

Problem Hintergrund:

ich eine App erschaffe, die auf den Benutzer Standortdaten beruht. Der Benutzer drückt eine Schaltfläche und wenn sie dies tun, nehme ich ihre Breite und Länge und übergebe sie an eine Singleton-Instanz, die eine NSURLSession für meine Web-gehostete API ausführt. Die API gibt eine JSON-Antwort zurück, die mein NSURLSession-Vervollständigungshandler in ein NSDictionary-Objekt übersetzt, das dann an den Beendigungshandler meiner Schaltfläche sowie an einen Statuscode zurückgegeben wird. Wenn der Statuscode anzeigt, dass die von meiner Web-API empfangenen Daten gut waren, dann möchte ich diese Daten über ein Segment an einen neuen Ansichtscontroller weitergeben, damit der neue Ansichtscontroller die Informationen formatieren und an den Benutzer ausgeben kann. Wenn der Status jedoch anzeigt, dass ein Fehler aufgetreten ist, oder ich eine entsprechende Nachricht an den Benutzer ausgeben möchte, und sie auf derselben Kartenseite belassen, damit sie einen gültigen Standort auswählen können (ich habe dies nicht implementiert, sondern angenommen es sollte nicht zu schwierig sein).

Mein Problem:

Ich weiß, wenn ich einen segue anrufen möchten, und ich weiß, was NSDictionary einwenden, dass ich zu diesem Übergang passieren wollen. Ich weiß einfach nicht, wie ich es schicken soll.

Hier ist mein Code für die Schaltfläche und seine Fertigstellung 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 
    } 
} 

Vielen Dank im Voraus für jede Hilfe. Lassen Sie es mich wissen, wenn Sie weitere Informationen von mir benötigen.

Antwort

1

Ich nehme an, appointments ist das Wörterbuch von Ihrer API zurückgegeben. Sie sollten eine Eigenschaft für Ihren View-Controller erstellen, in der Sie die appointments in Ihrem Abschluss-Handler speichern. Dann sollten Sie performSegueWithIdentifier:sender anrufen. Schließlich, in prepareForSegue:sender, weisen Sie das Wörterbuch einer Eigenschaft des Segments destinationViewController zu. Etwas wie:

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 
    } 
} 
1

Es ist nicht genau die Art und Weise, die das sender Argument sollte hier verwendet werden ... Aber alles, was Sie tun müssen, ist self.performSegueWithIdentifier("identifier", sender: appointments) genau dort, wo der Kommentar ist Ihr Code zu segue ist. Dann in Ihrem prepareForSegue das Absender-Argument wird Ihre Termine haben und Sie können dies mit dem nächsten View-Controller übergeben.

+0

hmmm ... Ich sah ein Tutorial, das diese Methode wurde darauf hindeutet, aber alle Kommentare waren ihm als schlechtes Design zu kritisieren, denn wenn man die gleiche segue Kennung in einem anderen Teil des Codes nennen sind Sie vorbei Gefahr ein schlechter Paramaeter. dh. Sie erwarten ein NSDictionary-Termine-Objekt in dem zweiten Ansichtscontroller, aber Sie übergeben ein Null. Kennst du eine bessere Methode? Und danke für den Hack! –

+1

Nun, der einzige andere Weg wäre, eine Klassenvariable zu haben und sie zu setzen, wenn der Completion-Handler aufgerufen wird, dann performSegue aufzurufen und dann in prepareForSegue können Sie die globale Variable als das verwenden, was Sie an das nächste VC übergeben – pbush25

Verwandte Themen