A Look Inside Address Book
Pages: 1, 2, 3
Searching
A database isn't worth much without a way to search the contents. In address book, the class ABSearchElement is how we create queries with any range of complexity. A search element contains a simple search, like search the address book for all records with the first name Mike, or search for all records with birth dates occurring before the turn of the millennium.
Two or more ABSearchElement objects may be combined into a single composite search elements using either an AND operator or an OR operator. By combining search elements in this way it is possible to build quite complex queries.
Instances of ABSearchElement are created using the ABPerson or ABGroup class method searchElementForProperty:label:key:value:comparison:. Whether we invoke this method in the ABPerson class object or the ABGroup class object depends on whether we want to perform a search for people, or a search for groups. This method takes the following parameters:
searchElementForProperty: is the record property the we wish to perform the search againlabel: If the property is a multi-value property, then we can specify a label here to restrict the search to one particular element of the multi-valuekey: If the property value is a dictionary, then we can specify a key in the dictionary here to restrict the search.value: This is the value we are searching forcomparison: This parameter specifies how the search process will identify a matching value.
The last parameter, comparison:, tells the search element how to determine a matching value. There are ten possible constants to pass here: kABEqual, kABEqualCaseInsensitive, kABLessThan, kABLessThanOrEqual, kABGreaterThan, kABGreaterThanOrEqual, kABContainsSubStringCaseInsensitive, kABPrefixMatch, kABPrefixMatchCaseInsensitive.
To create a composite, or conjunction, search we use the ABSearchElement class method searchElementForConjunction:children:. The first parameter tells the method how the child search elements will be combined. The possible values are kABAndSearch and kABOrSearch. The children: parameter takes an array of ABSearchElements that are to be combined in the conjunction search. Children search elements may be simple searches, or conjunction searches themselves.
The following is an example of searching the address book using search elements:
ABSearchElement *se;
NSArray *results;
se = [ABPerson searchElementForProperty:kABAddressProperty
label:kABAddressHomeLabel
key:kABAddressStateKey
value:@"Texas"
comparison:kABEqual];
results = [book recordsMatchingSearchElement:se];
NSLog( [results description] );
As you can see above, the method recordsMatchingSearchElement: returns an NSArray containing all of the people in the address book whose home address is in Texas.
Performing a conjunction search is done similarly:
ABSearchElement *se1, *se2, *cse;
NSArray *children;
se1 = [ABPerson searchElementForProperty:kABAddressProperty
label:kABAddressHomeLabel
key:kABAddressStateKey
value:@"Texas"
comparison:kABEqual];
se2 = [ABPerson searchElementForProperty:kABBirthdayProperty
label:nil
key:nil
value:[NSDate dateWithTimeIntervalSinceReferenceDate:0]
comparison:kABLessThan];
children = [NSArray arrayWithObjects:se1, se2, nil];
cse = [ABSearchElement searchElementForConjunction:kABAndSearch
children:children];
results = [book recordsMatchingSearchElement:cse];
NSLog( [results description] );
The composite search element cse will search for all people in the address book database who not only live in Texas, but who were born before the turn of the millennium, which we specify by creating a date that is zero seconds past the reference date (the absolute reference date used by NSDate is 12:00 AM, January 1, 2001 GMT).
Odds and Ends
To tie up loose ends, let's talk a bit about assigning images to an ABRecord, as well as how we can import and export vCards to and from the AddressBook database.
Creating a vCard is easily accomplished using the ABRecord method vCardRepresentation. This method returns an NSData object whose data is formatted in the vCard format. We can then write this data to disk, which can be read by any number of applications that recognize the vCard format. Going the other way we can initialize an ABRecord object with vCard data using the method initWithVCardRepresentation:. This method takes a parameter an NSData object, which was likely created by reading the contents of a vCard file on disk created by another application.
Finally, to associate an image with a person in the AddressBook we use the methods setTIFFImageData: and TIFFImageData to set and get the person's picture. These methods work with NSData objects whose data is formatted as a TIFF image. This interfaces well with the NSImage methods TIFFRepresentation, which returns an TIFF formatted NSData object, and initWithData:, which initializes an NSImage object with image data.
The End
So, that was a whirlwind tour of the AddressBook framework. It's not really my style to leave you empty-handed at the end of a column, so I've prepared a version of our old-school application Address Book that we worked on about a year ago while learning about NSTableView. This version has been revamped to display the contents of the user's address book in a table, and allow the user to edit records. It's basically the same thing we had before, except the data model is based on ABAddressBook rather than on NSArray and NSDictionary. This is an excellent example of the utility of MVC since the model was separated from the view and insulated by the controller, so it was relatively pain-free to change.
So, happy Jaguar release, and next time we'll get back to those plug-ins.
Michael Beam is a software engineer in the energy industry specializing in seismic application development on Linux with C++ and Qt. He lives in Houston, Texas with his wife and son.
Read more Programming With Cocoa columns.
Return to the Mac DevCenter.
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 16 of 16.
-
Parsing the AddressBook.data file?
2003-08-15 14:17:56 pthomsen [Reply | View]
I am trying to write an extension to Mozilla Thunderbird, that will allow me to read the Address Book database.
This will obviously be implemented in XUL and JavaScript.
Short of building a binary library that the JavaScript can talk to, does anyone have any idea how to parse the file directly?
Thanks in advance,
Per
-
List people in one particular category only.
2002-12-30 09:11:07 iuni [Reply | View]
Excellent article! I am wondering though, I still cannot see how you could fill an array with just the people in one particular category.
-
What about the interface?
2002-11-26 08:00:13 anonymous2 [Reply | View]
This is all fine and good, but why isn't there some way to do a generalized database along the same lines in regular cocoa programming? And while we're on the subject...
I use 10.1.5 currently, but happened to see 10.2 on another computer which didn't have developer tools installed. I'm trying to program a simple database but need a flexible user interface that adapts to wildly varied field lengths, while efficiently using screen space. The "edit" screen for individuals within the 10.2 address book was EXACTLY what I've been looking for (single scroll view with nicely formatted fields that expand as necessary), except of course I'd use different fields. This does not appear to be a typical interface element. How can a build a similar interface? Is there source code available somewhere?
-
Apple Laptop Keyboards Unsuitable for Unix Users
2002-09-18 02:20:11 anonymous2 [Reply | View]
Apple laptops are effectively unusable for unix users.
I am a long-time Unix user. That means I need to have the Ctrl key to the left of the A key. This is a genuine need, not merely a want; it is based upon ergonomics. The Ctrl key is heavily used in unix, and it must be easily accessable. It cannot be off in the lower left corner of the keyboard where it is difficult to get at, and where it distorts the position of your left hand such that you can't easily type other keys while holding the Ctrl key down.
Apple desktop keyboards are now all USB. They are all OK. The CapsLock key can be re-mapped into a Ctrl key.
Unfortunately, even in this modern age, all Apple laptops have built-in ADB keyboards. The ADB keyboard is broken-by-design. It is, in general, not possible to remap the CapsLock key into a Ctrl key.
There are some exceptions, but they are horrible kludges. They are
horrible kludges because the original design of the ADB keyboard was a horrible kludge. The correct solution would be for Apple to re-design their laptop motherboards to use built-in USB keyboards. This hasn't happened yet. If you run Linux, use Debian's solution. For Mac OS X users, uControl works. There are no solutions (that I know of) for either NetBSD or OpenBSD. Please note once again that the "solutions" above are in fact kludges, because of the original bad design of the ADB keyboard.
Apple is (currently) ignoring Unix users! This is not merely speculation on my part. In an on-going email exchange I am having with an Apple employee (whom I won't name) in their marketing department, the Apple marketing person directly stated to me that Apple was catering to their historic Mac customers, and is purposely ignoring the Unix market. He also claimed that Apple would soon start paying more attention to the Unix market. I won't hold my breath. Apple has been ignoring Unix users for more than 10 years. I expect that trend to continue. (Also note that my Apple contact indicated that Macs would never ship with a 3-button mouse, even though Apple intended to port almost all X-window software and deliver it either on a CD/DVD or installed directly on each Mac's hard drive. How Unix friendly is a 1-button mouse with X programs that often require 3 buttons?)
Apple has now lost two opportunities to sell me hardware. I really wanted an Apple laptop for their superior battery life, and for the PowerPC with Altivec CPU. (The Altivec is vastly superior to the x86 line for DSP.) Because I can't live with the broken-by-design built-in ADB keyboard in all Apple laptops, Sony and IBM sold me laptops instead. If Apple fixes this problem, they will sell me a PowerBook next year; if they don't, I'll still be running OpenBSD on x86 hardware, and wishing I could use a Mac.
-
Apple Laptop Keyboards Unsuitable for Unix Users
2004-04-06 09:50:17 macdaddy2008 [Reply | View]
I would like to know what this comment has to do with this article. If you would like to complain, tell it to Apple. But don't pollute these comments with content that has nothing to do with the article.
-
LDAP Databases
2002-09-13 12:51:21 inetws [Reply | View]
I noticed that the Address Book can access LDAP Databases. Can LDAP Databases be accessed through the APIs described in the article?
-
Strange Error
2002-09-09 21:41:06 johnts [Reply | View]
I tried entering the sample and I'm getting a strange error. Firstly, I have 10.2, the new dev tools and some entried in my address book on a G4 dual 450. I've added the AddressBook framework to the project and the main.m file is only:
#import <Foundation/Foundation.h>
#import <AddressBook/AddressBook.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
ABAddressBook *book = [ABAddressBook sharedAddressBook];
NSArray *everyone = [book people];
// insert code here...
NSLog([everyone description]);
[pool release];
return 0;
}
Simple.
I compile with no problem (even after cleaning) and when I try to run, I get an error at the bottom:
Run session aborted: No launchable executable present to run.
Don't have a clue. Same sample ran with no problems on my iBook.
-
clarified my confusion on NSDictionary
2002-09-03 15:56:36 psheldon [Reply | View]
I had some confusions a year ago in table article and now with NSDictionary, maybe others got stuck like I did. When we did tableview article, I didn't quite fathom why NSDictionary was called a dictionary. I wasn't quite satisfied I had "owned" what a dictionary was. For the current article, I wrote a lot of notes and thrashed my memory with them to winnow them down to something I could handle in understanding the lingo.
An NSDictionary corresponds to a record row under column headers. The elements of a column under the column header give their meanings or values of that column header. That's why this is called an NSDictionary.
NSDictionary, though an ntuple of sorts, is actually a 1D row. We saw, in a previous article, an table of such NSDictionary records is 2D. We know from databases and finder that column headers can be used for sorting and searching. NSDictionary looks like a specialized newtonscrript frame since it restricts values to certain kinds.
The following hard spots became easy when I had thrashed :
Mike wrote : "To demonstrate how multi-value objects are used, let's take a closer look at the kABAddressBookProperty, a particularly interesting property since it contains NSDictionary objects rather than simple strings."
Much as an NSMutable array contains NSDictionary objects in the article on tables.
Mike wrote : "The following list is a list of the keys used to access values in the address dictionaries in the ABMultiValue object for kABAddressProperty."
-
AddressBook in WebObjects
2002-08-29 12:58:18 cpenzini [Reply | View]
Thanks for the article it's realy good.
Does anybody know if it's possible to use the Address Book framework with java in WebObjects 5?
-
Address Book and Security
2002-08-27 22:32:59 jonblock [Reply | View]
While I think the central address book system is a great idea, I'm more than a bit concerned about the potential security implications.
You've just shown how easy it is to write an application that can read the entire address book and a) send it to an unauthorized third party, b) use it to spam/infect every contact in the list, and/or c) trash it, either subtly or obviously.
All it would take is for some malicious author (or some well-known companies who follow the software-as-market-research-tool philosophy) to distribute a program with a cute front-end hiding unfriendly address book manipulations, and bingo, instant virus (or worm, or whatever).
Of course, this would become a major worm candidate if Mail.app, or one of the other mass-market OS X mail clients, could be tricked into auto-launching an application attached to an e-mail.
I guess what I'd like to hear is that each application attempting to access the address book must be pre-authorized by an Administrator account, or else authorized on the fly by the current user (perhaps using the Keychain model). Unfortunately, it doesn't appear that this is the case.
Does this concern anyone else? Or have I overlooked an important security measure that everyone else has already noticed? -
Address Book and Security
2002-08-29 05:14:32 senjaz [Reply | View]
You've mentioned it yourself, this is only a problem if an executable could be launched without user interaction from an email.
Since I can't ever imagine Apple being so stupid as to add such abilities to Mail.app as exist in MS Outlook I think we have little to worry about.
The only problem then is tricking users into running such an executable, the I Love You worm on the PC for example. In that case it doesn't matter what Apple do there will always be people foolish enough to run such things. -
Address Book and Security
2002-08-29 10:05:31 jonblock [Reply | View]
I agree that such a malicious program could not become a worm through Mail.app, but Mac users will not necessarily restrict themselves to Apple mail clients. Entourage, Eudora, and others may be a different story. Either way, that only addresses the hostile code's worm potential.
It could still be harmful without being a self-replicating worm. Since (theoretically) all communications-related programs would use this common address book database, an attacker would have a defined target for virtually all possible software combinations on Jaguar machines.
The wetware factor (getting a person to run malicious code) is not as difficult as you might imagine. People launch attachments all the time, without paying attention to whether they're static images, videos, sound files, or actual programs.
In case I wasn't making myself clear about this, I'm not bashing Apple here at all. This has the potential to be a great feature. I'm just advocating that the database be treated like a secure information repository, with at least the ability to require programs to be individually authorized before being given access to it. -
Address Book and Security
2002-09-03 11:27:48 agave [Reply | View]
http://developer.apple.com/techpubs/macosx/AdditionalTechnologies/AddressBook/Concepts/WhatsInAB.html#BAJGJJAH
<blockquote>
The Address Book does not provide any security above what's provided by Mac OS X. Anyone who has read and write access to a user's home folder can also read and write that user's address book. For that reason, the Address Book may not be an appropriate place to store confidential information, such as credit card numbers.
</blockquote>






When creating a NSArray with multiple objects, be sure to terminate it with nil, like so...
allSearchElements = [NSArray arrayWithObjects: firstNameSearch, lastNameSearch, companySearch, nil];
Also when defining the search elements, kABAndSearch doesn't seem to be correct from the AddressBook documentation. It should be kABSearchAnd or kABSearchOr.
Hope this helps.