Go Back   MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Mar 7, 2008, 11:28 PM   #1
jhershauer
macrumors member
 
Join Date: Feb 2003
Location: Gilbert, AZ
Accessing Address Book in iPhone SDK?

Hi,
I've created a simple list application, starting out with a custom datasource class that simply returns a hard-wired list of data. With that working, I'm now attempting to alter my datasource class to pull data from the address book. I've added a reference to AddressBook/ABAddressBook.h and created an ABAddressBookRef variable. The application compiles fine with that, and I'm able to get Code Sense into the ABAddressBook API. However, if I attempt to initialize my ABAddressBookRef variable by calling ABAddressBookCreate(), I get a link error like this:

"_ABAddressBookCreate", referenced from:
-[TestTableDataSource init] in TestTableDataSource.o
symbol(s) not found
collect2: id returned 1 exit status

I'm new to this environment, so there may be something obvious I'm missing here in terms of setting this up. Has anybody successfully initialized/accessed the Address Book API with the iPhone SDK yet? Any quick samples of how to get the ball rolling with that API?

Thanks,
Jeff
__________________
Yet another MacRumors Team Folding member
jhershauer is offline   0 Reply With Quote
Old Mar 7, 2008, 11:33 PM   #2
kainjow
Moderator emeritus
 
kainjow's Avatar
 
Join Date: Jun 2000
Did you link in the entire framework?
kainjow is offline   0 Reply With Quote
Old Mar 7, 2008, 11:52 PM   #3
jhershauer
Thread Starter
macrumors member
 
Join Date: Feb 2003
Location: Gilbert, AZ
Quote:
Originally Posted by kainjow View Post
Did you link in the entire framework?
Wow...quick response! I was just coming back to answer myself. No, I hadn't linked in that framework. I was just poking around and noticed the "Linked Frameworks" node in the Groups and Files pane. All is well now.

Thanks!

Jeff
__________________
Yet another MacRumors Team Folding member
jhershauer is offline   0 Reply With Quote
Old Mar 8, 2008, 12:46 PM   #4
jhershauer
Thread Starter
macrumors member
 
Join Date: Feb 2003
Location: Gilbert, AZ
Follow-up question

OK, I've got a follow-up question that's more of a beginner Objective-C question:

