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 trialMichael Doyle
2,418 PointsNSUnknownKeyExeption for the key humidity?
Here is the ViewController.swift code:
import UIKit
class ViewController: UIViewController {
// links to labels
@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!
private let apiKey = "3a365c222ac8e460cdff4d4514dfe407"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//let forecastURL = "https://api.forecast.io/forecast/3a365c222ac8e460cdff4d4514dfe407/39.630016,-76.331865"
let baseURL = NSURL(string: "https://api.forecast.io/forecast/\(apiKey)/")
let forecastURL = NSURL(string: "39.630016,-76.331865", 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
// println(response)
// test to see if we are getting data from the URL
// var urlContents = NSString(contentsOfURL: forecastURL!, encoding: NSUTF8StringEncoding, error: nil)
//println(urlContents)
// want to hold contents in a file
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.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.
}
}
Here is the Current.swift code:
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
println(temperature)
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!
}
}
Here is the error text in the debug window:
2015-01-20 18:44:51.024 Stormy[25638:5639254] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<Stormy.ViewController 0x7fb6fd906c80> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key humidity.'
*** First throw call stack:
(
0 CoreFoundation 0x0000000100a29f35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010256dbb7 objc_exception_throw + 45
2 CoreFoundation 0x0000000100a29b79 -[NSException raise] + 9
3 Foundation 0x0000000100e417b3 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 259
4 CoreFoundation 0x0000000100973e80 -[NSArray makeObjectsPerformSelector:] + 224
5 UIKit 0x000000010157ac7d -[UINib instantiateWithOwner:options:] + 1506
6 UIKit 0x00000001013d9f98 -[UIViewController _loadViewFromNibNamed:bundle:] + 242
7 UIKit 0x00000001013da588 -[UIViewController loadView] + 109
8 UIKit 0x00000001013da7f9 -[UIViewController loadViewIfRequired] + 75
9 UIKit 0x00000001013dac8e -[UIViewController view] + 27
10 UIKit 0x00000001012f9ca9 -[UIWindow addRootViewControllerViewIfPossible] + 58
11 UIKit 0x00000001012fa041 -[UIWindow _setHidden:forced:] + 247
12 UIKit 0x000000010130672c -[UIWindow makeKeyAndVisible] + 42
13 UIKit 0x00000001012b1061 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 2628
14 UIKit 0x00000001012b3d2c -[UIApplication _runWithMainScene:transitionContext:completion:] + 1350
15 UIKit 0x00000001012b2bf2 -[UIApplication workspaceDidEndTransaction:] + 179
16 FrontBoardServices 0x0000000103cec2a3 __31-[FBSSerialQueue performAsync:]_block_invoke + 16
17 CoreFoundation 0x000000010095f53c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
18 CoreFoundation 0x0000000100955285 __CFRunLoopDoBlocks + 341
19 CoreFoundation 0x0000000100954a43 __CFRunLoopRun + 851
20 CoreFoundation 0x0000000100954486 CFRunLoopRunSpecific + 470
21 UIKit 0x00000001012b2669 -[UIApplication _run] + 413
22 UIKit 0x00000001012b5420 UIApplicationMain + 1282
23 Stormy 0x000000010043580e top_level_code + 78
24 Stormy 0x000000010043584a main + 42
25 libdyld.dylib 0x0000000102d47145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
I also see this in the AppDelegate.swift highlighted green right after @UIApplicationMain:
class AppDelegate: UIResponder, UIApplicationDelegate {
2 Answers
Michael Doyle
2,418 PointsHad to go back and delete the label in the main view. Then re-ad and re-connect. Then it worked. Not sure why.
Hampton Dunlap
Front End Web Development Techdegree Student 14,308 PointsI'm having the exact same issue; however, when a deleted and re-added the label in main view it did not fix the issue for me. Here is my viewController code: <body> 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!
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!)
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.
}
} </body>
here is the current code:
<body>
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 = "partly-cloudy"
default:
imageName = "default"
}
var iconImage = UIImage(named: imageName)
return iconImage!
}
}
</body>
and here is the error I'm receiving:
<body>
2015-03-27 10:31:21.865 Stormy[12762:1144886] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<Stormy.ViewController 0x7fa04a638290> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key precipitationLevel.' *** First throw call stack: ( 0 CoreFoundation 0x000000010027da75 exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000101dd5bb7 objc_exception_throw + 45 2 CoreFoundation 0x000000010027d6b9 -[NSException raise] + 9 3 Foundation 0x0000000100698d43 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 259 4 CoreFoundation 0x00000001001c75e0 -[NSArray makeObjectsPerformSelector:] + 224 5 UIKit 0x0000000100dd74ed -[UINib instantiateWithOwner:options:] + 1506 6 UIKit 0x0000000100c35a88 -[UIViewController _loadViewFromNibNamed:bundle:] + 242 7 UIKit 0x0000000100c36078 -[UIViewController loadView] + 109 8 UIKit 0x0000000100c362e9 -[UIViewController loadViewIfRequired] + 75 9 UIKit 0x0000000100c3677e -[UIViewController view] + 27 10 UIKit 0x0000000100b55509 -[UIWindow addRootViewControllerViewIfPossible] + 58 11 UIKit 0x0000000100b558a1 -[UIWindow _setHidden:forced:] + 247 12 UIKit 0x0000000100b61f8c -[UIWindow makeKeyAndVisible] + 42 13 UIKit 0x0000000100b0c0c2 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 2732 14 UIKit 0x0000000100b0ee3e -[UIApplication _runWithMainScene:transitionContext:completion:] + 1349 15 UIKit 0x0000000100b0dd35 -[UIApplication workspaceDidEndTransaction:] + 179 16 FrontBoardServices 0x0000000103987243 __31-[FBSSerialQueue performAsync:]_block_invoke + 16 17 CoreFoundation 0x00000001001b2c7c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 12 18 CoreFoundation 0x00000001001a89c5 __CFRunLoopDoBlocks + 341 19 CoreFoundation 0x00000001001a8785 __CFRunLoopRun + 2389 20 CoreFoundation 0x00000001001a7bc6 CFRunLoopRunSpecific + 470 21 UIKit 0x0000000100b0d7a2 -[UIApplication _run] + 413 22 UIKit 0x0000000100b10580 UIApplicationMain + 1282 23 Stormy 0x000000010009779e top_level_code + 78 24 Stormy 0x00000001000977da main + 42 25 libdyld.dylib 0x00000001025b1145 start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)
</body>