2017-05-06 3 views
0

Ich versuche, ein Struct zu verwenden, um einige Variablen zu übergeben, die ich von einer Facebook Graph Anfrage wie E-Mail, Name, Geschlecht, etc. Ich habe das Struct ('fbDemographics ') und die Variablen in' ViewController ', aber ich erhalte einen Fehler, wenn ich versuche, die Struktur und eine der Variablen in' SecondViewController 'aufzurufen (Typ' ViewController 'hat kein Mitglied' fbDemographics '). Ich habe Struct zuvor noch nie verwendet, also habe ich ein wenig verwirrt, warum ich diesen Fehler bekomme. Danke für irgendwelche Gedanken. Der Code für beide View-Controller ist unten:Verwenden von Struct um eine Variable zu übergeben Swift

class ViewController: UIViewController, FBSDKLoginButtonDelegate { 

override func viewDidLoad() { 
    super.viewDidLoad() 

    struct fbDemographics { 

     static var relationship_status: String? 
     static var gender: String? 
     static var user_education_history: String? 
     static var user_location: String? 
     static var email: String? 
     static var name: String? 

    }  

    FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, relationship_status, gender, user_location, user_education_history, email"]).start(completionHandler: { (connection, result, error) -> Void in 
     if (error == nil){ 
      //let fbDetails = result as! NSDictionary 
      //print(fbDetails) 

      if let userDataDict = result as? NSDictionary { 
       fbDemographics.gender = userDataDict["gender"] as? String 
       fbDemographics.email = userDataDict["email"] as? String 
       fbDemographics.name = userDataDict["name"] as? String 
       fbDemographics.user_location = userDataDict["user_location"] as? String 
       fbDemographics.user_education_history = userDataDict["user_education_history"] as? String 
       fbDemographics.relationship_status = userDataDict["relationship_status"] as? String 


       let myEducation = fbDemographics.user_education_history 
       let myEmail = fbDemographics.email 
       let myGender = fbDemographics.gender 
       let myName = fbDemographics.name 
       let myStatus = fbDemographics.relationship_status 
       let myLocation = fbDemographics.user_location     

       self.performSegue(withIdentifier: "LoginToHome", sender: (Any).self) 


      } 


     } 

SECOND-View-Controller

class SecondViewController: UIViewController { 

@IBAction func verticalSliderChanged(_ sender: UISlider) { 

     let currentValue = String(sender.value); 

     sliderLabel.text = "\(currentValue)" 

    func viewDidLoad() { 
     super.viewDidLoad() 

     ***ViewController.fbDemographics.myEmail*** 

    } 
} 
+0

eine Menge Dinge falsch mit der aktuellen Lösung Es gibt keine. Ich würde nach einigen Tutorials zum Übergeben von Daten zwischen View-Controllern suchen. – nathan

+0

Ich habe viele Tutorials durchgelesen. Ich bekomme einfach keine Variablen, aber ich vermute, dass sie sich immer wieder verstopfen. Danke für einen Blick. –

+1

Ihre Frage enthält viel unnötigen Code. Bitte lösche und behalte nur das Wichtige. – Macabeus

Antwort

1

Das Problem ist, dass Sie Ihre structinnerhalbviewDidLoad definiert haben. Daher ist der Umfang auf diese Methode beschränkt. Verschieben Sie es aus viewDidLoad, aber immer noch in ViewController, und Sie sollten in der Lage sein, es von der SecondViewController zugreifen. Offensichtlich müssen Sie diesen Verweis auch auf myEmail fixieren, da er email heißt. Außerdem sollten Sie in Ihrer SecondViewControllerviewDidLoad Implementierung aus der verticalSliderChanged Methode ziehen; Die viewDidLoad sollte eine Instanzmethode der obersten Ebene von SecondViewController sein, die nicht in einer anderen Methode definiert ist.

Hier gibt es jedoch tiefere Probleme. Anstatt struct mit static Variablen zu verwenden, sollten Sie diese einfachen Instanzvariablen erstellen, eine Instanz Ihres FbDemographics Typs erstellen (beachten Sie, dass struct Typen mit Großbuchstaben beginnen) und diese Instanz dann in prepare(for:sender:) übergeben.


Zum Beispiel der richtige Weg, Daten zu übergeben wäre:

  • static Variablen eliminieren;
  • geben Sie Ihrem struct einen Namen, der mit Großbuchstaben beginnt;
  • Instanz Ihrer struct erstellen; und
  • übergeben Sie diese Instanz an die Zielansicht Controller in prepare(for:sender:).

z.

struct FbDemographics { 
    var relationshipStatus: String? 
    var gender: String? 
    var userEducationHistory: String? 
    var userLocation: String? 
    var email: String? 
    var name: String? 
} 

class ViewController: UIViewController { 

    var demographics: FbDemographics? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     performRequest() // I actually don't think you should be initiating this in `viewDidLoad` ... perhaps in `viewDidAppear` 
    } 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     if let destination = segue.destination as? SecondViewController { 
      destination.demographics = demographics 
     } 
    } 

    func performRequest() { 
     FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, relationship_status, gender, user_location, user_education_history, email"]).start { connection, result, error in 
      guard let userDataDict = result as? NSDictionary, error == nil else { 
       print("\(error)") 
       return 
      } 

      self.demographics = FbDemographics(
       relationshipStatus: userDataDict["relationship_status"] as? String, 
       gender: userDataDict["gender"] as? String, 
       userEducationHistory: userDataDict["user_education_history"] as? String, 
       userLocation: userDataDict["user_location"] as? String, 
       email: userDataDict["email"] as? String, 
       name: userDataDict["name"] as? String 
      ) 

      self.performSegue(withIdentifier: "LoginToHome", sender: self) 
     } 
    } 

} 

Und dann SecondViewController konnte:

class SecondViewController: UIViewController { 

    var demographics: FbDemographics! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let value = demographics.email // this should work fine here 
    } 

} 
+0

Vielen Dank, dass Sie sich die Zeit genommen haben, eine so vollständige Antwort zu geben. Ich ging das durch und folgte dem, was du gesagt hast. Ich habe keine Fehler, was ein guter erster Start ist. Eine Frage allerdings; Ich war mir nicht sicher, was du meintest, als du sagtest, dass du die Instanz passierst (prepareforsegue). Danke noch einmal. –

+0

Aus vielen Gründen ist es nicht ratsam, statische Eigenschaften zu deklarieren (in denen jede Instanz von 'FbDemographics' denselben Wert hat). Sie möchten stattdessen eine "Instanz" mit der Syntax "let foo = FbDemographics (...)" erstellen.Dann stellt sich die Frage, wie 'SecondViewController' eine Kopie dieser Instanz bekommt. So haben Sie die 'prepare (for: sender:)' bestätigen Sie, dass das Ziel ein 'SecondViewController' ist, und wenn ja, weisen Sie die entsprechende 'demographics'-Eigenschaft als Kopie der ursprünglichen' FbDemographics'-Instanz, die wir oben erstellt haben. – Rob

Verwandte Themen