Yashman
Yashman

Reputation: 111

The simplest Cocoa Binding example

I am trying to get a basic understanding of Cocoa Bindings and I would like to create a really simple project. I have a class Person which has a variable name of type NSString. Here is how I want things to work:

  1. User enters a name into a text field and presses the "Update name" button
  2. The string from the text field is saved to an instance of the Person class.
  3. The label that is bound to the Person Controller (which is bound to the Person class) automatically changes its value according to the name variable of the Person instance.

I've spent hours reading various tutorials and the Apple Mac Developer Library, but each and every example only shows how to get Cocoa Bindings work with tables. When I try to develop something far more simpler I feel that I am completely lost. I have created a base project and the only thing left is to make all the bindings. I am kindly asking to make all the connections for me and hopefully provide me with an explanation. https://www.dropbox.com/sh/6hddfxyitqp6uoc/AACgaRhKBhLo6EXCVN9W6GQua?dl=0 The project is a document-based app because I will be developing an app of this type in the future.

Upvotes: 1

Views: 1943

Answers (1)

Willeke
Willeke

Reputation: 15589

There are several reasons why your project doesn't work so lets start again and create the simplest Cocoa Binding Example.

  1. Create a new Xcode project, choose Cocoa Application and don't check "Use Storyboards", "Create Document-Based Application" or "Use Core Data".
  2. Select MainMenu.xib, select the window and add a Text Field and a Label.
  3. Add an Object Controller to the xib. Switch Prepares Content on.
  4. Bind the Text Field to the Object Controller: bind Value to Object Controller, Controller Key selection and Model Key Path name.
  5. Bind the Label to the Object Controller: bind Value to Object Controller, Controller Key selection and Model Key Path name.
  6. Build, Run, Test. Enter some text and hit Return.

The controller automatically creates an instance of NSMutableDictionary which is KVO compliant for every key. When the contents of the Text Field is changed, the binding of the Text Field calls setValue:@"New Contents" forKey:@"name". This notifies the binding of the Label and the Label is updated.

Why your project doesn't work:

  • In the xib, the content of the Object Controller is connected to the document. The content of the controller should be a Person, not a Document. That's why you get [<Document 0x618000100750> valueForUndefinedKey:]: this class is not key value coding-compliant for the key name.. Remove this connection.
  • Class Person isn't KVO compliant. When the name changes, class Person doesn't emit a change notification and the binding doesn't notice the change. This can be fixed by using a property for name instead of an ivar. You don't have to use setValue:forKey: to change the name in code, person.name = [field stringValue] is ok.
  • The content of the Object Controller is set in the init method of the document. This is too early, the xib isn't loaded yet and the controller doesn't exist. Set the content in windowControllerDidLoadNib. Instead of addObject I would use setContent but addObject should work.

Upvotes: 7

Related Questions