2016-09-30 63 views
0

我试图更新我的ViewController.swift文件中的temperatureLabel。每当我从我的天气类文件值分配给它,它解决了错误:UILabel意外地发现零,而从类外部更新时展开可选值

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

不过,如果我给它分配在ViewController.swift文件viewDidLoad中的值,标签更新的罚款。请帮忙!

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 
} 

这里是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{ 
      _ = "" 
     } 
    } 
} 

} 

回答

0

添加到您的viewDidLoad

self.temperatureLabel.text=Weather.getWeatherFromAPI() 

,并在您的天气类中删除:

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

的另一件事你应该做的是做功能etWeatherFromAPI()返回一个字符串

+0

谢谢repsonse!我以前尝试过,它只是挂在启动屏幕上。林不知道是否因为它创建一个ViewController的新实例,在我的VC创建一个天气的实例,似乎只是不断循环通过相同的结果? –

+0

你可以在你的viewDidLoad中添加self.temperatureLabel.delegate = self – Do2

+0

'UILabel'类型的值没有成员'delegate' –

0

尝试

var mainVC: ViewController = ViewController() 
+0

感谢repsonse!我以前尝试过,它只是挂在启动屏幕上。林不知道是否因为它创建一个ViewController的新实例,在我的VC创建一个天气的实例,似乎只是不断循环通过相同的结果? –

+0

您是否已将ViewController的实例传递给Weather实例? –

+0

尽管此代码片段可能会解决问题,但[包括解释](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)确实有助于提高帖子的质量。请记住,您将来会为读者回答问题,而这些人可能不知道您的代码建议的原因。 –

0

您应该的ViewController当前实例分配mainVC

class ViewController... { 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     ... 
     self.currentLocation.mainVC = self 
    } 
} 
相关问题