2009-05-21 16:42:03 Testing arrayByApplyingSelector:
Code to point out how arrayByApplyingSelector: grabs often inappropriate values from SBElementArrays, since it ignores nil values and appends multiple return values into a single, compact array. I know the -get method is then available to force the appropriate behavior, but I can't imagine why this isn't the default.

This is just some down-n-dirty code to display the differences in output from what one might expect. Within the first ten people, I have a few cases of people having multiple addresses, so that's why I coded the 10 item lookup limit in mine. In your own address book you may have to change the code or temporarily doctor an entry to see the difference.

( objc )
  1  // gcc -std=gnu99 -fobjc-gc-only -o test -framework Foundation -framework AddressBook test.m
2
3 #import <Foundation/Foundation.h>
4 #import <ScriptingBridge/ScriptingBridge.h>
5
6 int main( int argc, const char *argv[] ) {
7 SBApplication *addressBook = [SBApplication applicationWithBundleIdentifier:@"com.apple.AddressBook"];
8 SBElementArray *peeps = [addressBook people];
9 SBElementArray *addresses = [peeps arrayByApplyingSelector:@selector(addresses)];
10 NSArray *getAddresses = [addresses get];
11
12 int numberOfPeopleWithAddresses = 0, totalNumberOfAddresses = 0;
13
14 for( id getArray in getAddresses ) {
15 totalNumberOfAddresses += [getArray count];
16 numberOfPeopleWithAddresses += ([getArray count]>0);
17 }
18
19 printf("\npeople in addressbook: %i\n", [peeps count]);
20 printf("%i addresses found for %i people with addresses listed\n",
21 totalNumberOfAddresses, numberOfPeopleWithAddresses);
22
23 printf("\nFirst 10 streets:\n");
24 for( int i=0; i<10; i++ ) {
25 SBElementArray *address = [addresses objectAtIndex:i];
26 printf("\t%s (%s)\n", [[address street] UTF8String], [[address label] UTF8String]);
27 }
28
29 printf("\nFirst 10 streets using get method also:\n");
30 int countDown = 10, i = 0;
31 while( countDown > 0 ) {
32 for( id a in [getAddresses objectAtIndex:i] ) {
33 id peep = [peeps objectAtIndex:i];
34 printf("\t%s (%s - %s)\n",
35 [[a street] UTF8String], [[peep name] UTF8String], [[a label] UTF8String]);
36 countDown--;
37 }
38 i++;
39 }
40 printf("\n");
41 return 0;
42 }


Note that traversing the getAddresses array forces one to go further than the compact addresses array, since getAddresses may have empty entries, but at least each item will correspond to an item in the peeps array.
Leave a comment