Setting person properties - iphone

Working on someone else's code. I am really confused about whats exactly happening in this code.
ABAddressBookRef addressBook = ABAddressBookCreate();
ABRecordRef persons = ABAddressBookGetPersonWithRecordID(addressBook, x);
CFErrorRef *error=NULL;
ABAddressBookRemoveRecord(addressBook, persons, error);
ABAddressBookSave(addressBook, error);
ABRecordRef persons = ABPersonCreate();
ABRecordSetValue(persons, kABPersonFirstNameProperty, firstName , nil);
What should be done is that, a ABRecordRef person should be created. His properties should be set and his record/details should be displayed. He should never be saved in the address book. Is this the way to do it. Need help.
Edit: Apart from setting properties to person, the following code is added to push the view controller to view the person.
MyContactDetailViewcontroller *personContactDetail = [[MyContactDetailViewcontroller alloc] init];
personContactDetail.displayedPerson = persons;
personContactDetail.passedSelectedContactData = selectedContactsOnlyData;
[self.navigationController pushViewController:personContactDetail animated:YES];
[personContactDetail release];
MyContactDetailViewcontroller subclass ABPersonViewController. Or is it more apt to use ABUnknownPersonViewController.
Do you find any cases where the contacts could be duplicated in address book

This is exactly what is happening here.. I will explain..
ABAddressBookCreate creates a new address book from data from the addressbook database, so any changes you make to ABAddressBookRef will only be saved to actual addressbook database once you call ABAddressBookSave(). so what it is doing is getting the reference for the person with recordid- x. Than you are creating a new person entry using
ABRecordRef persons = ABPersonCreate();
and than you are setting its value, but this is available to this particular object and not stored in the database unless you call... ABAddressBookSave()
hoping this helps you... :)

Related

potential leak of an object stored into address book

I got issue potential leak of an object stored into address book, how to resolve it.
I create address book locally and then copyArrayofAllpeople to people1 array. people1 array used outside of method. So where should I release addressbookref. Please make suggestions.
This is my code
ABAddressBookRef addressBook = ABAddressBookCreate();
people1 = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
Use CFRelease() method.
ABAddressBookRef addressBook = ABAddressBookCreate();
people1 = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
CFRelease(addressBook);
I think it will be helpful to you.

contact notes are not transferred when exporting/importing via the built-in vCard representation methods

Using the ABPersonCreateVCardRepresentationWithPeople method for export, and the ABPersonCreatePeopleInSourceWithVCardRepresentation for import, I have successfully transfered contact data between devices. However, the data in the contact's "notes" field isn't transfered.
Here's my export function:
+(NSData*)exportContactsToVcard:(NSArray*)contacts
{
NSMutableArray *people = [NSMutableArray arrayWithCapacity:contacts.count];
ABAddressBookRef ab = ABAddressBookCreate();
for (Contact *contact in contacts)
{
ABRecordRef person = ABAddressBookGetPersonWithRecordID(ab,contact.contactId);
[people addObject:(__bridge id)person];
}
NSData *vCard = (__bridge NSData*)ABPersonCreateVCardRepresentationWithPeople((__bridge CFArrayRef) people);
return vCard;
}
and part of my import function:
+(NSArray*)importContactsFromVcardData:(NSData*)vcardData
{
NSMutableArray *addedContactIds = [NSMutableArray array];
ABAddressBookRef addressBook = ABAddressBookCreate();
ABRecordRef defaultSource = ABAddressBookCopyDefaultSource(addressBook);
NSArray *createdPeople = (__bridge_transfer NSArray*)ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource,(__bridge CFDataRef)vcardData);
CFErrorRef error = NULL;
for (id person in createdPeople)
{
error = NULL;
ABRecordRef personRecord = (__bridge ABRecordRef)person;
NSString *notes = (__bridge NSString *)ABRecordCopyValue(personRecord, kABPersonNoteProperty);
In the last line, notes is always nil, even if the contact had notes before it was exported. All the other standard contact fields seem to be in place.
For example, if I replace the last line with:
NSString *firstName = (__bridge NSString *)ABRecordCopyValue(personRecord, kABPersonFirstNameProperty);
the firstName string will hold the contact's first name.
Any idea how I can work around this, and get the contact notes?
Thanks.
For testing purposes, you can export a vCard from Address Book. Then drag it to TextEdit to look at the various fields.
At the bottom you'll find something like this:
NOTE:This is a note!
Also, see this link for info on the vCard format:
http://en.wikipedia.org/wiki/VCard
ABPersonCreateVCardRepresentationWithPeople will only transfer the important contact details of a vCard...thats my identifying in much tests with the vCard and the iOS import-export function. It has many mistakes, e.g. if you try to import it with social networks like facebook, it won't do it with (just look in my other thread THREADLINK )
But if you try to add some vCard Information over ABNewPersonViewController, it will work perfectly.

EXC_BAD_ACCESS when add vCard data to AddressBook

I follow this instruction to add vcard data to addressbook, in my project. iOS 5.
Adding vCard data directly to the system Address Book
The code run ok, and add vcard data to adressbook in my ipad2 and iphone4s, however, xcode show this error:
thread 1 program received signal: "exc_bad_acess"
Why this error appears?
EDIT: code add.
NSString *vCardString =
#"BEGIN:VCARD\n"
#"N:Paulo;Joao\n"
#"TEL:+44 (0)9999 8888\n"
#"ADR;HOME:;;Flat 2, 43 Howitt Road, Belsize Park;London;;NW34LU;UK\n"
#"ORG:NetTek Ltd;\n"
#"TITLE:Consultant\n"
#"EMAIL:none#none.com\n"
#"URL:www.none.com\n"
#"BDAY:19001010\n"
#"END:VCARD";
CFDataRef vCardData = (__bridge CFDataRef)[vCardString dataUsingEncoding:NSUTF8StringEncoding];
ABAddressBookRef book = ABAddressBookCreate();
ABRecordRef defaultSource = ABAddressBookCopyDefaultSource(book);
CFArrayRef vCardPeople = ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource, vCardData);
for (CFIndex index = 0; index < CFArrayGetCount(vCardPeople); index++)
{
ABRecordRef person = CFArrayGetValueAtIndex(vCardPeople, index);
ABAddressBookAddRecord(book, person, NULL);
CFRelease(person);
}
CFRelease(vCardPeople);
CFRelease(defaultSource);
ABAddressBookSave(book, NULL);
CFRelease(book);
I found the problem.
The problem is with the last line, probably because of ARC.
CFRelease(book);
I commented the line, and the program run normally.
I'm glad you were able to find the problem, however, I just thought I'd let you know that it's not an ARC thing but a memory leak thing. You're over-releasing data the the OS wants to release itself. Here's an explanation.
Additionally, please mark the question as answered so you can help other people find the solution. Thank you!

