macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Applying "Digital Hub" Concepts to Enterprise Software Design, Part 5
Pages: 1, 2, 3, 4

Connecting the Code to the Interface

  1. If it is not already open, open MyDocument.nib in Interface Builder by double-clicking it.

  2. 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 MyDocument class is visible. At this point, you may want to hide all of the applications on your screen except for Interface Builder.

  3. Switch back to the Instances tab in the "MyDocument.nib" window.

  4. While holding down the Control key 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:

    While holding down the Control key on the keyboard, use the mouse to drag a line from the File's Owner icon in the

    The connection that you just made allows your code to access the pop-up menu using the typeMenu variable that you declared in the MyDocument.h header file.

  5. In a similar way, drag a line from File's Owner to the text box and connect it to the "dataField" outlet.

  6. Now we are going to make a connect the other direction. While holding down the Control key, 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.

    Now we are going to make a connect in the other direction

    When we drag a connection from the user interface to File's Owner, we are telling the application to call the createNewItem method 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 dataItems array.

  1. 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 DataItem Controller.

  2. Drag a second array controller to the "MyDocument.nib" window and rename it MeasureType Controller.

  3. Hold down the Control key 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 createNewItem method to send messages to the array controller.

    Hold down the Control key and drag a line from the File's Owner icon to the DataItem Controller icon that you created
  4. 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.

  5. Expand the "contentArray" option in the information page.

  6. Set the Bind to: option to File's Owner (MyDocument) and type theItems for the Model Key Path option. Then make sure that the Bind checkbox is checked.

    Hold down the Control key and drag a line from the File's Owner icon to the DataItem Controller icon that you created
  7. 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 DataItem (since DataItems are the objects stored in the array). Click the Add button three times and rename the keys to theData, typeName, and timeTaken

     Next, choose Attributes from the information pane pop-up menu
  8. Repeat steps 4 through 6, but this time bind the MeasureTypes Controller to the measureTypes array. Remember to check the Bind checkbox!

  9. 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:

  1. 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 timeTaken as the model key path. Make sure that the Bind checkbox is checked. See the following screenshot:

     Select the Date column in the table. It may take several clicks
  2. Use the same method to bind the Data column. The model key path will be theData.

  3. Bind the Type column as well. Because this column is displayed with pop-up menus, you will bind typeName to the selectedValue attribute rather than value. Otherwise, the steps are the same.

  4. 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".

  5. 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 name.

  6. Finally, connect the Delete Selected button to the DataItem Controller by holding Control and 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.

     Finally, connect the Delete Selected button to the DataItem Controller by holding control and dragging a line from the button to the DataItem Controller icon

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!

Extra Credit

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.

Resources

Adam Behringer works as the CEO of Bee Documents, which strives to help legal and medical firms efficiently manage their documents.


Return to MacDevCenter.com.