2017-03-26 3 views
0

Das macht mich wahnsinnig. Dies sollte die einfachste Sache auf der Welt sein, und es funktioniert einfach nicht, egal was ich versuche.Warum kann ich nicht innerhalb einer Funktion auf eine ViewController-Variable zugreifen (Swift3)?

Was ich versuche zu tun ist sehr einfach. Es gibt ein Textfeld und eine Schaltfläche in meiner Sicht. Sie geben eine ID-Nummer in das Textfeld ein und klicken auf die Schaltfläche. Wenn Sie auf die Schaltfläche klicken, wird eine Webanforderung ausgeführt, die die ID-Nummer an ein PHP-Skript sendet, das sie verarbeitet, und eine Zeichenfolge zurückgibt. Ich möchte die zurückgegebene Zeichenfolge nur in einer Variablen speichern und sie über einen neuen View-Controller senden.

Hier ist mein Code so weit:

class ViewController: UIViewController { 
    //================ Member Variables ================// 
    var customerDetails: NSString = "" 

    //================ Object Outlets ================// 
    @IBOutlet weak var deviceID: UITextField! 

    //================ Object Actions ================// 
    @IBAction func checkDeviceID(_ sender: UIButton) { 
     print(deviceID.text!) 
     validateDevice(deviceID: deviceID.text!) 
    } 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     let step2VC: Step2ViewController = segue.destination as! Step2ViewController 
     step2VC.deviceID = deviceID.text! 
     step2VC.customerDetails = customerDetails 
    } 

    //================ Custom Methods ================// 
    func validateDevice(deviceID: String) { 
     //Send a request out to server to validate credentials 
     let sessionConfig = URLSessionConfiguration.default 
     let session = URLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil) 
     guard let URL = URL(string: "http://monitt.dynamiscms.com/library/getCustomerDetails.php") else {return} 
     let request = NSMutableURLRequest(url: URL) 

     request.httpMethod = "POST" 

     request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type") 

     let bodyObject: [String: String] = [ 
      "deviceID": deviceID 
     ] 

     request.httpBody = try! JSONSerialization.data(withJSONObject: bodyObject, options: []) 
     var responseString: NSString = "" 

     let task = URLSession.shared.dataTask(with: request as URLRequest) { 
      data, response, error in 

      if (error == nil) { 
       // Success 
       let statusCode = (response as! HTTPURLResponse).statusCode 
       print("URL Session Task Succeeded: HTTP \(statusCode)") 

       responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)! 
       self.customerDetails = responseString 

       print("responseString = \(responseString)") 
      } 
      else { 
       // Failure 
       print("URL Session Task Failed: %@", error!.localizedDescription); 
      } 
     } 

     task.resume() 
     session.finishTasksAndInvalidate() 

     performSegue(withIdentifier: "setupStep2", sender: nil) 
    } 
} 

In meiner validateDevice Funktion, wo ich die print-Anweisung habe, ist es das zurückgegebene Ergebnis aus dem PHP-Skript erfolgreich anzeigt. Aber trotz der Tatsache, dass ich die Variable außerhalb der Funktionen vordefiniert habe, kann ich immer noch nicht die Variable customerDetails abrufen, die die zurückgegebenen Ergebnisse aus dem Skript enthält.

Kann jemand einen Einblick geben, was ich falsch mache?

Eine erfolgreiche Antwort ist eine, die es mir ermöglicht, den Inhalt von "customerDetails" in einem Textfeld im nächsten ViewController festzulegen, und enthalten Sie die Inhalte aus dem Webskript.

Antwort

0

Sie würden self verwenden und es sieht so aus als ob Sie sind.

Warten Sie, bis der Netzwerkanruf abgeschlossen ist, bevor Sie auf customerDetails zugreifen (oder ihn übergeben)?

Verschieben Sie den performSegue(forIdentifier:sender:) Aufruf an das Innere der Netzwerkaufrufe Schließung. Der Compiler wird Sie warnen, dass Sie self hinzufügen müssen.

func validateDevice(deviceID: String) { 

    //Send a request out to server to validate credentials 

    let sessionConfig = URLSessionConfiguration.default 
    let session = URLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil) 
    guard let URL = URL(string: "http://monitt.dynamiscms.com/library/getCustomerDetails.php") else {return} 
    let request = NSMutableURLRequest(url: URL) 

    request.httpMethod = "POST" 

    request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type") 

    let bodyObject: [String: String] = [ 
     "deviceID": deviceID 
    ] 

    request.httpBody = try! JSONSerialization.data(withJSONObject: bodyObject, options: []) 
    var responseString: NSString = "" 

    let task = URLSession.shared.dataTask(with: request as URLRequest) { 
     data, response, error in 

     if (error == nil) { 
      // Success 
      let statusCode = (response as! HTTPURLResponse).statusCode 
      print("URL Session Task Succeeded: HTTP \(statusCode)") 

      responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)! 
      self.customerDetails = responseString 

      print("responseString = \(responseString)") 
      self.performSegue(withIdentifier: "setupStep2", sender: nil) 
     } 
     else { 
      // Failure 
      print("URL Session Task Failed: %@", error!.localizedDescription); 
     } 
    } 

    task.resume() 
} 
2

Sie sollten die Netzanruf performSegue nach

beendet Neben
let task = URLSession.shared.dataTask(with: request as URLRequest) { 
     data, response, error in 

     if (error == nil) { 
      // Success 
      let statusCode = (response as! HTTPURLResponse).statusCode 
      print("URL Session Task Succeeded: HTTP \(statusCode)") 

      responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)! 
      self.customerDetails = responseString 
      //Here 
      self.performSegue(withIdentifier: "setupStep2", sender: nil) 
      print("responseString = \(responseString)") 
     } 
     else { 
      // Failure 
      print("URL Session Task Failed: %@", error!.localizedDescription); 
     } 
    } 

    task.resume() 

, gibt es keine Notwendigkeit

session.finishTasksAndInvalidate() 
zu nennen
Verwandte Themen