Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Build a Weather App with Swift (Retired) Displaying Our Weather Data Connecting the UI to Our Model

Issue at the final stage.

I have been able to pull data successfully up until this point, and my app builds without failure; however, once it comes time for the app to refresh with up-to-date data, my app crashes. The only error message I am given is (lldb). Any help would be greatly appreciated.

ViewController:

import UIKit

class ViewController: UIViewController {

    private let apiKey = "54e25f5e21f8faa088f12deffe0ada4f"


//    @IBOutlet weak var iconView: UIImageView!
//    @IBOutlet weak var currentTimeLabel: UILabel!
//    @IBOutlet weak var temperatureLabel: UILabel!
//    @IBOutlet weak var humidityLabel: UILabel!
//    @IBOutlet weak var precipitationLabel: UILabel!
//    @IBOutlet weak var summaryLabel: UILabel!
//    

    @IBOutlet weak var iconView: UIImageView!
    @IBOutlet weak var currentTimeLabel: UILabel!
    @IBOutlet weak var temperatureLabel: UILabel!
    @IBOutlet weak var humidityLabel: UILabel!
    @IBOutlet weak var precipitationLabel: UILabel!
    @IBOutlet weak var summaryLabel: UILabel!



    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let baseURL = NSURL(string: "https://api.forecast.io/forecast/\(apiKey)/")
        let forecastURL = NSURL(string: "33.613349,-117.899449", relativeToURL: baseURL!)

        //the following code makes our request syncronous and would tie up the app - not good
        // we want asyncronous code so we can use multiple threads of execution simultaneously

        //let weatherData = NSData(contentsOfURL: forecastURL!, options: nil, error: nil)
        //println(weatherData)

        let sharedSession = NSURLSession.sharedSession()
        let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(forecastURL!, completionHandler: { (#location: NSURL!, #response: NSURLResponse!, #error: NSError!) -> Void in

            if error == nil {
                let dataObject = NSData(contentsOfURL: location)
                let weatherDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataObject!, options: nil, error: nil) as NSDictionary

                let currentWeather = Current(weatherDictionary: weatherDictionary)


                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    self.temperatureLabel.text = "\(currentWeather.temperature)"
                    self.iconView.image = currentWeather.icon!
                    self.currentTimeLabel.text = "At \(currentWeather.currentTime!) it is"
                    self.temperatureLabel.text = "\(currentWeather.temperature)"
                    self.humidityLabel.text = "\(currentWeather.humidity)"
                    self.precipitationLabel.text = "\(currentWeather.precipProbability)"
                    self.summaryLabel.text = "\(currentWeather.summary)"
                })


            }
        })

        downloadTask.resume()
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

current:

import Foundation
import UIKit

struct Current {
    var currentTime : String?
    var temperature : Int
    var humidity : Double
    var precipProbability : Double
    var summary : String
    var icon : UIImage?

    init(weatherDictionary: NSDictionary) {

        let currentWeather = weatherDictionary["currently"] as NSDictionary

        temperature = currentWeather["temperature"] as Int
        humidity = currentWeather["humidity"] as Double
        precipProbability = currentWeather["precipProbability"] as Double
        summary = currentWeather["summary"] as String


        let currentTimeIntValue = currentWeather["time"] as Int
        currentTime = dateStringFromUnixTime(currentTimeIntValue)

        let iconString = currentWeather["icon"] as String
        icon = weatherIconFromString(iconString)
    }

    func dateStringFromUnixTime(unixTime : Int) -> String {
        let timeInSeconds = NSTimeInterval(unixTime)
        let weatherDate = NSDate(timeIntervalSince1970: timeInSeconds)

        let dateFormatter = NSDateFormatter()
        dateFormatter.timeStyle = .ShortStyle

        return dateFormatter.stringFromDate(weatherDate)
    }



    func weatherIconFromString(stringIcon: String) -> UIImage {
        var imageName: String

        switch stringIcon {
        case "clear-day":
            imageName = "clear-day"
        case "clear-night":
            imageName = "clear-night"
        case "rain":
            imageName = "rain"
        case "snow":
            imageName = "snow"
        case "sleet":
            imageName = "sleet"
        case "wind":
            imageName = "wind"
        case "fog":
            imageName = "fog"
        case "cloudy":
            imageName = "cloudy"
        case "partly-cloudy-day":
            imageName = "partly-cloudy"
        case "partly-cloudy-night":
            imageName = "cloudy-night"
        default:
            imageName = "default"
        }


        var iconImage = UIImage(named: imageName)
        return iconImage!
    }

    ````

It looks like you are missing the refreshActivityIndicator outlet and button.