Custom addressbook for ABPeoplePickerNavigationController on iPhone

I am trying to create a custom addressbook on the iPhone by adding new records to the device address book (basically, merging a private contact list with the device AB). I then want to let the user select a contact, which I thought I could do with the .addressbook property of ABPeoplePickerNavigationController:
ABAddressBookRef contacts = ABAddressBookCreate();
for (PrivateUserType *user in rosterItems)
{
CFErrorRef err = NULL;
ABRecordRef ref = ABPersonCreate();
ABRecordSetValue(ref, kABPersonLastNameProperty, (CFStringRef)user.lastName, &err);
if (err != NULL)
{
NSString *errorStr = [(NSString *)CFErrorCopyDescription(err) autorelease];
NSLog(#"Can not set name: %#", errorStr);
}
...
ABAddressBookAddRecord(contacts, ref, &err);
if (err != NULL)
{
NSString *errorStr = [(NSString *)CFErrorCopyDescription(err) autorelease];
NSLog(#"Error adding XMPP roster user to addressbook: %#", errorStr);
}
}
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.addressBook = contacts;
[viewController presentModalViewController:picker animated:YES];
[picker release];
The entries are successfully added to the addressbook (which I can verify if I do an ABAddressBookSave() after the loop to add everything in). However, the entries are not shown by picker (unless I save contacts, which of course saves all changes into the device addressbook).
Is there a way to do this? This is on iOS 4.3.1.
Thanks!
As Toro said, you need save any changes to database first. ABPeoplePickerNavigationController not intended to work with uncommit data or with custom data.
You can see rather fresh topic on Apple Dev Forums
https://devforums.apple.com/message/370070#370070
where similar question was asked. And guy from Apple says that "I can't see any way to do this." But he suggest filling a bug for this to implement this feature in future release of iOS.
All you can do now is code your own UI for this AddressBook from the ground :(
updated: he-he. I found your question on App Dev Forum too )))
You need to save any changes to database by ABAddressBookSave() method.
The apple doc link.

programmatically adding contact in iphone contact list

I want to programmatically add contact to iphone contact list without using ABNewPersonViewController. I would simply like to pass parameters and want the ABRecordRef as result. Is this possible?
ABGroupAddMember (group, contact, nil) ;
ABAddressBookSave(inAddressBook, nil) ;
After adding the contact save the address book.
bool ABAddressBookAddRecord (
ABAddressBookRef addressBook,
ABRecordRef record,
CFErrorRef *error
);
https://developer.apple.com/documentation/addressbook