I wanted to create a couple of class-level variables ("ivars" I suppose they're called). One would be a pointer to the AddressBook itself, and the other would point to the array of all people in the Address Book (NSArray *). This was so I wouldn't have to keep re-getting these things in the other methods of my class.

I was looking for the equivalent of a "constructor" in Objective-C and found the -init() method, so I overrode that as follows:

Code:
-(id)init
{
	self = [super init];
	addressBook = <SDKMehtodToGetAddressBook>();
	allPeople = (NSArray *)<SDKMethodToGetArrayOfPeople>(addressBook);
	return self;
}
This didn't work. When I got into my other methods, addressBook and allPeople were always nil. I got around this by turning addressBook and allPeople into properties, and implementing getters like this:


Code:
- (<SDKTypeThatReferencesAnAddressBook>)_getAddressBook {
	if (nil == addressBook)
	{
		addressBook = <SDKMethodToReturnAnAddressBook>();
	}
	return addressBook;
}
- (NSArray *)_getAllPeople {
	if (nil == allPeople)
	{
		allPeople = (NSArray *)<SDKMethodToGetArrayOfPeople>(self.addressBook);
	}
	return allPeople;
}

This works fine, and my application is happily running in the simulator, returning a list of people from the address book. However, I'm curious as to why the assignments to the allPeople and addressBook variables didn't "stick" when I tried to do it through the init method. I've done some google searching, and that seems like it's supposed to be the appropriate place to initialize ivars for the class. Any insight would be appreciated.


Here's the interface for my class:

Code:
#import <SDK UI Kit>
#import <SDK Address Book>


@interface TestTableDataSource : NSObject <UITableViewDataSource, UITableViewDelegate> {
<SDKAddressBookReferenceType> addressBook;
NSArray *allPeople;
}

@property (getter=_getAddressBook,assign) <SDKTypeThatReferencesAnAddressBook> addressBook;
@property (getter=_getAllPeople,assign) NSArray *allPeople;
- (NSString *)stringValueForRow:(NSInteger)row;

@end
Thanks,
Jeff

[Edit]: Hmm...I see other references to NDA, and although this thing is publicly available now, I know I agreed to something (didn't actually read it) when I downloaded the SDK, so I've gone back and attempted to kind of obfuscate the code so as not to give any SDK "secrets" away. :-)
__________________
Yet another MacRumors Team Folding member

Last edited by jhershauer; Mar 8, 2008 at 02:07 PM. Reason: Hiding specifics of the iPhone SDK (just in case)
jhershauer is offline   0 Reply With Quote
Old Mar 8, 2008, 12:53 PM   #5
kainjow
Moderator emeritus
 
kainjow's Avatar
 
Join Date: Jun 2000
Your init method may not be getting called. You can NSLog() it to see if it is.

How is your class being created?
kainjow is offline   0 Reply With Quote
Old Mar 8, 2008, 01:50 PM   #6
jhershauer
Thread Starter
macrumors member
 
Join Date: Feb 2003
Location: Gilbert, AZ
Quote:
Originally Posted by kainjow View Post
Your init method may not be getting called. You can NSLog() it to see if it is.

How is your class being created?
Doh! I feel like an idiot. You're right...the init wasn't being called. I could have sworn I put a breakpoint in my init method to make sure the variables were getting set, but I must not have (taking in a lot of new stuff all at once, and probably getting a bit discombobulated).

Your tip was enough to point me to my problem. I was creating my class instance like this:

Code:
    //Set up data source
    testDs = [TestTableDataSource alloc];
Now I'm creating it like this, and it's working:

Code:
	
    //Set up data source
    testDs = [[TestTableDataSource alloc] init];
I was assuming that simply doing an alloc on the class was the equivalent of doing a New in C#, and thought my init (which I was thinking of as a constructor) would automatically be called.

At least I learned how to create custom property accessors in the process. :-)

Thanks again!

Jeff
__________________
Yet another MacRumors Team Folding member

Last edited by jhershauer; Mar 8, 2008 at 02:05 PM.
jhershauer is offline   0 Reply With Quote
Old Mar 11, 2008, 08:51 PM   #7
nick718
macrumors newbie
 
Join Date: Jul 2007
Hey, I'm trying to do something similar. How did you find usages for the ABAddressBookRef class? I looked at the library ref on the developer center, but it had no example code and nothing about how to create the instance. I feel like I must be missing a large amount of reference documentation somewhere.

Thanks
nick718 is offline   0 Reply With Quote
Old Mar 12, 2008, 01:31 AM   #8
netik
macrumors newbie
 
Join Date: Mar 2008
Quote:
Originally Posted by nick718 View Post
Hey, I'm trying to do something similar. How did you find usages for the ABAddressBookRef class? I looked at the library ref on the developer center, but it had no example code and nothing about how to create the instance. I feel like I must be missing a large amount of reference documentation somewhere.

Thanks
All of the reference documentation is available in the research assistant, and apple has squirreled away tons of example code inside of the documentation bundle. Go to Help, and then "Show research assistant".

Search in the SDK and you should be set.
netik is offline   0 Reply With Quote
Old Mar 12, 2008, 01:32 AM   #9
netik
macrumors newbie
 
Join Date: Mar 2008
Quote:
Originally Posted by jhershauer View Post
Doh! I feel like an idiot. You're right...the init wasn't being called. I could have sworn I put a breakpoint in my init method to make sure the variables were getting set, but I must not have (taking in a lot of new stuff all at once, and probably getting a bit discombobulated).
I have a similar problem to yours, but it seems that the compiler is not finding any of the header files. I have errors like:

