Tải bản đầy đủ (.pdf) (7 trang)

a0247 wrox professional split 1 1063

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (931.25 KB, 7 trang )

186



CHAPTER 7 BUILDING A CORE DATA APPLICATION

LISTING 7-4 (continued)

Task* managedTaskObject;
NSManagedObjectContext *managedObjectContext;
}
@property (nonatomic, retain) Task* managedTaskObject;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;

@end

In the implementation fi le, you fi rst need to synthesize the properties that you declared in the
header:
@synthesize managedTaskObject,managedObjectContext;

As in the EditTextController, you should implement the viewDidUnload method to set the
properties defi ned in the class to nil:
- (void)viewDidUnload {
self.managedObjectContext=nil;
self.managedTaskObject = nil;
[super viewDidUnload];
}
EditPriorityController.m

Leave the numberOfSectionsInTableView method with the default implementation because the
table will have only one section. Change tableView:numberOfRowsInSection: to return four


rows, one for each priority level.
Next, implement the tableView:cellForRowAtIndexPath: method to show the priority options in
the appropriate cell:
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @”Cell”;
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}

CH007.indd 186

9/18/10 9:48:45 AM


Building the Editing Controllers

// Set up the cell...
switch (indexPath.row) {
case 0:
cell.textLabel.text
break;
case 1:
cell.textLabel.text
break;

case 2:
cell.textLabel.text
break;
case 3:
cell.textLabel.text
break;
default:
break;
}

❘ 187

= @”None”;

= @”Low”;

= @”Medium”;

= @”High”;

// place the checkmark next to the existing priority
if (indexPath.row == [managedTaskObject.priority intValue] )
{
cell.accessoryType=UITableViewCellAccessoryCheckmark;
}
return cell;
}
EditPriorityController.m

This method should be familiar to you. The fi rst few lines try to dequeue a cell as usual. Then,

the code determines the text of the cell based on which cell you are providing. The last bit of code
displays a checkmark next to the currently chosen priority for the task.
When a user taps a row, you need to save that selection in the Task object. You will do that in the
tableView:didSelectRowAtIndexPath: method:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Deselect the currently selected row according to the HIG
[tableView deselectRowAtIndexPath:indexPath animated:NO];
// Configure the managed object
managedTaskObject.priority=[NSNumber numberWithInt:indexPath.row];
// Save the context.
NSError *error = nil;
if (![self.managedObjectContext save:&error]) {
// There was an error validating the date

CH007.indd 187

9/18/10 9:48:46 AM


188



CHAPTER 7 BUILDING A CORE DATA APPLICATION

// Display error information
NSLog(@”Unresolved error %@, %@”, error, [error userInfo]);
UIAlertView* alert = [[UIAlertView alloc]
initWithTitle:@”Invalid Due Date”

message:[[error userInfo] valueForKey:@”ErrorString”]
delegate:nil cancelButtonTitle:@”OK” otherButtonTitles:nil ];
[alert show];
[alert release];
// Roll back the context to
// revert back to the old priority
[self.managedObjectContext rollback];

}
else {
// pop the view
[self.navigationController popViewControllerAnimated:YES];
}
}
EditPriorityController.m

The fi rst thing that this method does is deselect the selected row as I explained in the
last section.
The next line sets the Task object’s priority field to the priority level selected on the screen.
Then, the code saves the context. Because you are going to add a validation rule that includes the
priority, there is a possibility that the new priority could fail the validation. If the validation fails,
the save method will fail, so you need to roll the context back to its state before the failed save.
If the save method fails, you revert the priority back to its original state using the rollback
method of the context. The rollback method undoes all changes to the context that have not yet
been committed with a successful save call. If an error occurs, such as a validation failure, you
show the user an alert to inform him that a problem has occurred. If there is no problem, the code
pops the View Controller from the stack.
Finally, implement the dealloc method to release the member variables that you allocated in
the class:
- (void)dealloc {

[managedTaskObject release];
[managedObjectContext release];
[super dealloc];
}
EditPriorityController.m

CH007.indd 188

9/18/10 9:48:46 AM


❘ 189

Building the Editing Controllers

Adding and Editing Locations with the
EditLocationController
The user navigates to the EditLocationController by
tapping the location cell on the ViewTaskController. The
EditLocationController, as shown in Figure 7-9, allows
the user to select a location, add new locations, and delete
existing locations. To create the EditLocationController,
create a new UITableviewController without a NIB called
EditLocationController.
Modify your new header fi le to create instance variables
and properties to hold the context and Task objects that the
parent screen will configure. You will also need to add a member
variable and property for the NSFetchedResultsController
that you will use to display your location list. Additionally,
you will need to add #import directives for the Task and

Location header fi les. The completed header fi le should look
like Listing 7-5.

FIGURE 7- 9: EditLocation
Controller Screen

LISTING 7-5: EditLocationController.h

#import <UIKit/UIKit.h>
#import “Task.h”
#import “Location.h”
@interface EditLocationController :
UITableViewController <NSFetchedResultsControllerDelegate> {
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
Task* managedTaskObject;
}
@property (nonatomic, retain) NSFetchedResultsController
*fetchedResultsController;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) Task* managedTaskObject;
@end

Let’s move on to the implementation fi le. Add an import statement for EditTextController.h:
#import “EditTextController.h”

You will use the EditTextController to add the text for newly added locations. Next, synthesize
the properties that you declared in the header fi le:
@synthesize fetchedResultsController, managedObjectContext, managedTaskObject;


CH007.indd 189

9/18/10 9:48:46 AM


190



CHAPTER 7 BUILDING A CORE DATA APPLICATION

Uncomment and implement the viewDidLoad method:
- (void)viewDidLoad {
[super viewDidLoad];
// Set up the add button
UIBarButtonItem *addButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self action:@selector(insertNewLocation)];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
NSError* error;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@”Unresolved error %@, %@”, error, [error userInfo]);
abort();
}
// set the title to display in the nav bar
self.title = @”Location”;
}
EditLocationController.m


This code creates the addButton and sets it to call the insertNewLocation method. It then adds the
addButton to the nav bar. Next, you tell the fetched results controller to fetch its data. Finally, you
set the title of the screen to Location.
Next, you need to set the class properties in the viewDidUnload method to nil:
- (void)viewDidUnload {
self.fetchedResultsController=nil;
self.managedTaskObject=nil;
self.managedObjectContext=nil;
[super viewDidUnload];
}
EditLocationController.m

Now, add the insertNewLocation method that runs when the user taps the Add button that
you created in viewDidLoad. This method adds a new Location to the context and pushes the
text controller on to the navigation stack to allow the user to edit the location name. Here is
the insertNewLocation method:
- (void)insertNewLocation {
NSManagedObjectContext *context = self.managedObjectContext;
Location *newLocation =

CH007.indd 190

9/18/10 9:48:47 AM


bindex.indd 377

9/17/10 7:26:14 PM



bindex.indd 378

9/17/10 7:26:14 PM



×