Connecting the Code to the Interface
If it is not already open, open MyDocument.nib in Interface Builder by double-clicking it.
Drag MyDocument.h from Xcode to the Instances tab of the window titled "MyDocument.nib" in Interface builder. This will cause the .nib file to be aware of the outlets you added in the code. You will have successfully completed this step if the "MyDocument.nib" window switches to the Classes tab and the
MyDocumentclass is visible. At this point, you may want to hide all of the applications on your screen except for Interface Builder.
Switch back to the Instances tab in the "MyDocument.nib" window.
While holding down the
Controlkey on the keyboard, use the mouse to drag a line from the File's Owner icon in the "MyDocument.nib" window to the pop-up menu in the user interface window. Then, using the connections options in the information pane, select the typeMenu outlet and press the Connect button. See the screenshot below:
The connection that you just made allows your code to access the pop-up menu using the
typeMenuvariable that you declared in the MyDocument.h header file.
In a similar way, drag a line from File's Owner to the text box and connect it to the "dataField" outlet.
Now we are going to make a connect the other direction. While holding down the
Controlkey, drag a line from the Add button to the File's Owner icon. In the information pane, choose the target "createNewItem:" and click the connect button. If you do not see the "createNewItem:" target, then you may need to change the second pop-up menu in the information pane to Outlets. See the screenshot if you need help.
When we drag a connection from the user interface to File's Owner, we are telling the application to call the
createNewItemmethod when the user clicks the button.
Notice that we have not connected the table or the delete button yet. That is because Xcode has recently added the concept of bindings. We can (and will) create a controller object that will manage a lot of the busywork in synchronizing the user interface elements and the
Switch to the Controllers palette in Interface Builder and drag the array controller from the palette to the "MyDocument.nib" window. The array controller is the one that looks like three green cubes. Rename the controller that you just created to
Drag a second array controller to the "MyDocument.nib" window and rename it
Hold down the
Controlkey and drag a line from the File's Owner icon to the DataItem Controller icon that you created. Choose "theController" in the information pane and click the connect button. This will allow our
createNewItemmethod to send messages to the array controller.
The array controllers can stay synchronized with our array instance variables, but we need to tell them to do so. Click the DataItem Controller icon and choose the Bindings option from the pop-up menu in the information pane.
Expand the "contentArray" option in the information page.
Set the Bind to: option to File's Owner (MyDocument) and type
theItemsfor the Model Key Path option. Then make sure that the Bind checkbox is checked.
Next, choose Attributes from the information pane pop-up menu. We are going to add three keys to the
NSArrayController, one for each instance variable in
DataItems are the objects stored in the array). Click the Add button three times and rename the keys to
Repeat steps 4 through 6, but this time bind the MeasureTypes Controller to the
measureTypesarray. Remember to check the Bind checkbox!
With MeasureTypes Controller still selected, choose Attributes from the information page pop-up menu. Add a key labeled "name".
We are almost done! All that remains is binding the array controllers to the user interface elements with Interface Builder. Here is how to do that:
Select the Date column in the table. It may take several clicks. You will know you have it selected when the column header is blue and the information pane is labeled "NSTableColumn". In the pop-up menu at the top of the information pane, select Bindings. Expand the options for value. Select DataItem Controller as the Bind to: value, arrangedObjects as the controller key, and
timeTakenas the model key path. Make sure that the Bind checkbox is checked. See the following screenshot:
Use the same method to bind the Data column. The model key path will be
Bind the Type column as well. Because this column is displayed with pop-up menus, you will bind
selectedValueattribute rather than
value. Otherwise, the steps are the same.
The Type column as needs to know the values with which to populate its pop-up menus. Select the small triangle on the right side of the column header. The information pane should now be labeled "NSPopUpButtonCell".
Expand the "content" options in the bindings pane. Set Bind to: to MeasureType Controller, the controller key to "arrangedObjects", and the modal key path to
Finally, connect the Delete Selected button to the DataItem Controller by holding
Controland dragging a line from the button to the DataItem Controller icon. Select the "remove:" target (you may have to set the pop-up menu to Outlets first) and click Connect.
Congratulations, you are done! Save the work you did in Interface Builder,
then switch back to Xcode and run your application by pressing
Apple-R. If an
element of the user interface is not working, be sure to check its connections
and bindings. Open the
sample XML file, add some new data, and save it. Check out the column sorting
too. If you built the WeatherHub application in the previous article, try exporting
XML, adding some new data, and then importing the data back into the hub.
The Beauty of it All
Now, I know that you are probably having a lot of fun creating this Cocoa application. Cocoa is pretty cool, particularly with the new bindings technology. However, I do not want you to miss this the real beauty of what is going on here.
Because we laid the foundation of flexible enterprise hub architecture based on XML, we were able, in a short time, to design and build a powerful data-entry tool that plugs right into the greater system and can contribute valuable new features without changing any of the other components. It does not matter that most of the system so far was written in Java and the new piece was written in Cocoa. We can use the best tool for the job without restriction (as long as it can parse XML).
Let's say that after creating this application, all of the iBook-toting scientists are happy, but those with Windows machines feel left out. No problem; just whip up a similar application in Visual Basic .NET that parses and creates XML in the same way.
As a final example, imagine that a Linux machine is controlling a thermometer and should be able to submit the data without human interaction. Again, no problem, because you can quickly create a script in your favorite language that can take the data from the thermometer, package it in XML, and send it to the hub via a file upload or a web service.
In fact, in the next article, we will build another module in another language to prove this point. It will be a Perl tool that will retrieve data from the WeatherHub application using web services rather than requiring the user to manually download the XML from the web interface. Then the tool will do some analysis of the data. Stay Tuned!
When we open the XML in our Cocoa application and then save it, we are tossing out the old data and only preserving the data we need to make updates. This is fine if someone is downloading the data only for the purpose of adding updates, but if they want to use it for other purposes--while they have it stored locally--it might be better to preserve the old data. As extra credit, save all of the data that is read from the XML file and write it back out again. Remember that the old data should not be displayed in the user interface of the EnterData application.
Another thing that would be great is data validation based on the
dataType attribute of each measurement type. In this tutorial, we are not doing any validation of the data that is entered. If this was a real-world project, the validation should be dynamic based on the values found in the XML.
- Apple Developer Connection
- Big Nerd Ranch: Great Cocoa training and books
- Cocoa Dev Central: Articles and tutorials
Return to MacDevCenter.com.