Code:
/Users/jna/Documents/Iphone App Dev/WhatHappened/Classes/../RootViewController.m:194: error: 'ABPerson' undeclared (first use in this function)
/Users/jna/Documents/Iphone App Dev/WhatHappened/Classes/../RootViewController.m:194: error: 'aPerson' undeclared (first use in this function)
/Users/jna/Documents/Iphone App Dev/WhatHappened/Classes/../RootViewController.m:194: error: 'ABAddressBook' undeclared (first use in this function)
/Users/jna/Documents/Iphone App Dev/WhatHappened/Classes/../RootViewController.m:195: error: 'ABMutableMultiValue' undeclared (first use in this function)
/Users/jna/Documents/Iphone App Dev/WhatHappened/Classes/../RootViewController.m:195: error: 'anAddressList' undeclared (first use in this function)
/Users/jna/Documents/Iphone App Dev/WhatHappened/Classes/../RootViewController.m:196: error: 'kABAddressProperty' undeclared (first use in this function)
/Users/jna/Documents/Iphone App Dev/WhatHappened/Classes/../RootViewController.m:198: warning: unused variable 'primaryIndex'
and I have certainly put the framework in both the 'link binary with libraries' part of my target, as well as in the 'linked framework' part. What gives?

Why can't it see the header files?!
netik is offline   0 Reply With Quote
Old Mar 12, 2008, 07:46 AM   #10
nick718
macrumors newbie
 
Join Date: Jul 2007
Thanks for the info.

I am still having an issue though. I show the Research Assistant, but mo matter what I click on, even non-iPhone SDK classes, I see nothing in the window. Is there something I'm missing? I tried just putting the cursor over the class name in the code, and also highlighting the name.

Thanks
nick718 is offline   0 Reply With Quote
Old Mar 12, 2008, 09:09 AM   #11
kainjow
Moderator emeritus
 
kainjow's Avatar
 
Join Date: Jun 2000
Quote:
Originally Posted by netik View Post
and I have certainly put the framework in both the 'link binary with libraries' part of my target, as well as in the 'linked framework' part. What gives?

Why can't it see the header files?!
Did you #import <AddressBook/AddressBook.h> ?
kainjow is offline   0 Reply With Quote
Old Mar 12, 2008, 06:35 PM   #12
nick718
macrumors newbie
 
Join Date: Jul 2007
So I've finally managed to get the Research Assistant working, but now I have a new question. This may be a dumb question but, how did you manage to get a list of all the records in the address book? In looking at the doc and the AddressBookh file, I see no functions for just getting a or all of the records.

Thanks!
nick718 is offline   0 Reply With Quote
Old Mar 12, 2008, 07:02 PM   #13
jhershauer
Thread Starter
macrumors member
 
Join Date: Feb 2003
Location: Gilbert, AZ
Quote:
Originally Posted by nick718 View Post
So I've finally managed to get the Research Assistant working, but now I have a new question. This may be a dumb question but, how did you manage to get a list of all the records in the address book? In looking at the doc and the AddressBookh file, I see no functions for just getting a or all of the records.

Thanks!
For that, you'll want to import the ABPerson header file and take a look at the available functions there. I believe it's also documented. There's an ABAddressBookCopyArrayOfAllPeople function that will get you all of the records. You'll need your address book reference as a parameter for the ABPerson functions.

Jeff
__________________
Yet another MacRumors Team Folding member
jhershauer is offline   0 Reply With Quote
Old Mar 12, 2008, 08:43 PM   #14
nick718
macrumors newbie
 
Join Date: Jul 2007
Awesome, thanks so much!

One more question to anybody who can answer. Am I missing something here, or are all the AddressBook libraries standard C libraries? I'm finding myself relying on all of these C functions that are passed object references and parameters, it seems to defeat the idea of using Objective C as an OO language for the SDK. Are there some sort of OC wrappers for all this functionality? Or are some of the APIs just standard C, no if an or buts?

Thanks,
Nick
nick718 is offline   0 Reply With Quote
Old Mar 13, 2008, 03:37 AM   #15
netik
macrumors newbie
 
Join Date: Mar 2008
Quote:
Originally Posted by kainjow View Post
Did you #import <AddressBook/AddressBook.h> ?
Ahh, it was getting the headers but I was used to addressbook in cocoa and accessing it the wrong way.

