A couple of tweaks that I made to the Property List example:
1. As written, since everything is keyed off of the lastName, it is not possible to have two entries with the same last name, something that is very likely in a "Contacts" program (e.g. family members). All subsequent entries replace prior entries with the same lastName. I resolved this by creating an additional key containing a fullName by appending the firstName to the lastName. Sorting and searching is done by this new key to maintain alphabetic order. When presenting the names in the rootView tableView, if instances of the same name appear more than one time, a first initial is also included. For example:
Jones, J.
Jones, T.
2. In PersonAddViewController I felt some basic validation is a good thing. I added checks to make sure that the input for names was alphabetic throwing up an alert if it was not, and when entering the phone number having the keyboard type switch to the number pad and requiring a valid (U.S.) number of digits. The phone number in the PersonDetailView pane could also be formatted.
In the CoreData version, since everything is stored as a Person entity, there is no issue with multiple same lastName entries. As above, to distinguish matching entries, I also have first initials displayed if multiple entries of the same last name occur. In order to keep things properly sorted when this occurs, I added a second,
firstName, sortDescriptor to the fetchedRequestController. I also applied the same validation and formatting as in the Property List example.
In both versions, it does not make sense to have the edit button available if no contacts are in the list. I add it after the first contact is inserted, and remove it should the number of contacts go to 0.
A minor editorial issue which also snuck into the the downloadable source code is a mismatch of keys and fields on p. 340 and again on p. 364 Listing 10-26
Code:
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:[self firstName] forKey:@"firstName"];
[coder encodeObject:[self lastName] forKey:@"lastName"];
[coder encodeObject:[self phone] forKey:@"phone"];
}
- (id)initWithCoder:(NSCoder *)coder {
if (self = [super init]) {
[self setLastName:[coder decodeObjectForKey:@"firstName"]];
[self setFirstName:[coder decodeObjectForKey:@"lastName"]];
[self setPhone:[coder decodeObjectForKey:@"phone"]];
}
return self;
}
should be
Code:
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:[self firstName] forKey:@"firstName"];
[coder encodeObject:[self lastName] forKey:@"lastName"];
[coder encodeObject:[self phone] forKey:@"phone"];
}
- (id)initWithCoder:(NSCoder *)coder {
if (self = [super init]) {
[self setFirstName:[coder decodeObjectForKey:@"firstName"]];
[self setLastName:[coder decodeObjectForKey:@"lastName"]];
[self setPhone:[coder decodeObjectForKey:@"phone"]];
}
return self;
}
Bob