2016-09-30 2 views
0

Ich versuche, temperatureLabel in meiner ViewController.swift-Datei zu aktualisieren. Jedes Mal, wenn ich einen Wert, um es von meiner Wetter Klassendatei zuweisen, den Fehler behebt:UILabel hat beim Entpacken versehentlich einen Nullwert gefunden. Beim Aktualisieren von außerhalb der Klasse

"fatal error: unexpectedly found nil while unwrapping an Optional value".

Allerdings, wenn ich es einen Wert in viewDidLoad der ViewController.swift Datei zuweisen, aktualisiert das Etikett gut. Bitte helfen Sie!

class Weather{ 
var city = "" 
var lat = "" 
var long = "" 
var currentTemp = 0 
var currentCondition: String? 

var dayOneName: String? 
var dayTwoName: String? 
var dayThreeName: String? 

var dayOneCondition: String? 
var dayTwoCondition: String? 
var dayThreeCondition: String? 

var mainVC: ViewController! 


func getWeatherFromAPI(){ 
    let urlString = "https://api.forecast.io/forecast/<removed key>/(\self.lat),\(self.long)" 
    let url = URL(string: urlString) 
    URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in 
     if error != nil { 
      print(error) 
     } else { 
      do { 
       let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject] 

        let currentConditions = parsedData["currently"] as! [String:Any] 
        let temp = currentConditions["temperature"] as! Int! 
        self.currentTemp = temp! 
        print(self.currentTemp)//returns expected value 

        self.mainVC.temperatureLabel.text = "\(self.currentTemp)" //fatal error: unexpectedly found nil while unwrapping an Optional value 
      } catch let error as NSError { 
       print(error) 
      } 
     } 

    }).resume() 
}//end of getWeatherFromAPI 
} 

und hier ist die ViewController.swift

class ViewController: UIViewController, CLLocationManagerDelegate { 
@IBOutlet weak var conditionImage: UIImageView! 

@IBOutlet weak var mainConditionLabel: UILabel! 
@IBOutlet weak var mainCityLabel: UILabel! 

@IBOutlet weak var temperatureLabel: UILabel! 

@IBOutlet weak var dayOneLabel: UILabel! 
@IBOutlet weak var dayTwoLabel: UILabel! 
@IBOutlet weak var dayThreeLabel: UILabel! 
@IBOutlet weak var dayOneConditionImage: UIImageView! 
@IBOutlet weak var dayTwoConditionImage: UIImageView! 
@IBOutlet weak var dayThreeConditionImage: UIImageView! 

let locationManager = CLLocationManager() 
var currentLocation = Weather() 

override func viewDidLoad() { 
    super.viewDidLoad() 
    locationManager.delegate = self 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest 
    locationManager.requestWhenInUseAuthorization() 
    locationManager.startUpdatingLocation() 
    // Do any additional setup after loading the view, typically from a nib. 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
    CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)->Void in 

     if (error != nil){ 
      self.locationManager.stopUpdatingLocation() 
      print("Reverse geocoder failed with error" + (error?.localizedDescription)!) 
      return 
     } 

     if (placemarks?.count)! > 0{ 
      let pm = (placemarks?[0])! as CLPlacemark 
      self.locationInfo(placemark: pm) 
     } 
     else{ 
      print("Problem with the data received from geocoder") 
     } 
    }) 
} 
func locationInfo(placemark: CLPlacemark?){ 
    if let containsPlacemark = placemark{ 
     //stop updating location to save battery life 
     //locationManager.stopUpdatingLocation() 

     if containsPlacemark.locality != nil{ 
      let locality = containsPlacemark.locality 
      let location = self.locationManager.location 
      let lat = String(describing: location!.coordinate.latitude) 
      let long = String(describing: location! .coordinate.latitude) 

      self.currentLocation.city = locality! 
      self.currentLocation.lat = lat 
      self.currentLocation.long = long 

      self.currentLocation.getWeatherFromAPI() 
     } 
     else{ 
      _ = "" 
     } 
    } 
} 

} 

Antwort

0

diese

self.temperatureLabel.text=Weather.getWeatherFromAPI() 

zu Ihrem viewDidLoad hinzufügen und in Ihrem Wetter Klasse löschen:

self.mainVC.temperatureLabel.text = "\(self.currentTemp)" 

Die andere Sache Sie sollten tun, um func g zu machen etWeatherFromAPI() einen String

+0

Danke für die Antwort! Ich habe das schon mal probiert und es hängt einfach auf dem Startbildschirm. Ich bin nicht sicher, ob das, weil es eine neue Instanz von ViewController erstellt, die in meinem VC eine Instanz von Weather erstellt, die scheinen würde, immer nur die gleichen Ergebnisse durchlaufen? –

+0

können Sie self.temperatureLabel.delegate = self in Ihrer Ansicht hinzufügenDidLoad – Do2

+0

Wert des Typs 'UILabel' hat kein Mitglied 'Delegat' –

0

zurückzukehren

var mainVC: ViewController = ViewController() 
+0

Danke für die Antwort! Ich habe das schon mal probiert und es hängt einfach auf dem Startbildschirm. Ich bin nicht sicher, ob das, weil es eine neue Instanz von ViewController erstellt, die in meinem VC eine Instanz von Weather erstellt, die scheinen würde, immer nur die gleichen Ergebnisse durchlaufen? –

+0

Haben Sie die Instanz von ViewController an die Wetterinstanz übergeben? –

+0

Während dieses Code-Snippet die Frage lösen kann, [hilft eine Erläuterung] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) wirklich, um die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in der Zukunft beantworten, und diese Leute könnten die Gründe für Ihren Codevorschlag nicht kennen. –

0

Versuchen Sie sollten die mainVC mit der aktuellen Instanz von ViewController zuweisen.

class ViewController... { 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     ... 
     self.currentLocation.mainVC = self 
    } 
} 
Verwandte Themen