The iPhone SDK is a bit different, so, to open the address book and get the contacts, it looks something like this:

Code:
// open the default address book. 
	ABAddressBookRef m_addressbook = ABAddressBookCreate();
    if (!m_addressbook) {
        NSLog(@"opening address book");
    }
	
	// can be cast to NSArray, toll-free
	CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(m_addressbook);
	CFIndex nPeople = ABAddressBookGetPersonCount(m_addressbook);

	// CFStrings can be cast to NSString!

	for (int i=0;i < nPeople;i++) { 
		ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);
		... do something with ABRecordRef...
	}

	[region release];
netik is offline   0 Reply With Quote
Old Mar 13, 2008, 03:39 AM   #16
netik
macrumors newbie
 
Join Date: Mar 2008
Quote:
Originally Posted by jhershauer View Post
For that, you'll want to import the ABPerson header file and take a look at the available functions there. I believe it's also documented. There's an ABAddressBookCopyArrayOfAllPeople function that will get you all of the records. You'll need your address book reference as a parameter for the ABPerson functions.

Jeff
Importing <AddressBook/AddressBook.h> all of the other header files for you. You shouldn't import ABPerson.h directly.
netik is offline   0 Reply With Quote
Old Mar 13, 2008, 07:26 AM   #17
nick718
macrumors newbie
 
Join Date: Jul 2007
Quote:
Originally Posted by netik View Post
Ahh, it was getting the headers but I was used to addressbook in cocoa and accessing it the wrong way.

The iPhone SDK is a bit different, so, to open the address book and get the contacts, it looks something like this:

Code:
// open the default address book. 
	ABAddressBookRef m_addressbook = ABAddressBookCreate();
    if (!m_addressbook) {
        NSLog(@"opening address book");
    }
	
	// can be cast to NSArray, toll-free
	CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(m_addressbook);
	CFIndex nPeople = ABAddressBookGetPersonCount(m_addressbook);

	// CFStrings can be cast to NSString!

	for (int i=0;i < nPeople;i++) { 
		ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);
		... do something with ABRecordRef...
	}

	[region release];
Reassuring to see that, it's almost exactly what I have. Thanks for the tip on the casting though, I didn't realize those foundations classes could be cast into NS classes that easily.

Do you know how I could go about getting which indexes are for which Record properties? It seems like there should be a list somewhere, but I could not find one.
Thanks
nick718 is offline   0 Reply With Quote
Old Mar 13, 2008, 02:18 PM   #18
drivefast
macrumors regular
 
Join Date: Mar 2008
Quote:
Originally Posted by nick718 View Post
Do you know how I could go about getting which indexes are for which Record properties? It seems like there should be a list somewhere, but I could not find one.
i think youre talking about how to get the values in the database fields...? something like this?
PHP Code:
NSString *contactFirstLast = [NSString stringWithFormat:@"%@,%@"
  
ABRecordCopyValue(refkABPersonFirstNameProperty), 
  
ABRecordCopyValue(refkABPersonLastNameProperty)
]; 
the kABPersonBlahBlahProperty constants (or enums, i forgot what they are) are decribed in the ABPerson documentation pages. it's a little more difficult to get a hold of the multivalues, like addresses and phone numbers, ive got something working if you need it, but i feel it's not as nice as it could be.
drivefast is offline   0 Reply With Quote
Old Mar 13, 2008, 02:29 PM   #19
kainjow
Moderator emeritus
 
kainjow's Avatar
 
Join Date: Jun 2000
Any values used from ABRecordCopyValue() need to be released when done, so that code above is leaking memory, and if you use that in a loop with every contact, that'd be a lot of memory to leak.

It should probably be something like this:

Code:
CFStringRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
CFStringRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
NSString *contactFirstLast = [NSString stringWithFormat:@"%@,%@",
    firstName, lastName];
CFRelease(firstName);
CFRelease(lastName);
kainjow is offline   0 Reply With Quote
Old Mar 13, 2008, 02:55 PM   #20
drivefast
macrumors regular
 
