2016-12-27 2 views
0

Ich lerne derzeit iOS-Entwicklung mit Swift. Ich mache eine einfache Wetter-App. Ich habe mehrere Knöpfe um das Wetter für die nächsten 4 Stunden zu bekommen. Ich bekomme das Wetter von der Dark Sky API, die im JSON-Format zurückgegeben wurde. Ich habe schließlich herausgefunden, wie man die korrekten Daten vom JSON abruft, und habe eine Klasse geschaffen, die die Daten holt.Wie kann ich Daten abrufen, die in einer separaten Klasse gespeichert sind, wenn ich von ViewController aus anrufe?

typealias WeatherCallback = (Weather) -> Void 
typealias ErrorCallback = (Error) -> Void 

class NetworkManager { 

    class func getWeather(latitude: String, longitude: String, onSuccess: WeatherCallback? = nil, onError: ErrorCallback? = nil) { 

     let urlString = "https://api.darksky.net/forecast/(api key)/" + latitude + "," + longitude + "?units=si" 

     let url = URL(string: urlString) 

     URLSession.shared.dataTask(with: url!) { (data, response, error) in 
      if error != nil { 
       print(error!) 
       onError?(error!) 
      } else { 
       do { 
        let json = JSON(data: data!) 
        let weather = Weather() 

        DispatchQueue.main.async { 
         weather.updateWithJSON(dict: json["currently"], hour: 0) 

         for i in 1...4 { 
          weather.updateWithJSON(dict: json["hourly"]["data"][i], hour: i) 
         } 
        } 
        onSuccess?(weather) 
       } 
      } 
      }.resume() 
    } 
} 

Und ich habe eine andere Klasse, um die abgerufenen Daten zu speichern.

class Weather { 

    public var currentTime: String = "" 
    public var currentTemperature: String = "" 

    public var nextHourTime: String = "" 
    public var nextHourTemperature: String = "" 

    public var nextTwoHourTime: String = "" 
    public var nextTwoHourTemperature: String = "" 

    public var nextThreeHourTime: String = "" 
    public var nextThreeHourTemperature: String = "" 

    public var nextFourHourTime: String = "" 
    public var nextFourHourTemperature: String = "" 

    func updateCurrentData(time: String, temp: String) { 
     currentTime = time 
     currentTemperature = temp 
    } 

    func updateWithJSON(dict: JSON, hour: Int){ 

     switch hour { 
     case 0: 
      currentTime = dict["time"].stringValue 
      currentTemperature = dict["temperature"].stringValue 

     case 1: 
      nextHourTime = dict["time"].stringValue 
      nextHourTemperature = dict["temperature"].stringValue 

     case 2: 
      nextTwoHourTime = dict["time"].stringValue 
      nextTwoHourTemperature = dict["temperature"].stringValue 

     case 3: 
      nextThreeHourTime = dict["time"].stringValue 
      nextThreeHourTemperature = dict["temperature"].stringValue 

     case 4: 
      nextFourHourTime = dict["time"].stringValue 
      nextFourHourTemperature = dict["temperature"].stringValue 

     default: 
      print("rip") 
     } 
    } 
} 

Mein Problem ist, ich kann nicht die gespeicherten Werte in der Klasse zugreifen Weather aus ViewController.

Zum Beispiel

let weather = Weather() 

print(weather.currentTime)

Jede Hilfe mich in der richtigen Richtung genial wäre in zeigen! Vielen Dank!

+0

Zuerst sollten Sie mit 'Weather' mit' updateWithJSON' oder 'updateCurrentData' Methode initialisieren, dann können Sie nur durch die Instanz der Wetterklasse gespeicherte Werte erhalten. – Poles

Antwort

1

Sie können es tun, indem Sie Weather Klasse Singleton erstellen. Verwenden von Singleton Nur eine Kopie dieses Objekts existiert und der Status wird von jedem anderen Objekt freigegeben und erreichbar.

class Weather { 
public static var sharedInstance = Weather() 
... 
private init() { 
} 
} 

und erhalten Objekt von Singletons wie dieses

let weather = Weather.sharedInstance // it will give you the same instance of Weather every time you call it. 
+0

Muss ich dann meine Variablen innerhalb 'init' zuweisen? Wie würde ich das machen, wenn die Variablen innerhalb einer Funktion zugewiesen sind? – samuria

+0

nein. Wir deklarieren init mit privat, um zu verhindern, dass andere Objekte des Wetters erstellt werden. – Sahil

0

Sie können Anfrage GetWeather in Ihrem Viewcontroller erstellen. Mit dieser Funktion haben Sie Zugriff auf das Weather-Objekt als Complete-Handler (WeatherCallback = (Weather) -> Void).

0

Hier können Sie ein Singleton-Entwurfsmuster verwenden. Machen Sie eine Singleton Weather Klasse und wann immer Sie eine Antwort von getWeather Funktion erhalten, aktualisieren Sie Ihre Weather Singleton-Klasse. Wenn Sie eine Benutzerantwort wünschen, erhalten Sie einfach Werte von Weather Klasse.

1

Sie können Delegate Pettern verwenden, um das Ergebnis in ViewController zu erhalten. Erstellen Sie zuerst ein Protokoll wie folgt aus:

protocol YourDelegateProtocol { 
    func getDataFromServer(data: String) 
} 

Danach eine Instanz dieses Protokoll in Ihrer Networkmanager-Klasse wie das erstellen:

class NetworkManager { 
    var delegate: YourDelegateProtocol?  
} 

Nach Erhalt der Antwort die Antwort auf Ihre Viewcontroller von dort aus senden:

URLSession.shared.dataTask(with: url!) { (data, response, error) in 
     if error != nil { 
      print(error!) 
      onError?(error!) 
     } else { 
      do { 
       let json = JSON(data: data!) 
        delegate.geDataFromServer(json as String) 
       } 
       onSuccess?(weather) 
      } 
     } 
     }.resume() 

Danach die Daten in Ihrem Viewcontroller erhalten wie die

class WeatherData: UIViewController, YourDelegateProtocol { 

    var yourModelClass = YourModelClass() //init model class globally. 

    func getDataFromServer(data: String) { 
    // populate json String into your model class. Then you are ready to go. 
    } 
} 
Verwandte Themen