BaseTen Tutorial
This tutorial was originally written by Tim Bedford.
Introduction
If you have read Aaron Hillegass’ book Cocoa Programming for Mac OS X, then this example will be familiar. We are going to create an application much like the one in the chapter on Basic Core Data. If you haven’t read the book, then I recommend you do. It is a great primer to Objective-C and Cocoa. Even if you have a good working knowledge of both, the book makes a good reference.
Before We Start
Before we can begin building a BaseTen application we need to install the tools and frameworks. Open up BaseTen-1.7.dmg. Drag the BaseTen.framework and BaseTenAppKit.framework to the alias of the Frameworks folder. This will copy them into /Library/Frameworks/. Copy BaseTen Assistant and the reference manual where ever you like.
You will also need to have a version of PostgreSQL installed, either on your development machine, or another accessible over the network. PostgreSQL 8.3 has been used to create this tutorial. A ready compiled version for Mac OS X is available with a simple installer:
Designing the Model
Start Xcode and create a new project of type Cocoa Application. Name the project CarLot. Imagine that you own several used car lots. This application will enable you to keep track of the cars that you wish to sell. Better your staff at each lot can see and update this information. When it is done, it will look like Figure 1.
In the new project add a new group, name it Models. Within it add a new file of type Data Model, name it CarLotModel.xcdatamodel. We won’t be adding any existing classes as entities, so click Finish.
Now we need to uncheck the target membership, as shown in Figure 2. The data model will be used by the BaseTen Assistant to create a database schema, but will not be compiled into the project.
Open CarLotModel.xcdatamodel. At the bottom of the Entity table view, click the + button to create a new entity. Name the entity Car.
With the Car entity selected, choose Add Attribute in the pop-up at the bottom of the Properties table view. Add six attributes and give them the following names and types. Finally save the model.
| Name | Type |
| condition | Integer 16 |
| datePurchased | Date |
| makeModel | String |
| onSpecial | Boolean |
| photo | Binary data |
| price | Decimal |
Figure 3 shows what it looks like in the modeller.
Building the Database Schema
Launch the Terminal utility and create a new PostgreSQL database named cars. See the PostgreSQL manual for more information on how to do this. If the PostgreSQL bin folder is not in your user path you will need to navigate there manually:
cd /Library/PostgreSQL/8.3/bin
./createuser -S -D -r -E -U postgres -P carlot
Enter a password for the new role. Enter it again to confirm. Now enter your postgres password to create the new user. Now create the new database:
./createdb -E UTF-8 -O carlot -U postgres cars
Enter the postgres password.
Start the BaseTen Assistant. Connect to the PostgreSQL server, specifying the cars database and the carlot user name and password. Click Import Model on the toolbar, or press ⌘O. Choose the CarLotModel.xcdatamodel you recently created. The import sheet will be displayed, as shown in Figure 4.
Check the Car box in the Tables table view. Now press Import Model. Because this is a new database the BaseTen schema, required by the framework, needs to be installed. Click on Install when prompted to install the BaseTen schema. The imported schema should look like Figure 5.
Add Frameworks
Return to Xcode. Expand the Frameworks group, then select the Linked Frameworks group within it. Now choose Add → Existing Frameworks from the context menu. Navigate to /Library/Frameworks/ and add BaseTen.framework and BaseTenAppKit.framework.
Add a Copy Files Build Phase
BaseTen and BaseTenAppKit have been set up so that they are expected to be found inside an application bundle. To make sure the frameworks get copied inside your application, expand the Targets group and the CarLot target inside it. Select CarLot and choose Add → New Build Phase → New Copy Files Build Phase from the context menu. An info window for the build phase will open. Select Frameworks as the target, leave the path field empty and close the window. Now drag BaseTen.framework and BaseTenAppKit.framework from Linked Frameworks onto the new build phase. You can also rename it by choosing Rename from the context menu.
Interface
Open MainMenu.xib. Since you added BaseTenAppKit to your project, Interface Builder should automatically load the BaseTen plug-in. You can check this from the Plug-ins pane of Interface Builder preferences.
Look for BXDatabaseContext and BXSynchronizedArrayController in the Library palette, Figure 7 shows what they look like. Drag one of each into the MainMenu.xib window.
Select the Database Context. In the Attributes Inspector, set the Database URI to pgsql://carlot@localhost/cars/. Also check Autocommits (Figure 8).
Select the Synchronized Array Controller. Hold control and drag a connection from the databaseContext outlet to the Database Context object in the MainMenu.xib window (Figure 9).
Note: Under some circumstances the outlets and actions won't show up when the Interface Builder plug-in has been loaded for the first time. If this happens, save and close your MainMenu.xib and open it again. Also relaunching Interface Builder has solved the issue.
Switch to the Attributes Inspector, set the Table Name to Car. Check the Fetch On Connect option. In the MainMenu.xib window rename the Synchronized Array Controller to Cars, this makes it easier to refer to later on. See Figure 10.
Create and Configure Views
Open the NSWindow object. Drag out an NSTableView from the Library and drop it in the window. In the Attributes Inspector, give the table three columns. Name them Make/Model, Price, and Special. Drop a number formatter on the Price column. Select the formatter (represented by a little circle in the column), and configure it to show currency. Use the 10.4+ formatter, and set the style to Currency. Also, check the boxes Generate Decimal Numbers and Always Shows Decimal (Figure 11).
The third column will be populated by check boxes, so drop a check box cell on the third column. Select the cell, and clear its title.
Below the table view, drop on the window an NSDatePicker, two NSButtons, an NSImageView (Image Well) and an NSLevelIndicator. Put label text fields next to the date picker and the level indicator. The buttons should be labelled New and Delete.
The labels should be Date Purchased: and Condition:. In the Attributes Inspector of the NSLevelIndicator, set its min to 0 and its max to 5. Set its style to Rating mode (to get the stars). Also, make the level indicator editable. See Figure 12.
Make the NSImageView editable by using the Attributes Inspector.
Select the date picker, the image view, the two labels, and the level indicator. Go to the Layout menu and select the Embed Objects In → Box menu item.
Connections and Bindings
Now, you are going to do a bunch of bindings. I will walk you through it step by step; Figure 13 is a diagram of the bindings that you are going to create between your views and the array controller.
Bind the value of each column:
| Binding | Bind to | Controller Key | Key Path |
| value of Col 0 | Cars | arrangedObjects | makeModel |
| value of Col 1 | Cars | arrangedObjects | price |
| value of Col 2 | Cars | arrangedObjects | onSpecial |
Make the New button trigger the add: method of the Cars object, and make the Delete button trigger the remove: method of the Cars object.
Bind the value of the controls to the selection of the Cars:
| Binding | Bind to | Controller Key | Key Path |
| value of date picker | Cars | selection | datePurchased |
| enabled of Delete button | Cars | canRemove | |
| value of level indicator | Cars | selection | condition |
Bind the Data (not Value) of the image view to Cars. Choose the controller key selection and the key path photo. Also, check the box that says Conditionally Sets Editable (Figure 14).
Bind the Title With Pattern of the box to Cars. Set the Controller Key to selection. Set the Model Key Path to makeModel. Set the Display Pattern to Details for %{title1}@ . Set the No Selection Placeholder to <No selection>. Set the Null Placeholder to <No make/model>. See Figure 15.
Finally make the text of the first two columns appear in bold if the car is on special. Bind the Font Bold binding to Car’s arrangedObjects.onSpecial (Figure 16).
That’s it. Make sure MainMenu.xib is saved, then build and run the application.
Testing
New cars can be added by clicking the Add button. The make/model, pric and on special information can be edited in the table view. A picture can be dragged to the image well. Add the details for a few cars.
From the Termial application connect to the database with psql -U carlot cars. Type a simple query:
select "makeModel", "price", "onSpecial", from "Car";
Press return. PostgreSQL will output the data you entered in the CarLot application.
Try updating the data with a query such as:
update "Car" set "price" = "price" - 1000, "onSpecial" = true;
All cars will be reduced in price by £1000 and marked as on special.
Notice how the table view in CarLot application automatically updates when you do this.