Join Date: Mar 2008
thanks for pointing that out. i should have said that in my previous post - i only started with obj-c a couple of days ago

now anyone has any idea how to get the own phone's phone number?... on the iPhone it shows up on top of the "all contacts" list, but i couldnt find it anywhere in the address book database.
drivefast is offline   0 Reply With Quote
Old Mar 13, 2008, 02:58 PM   #21
gifford
macrumors 6502
 
Join Date: Jun 2007
Location: Miserable England
I have been trundling through the adressbook iphone framework all day looking for ways to receive "missed call" events, are an array of missed calls, or any info to do with missed calls.

Has anyone spotted any info on this anywhere?
__________________
WANTED: ADBE tried for crimes against humanity.
gifford is offline   0 Reply With Quote
Old Mar 14, 2008, 03:34 AM   #22
netik
macrumors newbie
 
Join Date: Mar 2008
Quote:
Originally Posted by kainjow View Post
Any values used from ABRecordCopyValue() need to be released when done, so that code above is leaking memory, and if you use that in a loop with every contact, that'd be a lot of memory to leak.

It should probably be something like this:

Code:
CFStringRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
CFStringRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
NSString *contactFirstLast = [NSString stringWithFormat:@"%@,%@",
    firstName, lastName];
CFRelease(firstName);
CFRelease(lastName);
I really don't have my head completely around references and what needs to be released and what doesn't yet.

I don't understand how you can copy something into a reference, and then release it, and still be able to use it. Got a reference for this that I can read?
netik is offline   0 Reply With Quote
Old Mar 14, 2008, 03:37 AM   #23
netik
macrumors newbie
 
Join Date: Mar 2008
Quote:
Originally Posted by gifford View Post
I have been trundling through the adressbook iphone framework all day looking for ways to receive "missed call" events, are an array of missed calls, or any info to do with missed calls.

Has anyone spotted any info on this anywhere?
I don't think you're going to get that from the address book.

There's no section of the SDK that I can find to get to call, calendar, or voice mail data, so I guess that's not available just yet. Maybe there's an NSDictionary someplace with this?
netik is offline   0 Reply With Quote
Old Mar 14, 2008, 05:19 AM   #24
gifford
macrumors 6502
 
Join Date: Jun 2007
Location: Miserable England
Quote:
Originally Posted by netik View Post
I don't think you're going to get that from the address book.

There's no section of the SDK that I can find to get to call, calendar, or voice mail data, so I guess that's not available just yet. Maybe there's an NSDictionary someplace with this?
I was told by one of the guy's from Apple that address book was where to look. So I kept on looking, and looking, and looking, and now I have given up.

I will have to wait I suppose, the application I want it for has already been put off for 3 years in anticipation of the iphone (and lack of patience to learn any other inevitably doomed mobile platform) so whats another couple of years gona make!
__________________
WANTED: ADBE tried for crimes against humanity.
gifford is offline   0 Reply With Quote
Old Mar 14, 2008, 09:40 AM   #25
kainjow
Moderator emeritus
 
kainjow's Avatar
 
Join Date: Jun 2000
Quote:
Originally Posted by netik View Post
I really don't have my head completely around references and what needs to be released and what doesn't yet.

I don't understand how you can copy something into a reference, and then release it, and still be able to use it. Got a reference for this that I can read?
Read up on memory management: http://developer.apple.com/documenta...emoryMgmt.html
kainjow is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Why can't you add an email address to your account's address book in the mail app? TH55 iPhone 30 Jan 15, 2014 12:10 PM
iPhone syncing contacts to Address Book DominusNovus iPhone 0 Jan 3, 2013 12:34 PM
How to access Yahoo address book from Mac Address Book app or Mac Mail...? rhimbo Mac Basics and Help 0 Oct 12, 2012 04:07 PM
Syncing Address Book with iCloud/ iPhone ParryD MacBook Pro 0 Aug 18, 2012 03:52 AM
iPhone 4 contacts not syncing with Address Book Oktober iPhone 1 Aug 2, 2012 03:57 AM

Forum Jump

All times are GMT -5. The time now is 12:44 PM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC