When I set the model key path for the vertical slider to the temperature variable, I see the error message “The value binding expects to be bound to an object of type NSNumber, but temperature is of type int”. So I change the temperature definition to "var temperature = 68 as NSNumber. This takes care of the first error.
Now when I set the model key path for the label I get the error message “The value binding expects to be bound to an object of type NSString, but temperature is of type NSNumber” It would appear that I want something other than a Label to display the value of the temperature variable. I have deleted the label and added a text field with number formatter but now Xcode just hangs. Very perplexing.
Did you add @objc dynamic to your variables? like this:
@objc dynamic var temperature: Int {
set {
print("set temperature to \(newValue)")
privateTemperature = newValue
}
get {
print("get temperature")
return privateTemperature
}
}
@objc dynamic var isOn = 1 // have to use the number 1 because this is an Objective-C property
you don’t need to define privateTemperature with the Int type. Swift will infer the type from this:
var privateTemperature = 68
No huge deal, just pointing it out, and this is definitely NOT causing your issue.
When you first built the program, were you able to launch the empty window before adding any Thermostat code? Meaning, do you have the single window set up and the new windowNibName?
If so, did the program run initially when you set up the bindings between the slider and the label with File’sOwner.temperature? I’m assuming so. (I’m just trying to work through where you are in the process and what worked, and what was added when it quit running. I am new to programming so I have to work through it)
Try reviewing all of your bindings per the Debugging Bindings section of this chapter. If you are still stuck, the next advice I have is to completely build it again from the beginning. A lot of us on here have had to do that. Seems like there are times where Xcode puts a bug in as code is changed, changed again, copied and pasted. I built it again from the beginning while reviewing the chapter to see what might be causing your issue, it won’t take too long.
It seems to me the issue is with the bindings somehow. You could try rebinding to file’s owner and temperature to see if that works, before starting over.
import Cocoa
class MainWindowController: NSWindowController {
private var privateTemperature = 68
@objc dynamic var isOn = true
@objc dynamic var temperature: Int {
set {
privateTemperature = newValue
}
get {
return privateTemperature
}
}
@IBAction func makeWarmer(sender: NSButton) {
temperature = temperature + 1
}
@IBAction func makeCooler(sender: NSButton) {
temperature = temperature - 1
}
// The following is not needed, I included it incase you did to see if it caused the error somehow.
// It didn't.
override func setNilValueForKey(_ key: String) {
switch key {
case "temperature":
temperature = 68
default:
super.setNilValueForKey(key)
}
}
override var windowNibName: NSNib.Name? {
return NSNib.Name(rawValue: "MainWindowController")
}
override func windowDidLoad() {
super.windowDidLoad()
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
}
If yours is like this one, then the problem has to be with the bindings.
Open MainWindowController.xib and right click on File’s Owner. It should be similar to:
Thank you so much. Its working now. I created a new project and modified it according to the above discussion. Still I dont know what is wrong with old project. I dont see anything wrong with project settings.
Something like this has happened a few times, to me and others, working through this book. I don’t know if it’s a bug in Xcode, or if while we work on these we make changes and more changes and somehow that introduces an internal bug that we can’t see.