ABAddressBookRef _addressBookRef = ABAddressBookCreate ();
NSArray* allPeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(_addressBookRef);
NSMutableArray* _allItems = [[NSMutableArray alloc] initWithCapacity:[allPeople count]]; // capacity is only a rough guess, but better than nothing
for (id record in allPeople) {
CFTypeRef phoneProperty = ABRecordCopyValue((ABRecordRef)record, kABPersonPhoneProperty);
NSArray *phones = (NSArray *)ABMultiValueCopyArrayOfAllValues(phoneProperty);
CFRelease(phoneProperty);
for (NSString *phone in phones) {
NSString* compositeName = (NSString *)ABRecordCopyCompositeName((ABRecordRef)record);
NSString* field = [NSString stringWithFormat#"%#:%#",compositeName,phone];
[compositeName release];
[_allItems addObject:field];
}
[phoness release];
}
CFRelease(_addressBookRef);
[allPeople release];
allPeople = nil;
Thats my code now i need assistance with what to import && how would i set my UITextView as that
Thanks for any help
This code puts name and phone number in the _allItems array, which you can subsequently use to fill a textview with:
for ( NSString *txt in _allItems )
{
mytextview.text = [mytextview.text stringByAppendingFormat:#"%#\n",txt];
}
assuming you have a UITextView hooked up named mytextview.
Related
I want to show phone contacts along with the pic in table view in alphabetic order.
I have managed to show contact name in correct order but unable to show images in correct order.
I have been trying these for few days but couldn't succeed .
I know how to sort array but don't know how to sort the image data.
please help me guys.
here is my demo code:
NSArray *sortedFirstNames;
- (void)getPersonDetails
{
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (addressBook != nil)
{
NSLog(#"Succesful.");
NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSUInteger i = 0;
NSMutableArray *firstNames = [[NSMutableArray alloc] init];
NSMutableArray *firstimages = [[NSMutableArray alloc] init];
for (i = 0; i < [allContacts count]; i++)
{
Person *person = [[Person alloc] init];
ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
NSString *fullName;
if (lastName == nil)
{
fullName = [NSString stringWithFormat:#"%#", firstName];
[firstNames addObject: fullName];
}
else if(firstName ==nil)
{
fullName = [NSString stringWithFormat:#"%#", lastName];
[firstNames addObject: fullName];
}
else
{
fullName = [NSString stringWithFormat:#"%# %#", firstName, lastName];
[firstNames addObject: fullName];
}
person.firstName = firstName;
person.lastName = lastName;
person.fullName = fullName;
//email
imgdata=(__bridge NSData*)ABPersonCopyImageDataWithFormat(contactPerson, kABPersonImageFormatThumbnail);
NSLog(#"newstris%#",imageStr);
if(imgdata==nil)
{
}
else
{
[firstimages addObject:imgdata];
}
[self.tableData addObject:person];
}
sortedFirstNames = [firstNames sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
CFRelease(addressBook);
}
code for showing images in cell:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
UIImage *image1;
// cell.imageView.frame = CGRectMake(0, 0, 50, 50);
if (person.imgdata==nil) {
image1=[UIImage imageNamed:#"default_profile_pic.jpg"];
}
else
{
image1 = [UIImage imageWithData:person.imgdata];
}
UIImageView *imageView = [[UIImageView alloc] initWithImage:image1];
imageView.frame = CGRectMake(6.5, 6.5, 45., 45.);
dispatch_sync(dispatch_get_main_queue(), ^{
[cell addSubview:imageView];
});
});
Thanks..
Answer is pretty simple.
Add a field in your Person class which stores a NSData.
Like:
#property (nonatomic, strong) NSData *imageData;
And use:
person.imageData = imgdata;
I too faced same issue. I have fixed this issue by associate object like this.
while loading source array:
objc_setAssociatedObject(hDetails, #"imageUrl", record, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
in cell for row at indexpath :
Record *record = objc_getAssociatedObject(hDetails,#"imageUrl");
for more reference see this :
How do I use objc_setAssociatedObject/objc_getAssociatedObject inside an object?
i am having trouble retrieving the last names of my addressbook. I only want to retrieve last names by each letter of the alphabet.
this is the codes i have so far
ABAddressBookRef addressBook = ABAddressBookCreate();
totalPeople = (__bridge_transfer NSMutableArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSString *aString = #"A";
for(int i =0;i<[totalPeople count];i++){
ABRecordRef thisPerson = (__bridge ABRecordRef)
[totalPeople objectAtIndex:i];
lastName = (__bridge_transfer NSString *) ABRecordCopyValue(thisPerson, kABPersonLastNameProperty);
}
I dont know what to do after, thank you for looking at this.
now it is like this
ABAddressBookRef addressBook = ABAddressBookCreate();
totalPeople = (__bridge_transfer NSMutableArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSString *aString = #"A";
for(int i =0;i<[totalPeople count];i++){
ABRecordRef thisPerson = (__bridge ABRecordRef)
[totalPeople objectAtIndex:i];
lastName = (__bridge_transfer NSString *) ABRecordCopyValue(thisPerson, kABPersonLastNameProperty);
NSString *firstLetterOfCopiedName = [lastName substringWithRange: NSMakeRange(0,1)];
if ([firstLetterOfCopiedName compare: aString options: NSCaseInsensitiveSearch] == NSOrderedSame) {
//This person's last name matches the string aString
aArray = [[NSArray alloc]initWithObjects:lastName, nil];
}
}
it onlys adds one name to the array, what should i do in order to add it all.
sorry guys, i am fairly new to ios developing!
You could use something like this and store the result in an array or return the result. (Not tested)
NSString *firstLetterOfCopiedName = [lastName substringWithRange: NSMakeRange(0,1)];
if ([firstLetterOfCopiedName compare: aString options: NSCaseInsensitiveSearch] == NSOrderedSame) {
//This person's last name matches the string aString
}
You need to alloc the array outside the loop (otherwise it will only ever contain one object), the array also has to be an NSMutableArray (so it can be modified). Here is an example:
ABAddressBookRef addressBook = ABAddressBookCreate();
totalPeople = (__bridge_transfer NSMutableArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSString *aString = #"A";
//This is the resulting array
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
for(int i =0;i<[totalPeople count];i++){
ABRecordRef thisPerson = (__bridge ABRecordRef)
[totalPeople objectAtIndex:i];
lastName = (__bridge_transfer NSString *) ABRecordCopyValue(thisPerson, kABPersonLastNameProperty);
NSString *firstLetterOfCopiedName = [lastName substringWithRange: NSMakeRange(0,1)];
if ([firstLetterOfCopiedName compare: aString options: NSCaseInsensitiveSearch] == NSOrderedSame) {
//This person's last name matches the string aString
[resultArray addObject: lastName];
}
}
//print contents of array
for(NSString *lastName in resultArray) {
NSLog(#"Last Name: %#", lastName);
}
when i am analyze my project following code gives me leakage warning. is there any way to solve my memory leakage problem ?
warning :
Potential leak of an object allocated on line 38 and stored into 'addressBook'
Bellow is my code.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
m_tableDataArray = [[[NSMutableArray alloc] init]autorelease];
NSMutableArray *listDate = [[[NSMutableArray alloc] init]autorelease];
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *addresses = (NSArray *) ABAddressBookCopyArrayOfAllPeople(addressBook);
NSInteger addressesCount = [addresses count];
for (int i = 0; i < addressesCount; i++) {
ABRecordRef record = [addresses objectAtIndex:i];
NSString *firstName = (NSString *)ABRecordCopyValue(record, kABPersonFirstNameProperty);
NSString *lastName = (NSString *)ABRecordCopyValue(record, kABPersonLastNameProperty);
if(firstName != nil && lastName != nil){
NSString *contactFirstLast = [NSString stringWithFormat: #"%# %#", firstName, lastName];
[listDate addObject:contactFirstLast];
}
[firstName release];
[lastName release];
}
m_tableDataArray = [[NSArray arrayWithArray:listDate] retain];
[addresses release];
addresses = nil;
[m_mainTable reloadData];
}
Thanks in adv...
Once you have finished using addressBook you need to release it using:
CFRelease(addressBook);
This should probably be placed at the end of your viewWillAppear: method.
Updated: There are a few unnecessary arrays and steps in your version of viewWillAppear:. I have cleaned it up a bit and fixed a potential memory leak.
Note: I haven't actually run this so double-check that it works correctly.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// I assume m_tableDataArray is an instance variable. If so, if the
// view appears multiple times it will result in a leak unless we
// release pre-existing instances first.
[m_tableDataArray release], m_tableDataArray = nil;
m_tableDataArray = [[NSMutableArray alloc] init];
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *addresses = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
for (ABRecordRef record in addresses) {
NSString *firstName = (NSString *)ABRecordCopyValue(record, kABPersonFirstNameProperty);
NSString *lastName = (NSString *)ABRecordCopyValue(record, kABPersonLastNameProperty);
if(firstName != nil && lastName != nil){
NSString *contactFirstLast = [NSString stringWithFormat: #"%# %#", firstName, lastName];
[m_tableDataArray addObject:contactFirstLast];
}
[firstName release];
[lastName release];
}
[addresses release], addresses = nil;
CFRelease(addressBook);
[m_mainTable reloadData];
}
I want to make an app and want to access the contact numbers directly when i touch/press a particular text field or button and then return to my app with a selected contact number. How can i do this.
You need to add ABPeoplePickerNavigationControllerDelegate delegate in .h file
and in .m file write down below three methods:
#pragma mark People Picker Delegate Methods
- (void)peoplePickerNavigationControllerDidCancel:
(ABPeoplePickerNavigationController *)peoplePicker {
[peoplePicker dismissModalViewControllerAnimated:YES];
[peoplePicker autorelease];
}
- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
return YES;
}
- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)valueID{
ABPropertyType type = ABPersonGetTypeOfProperty(property);
if (type==kABMultiDictionaryPropertyType) {
ABMutableMultiValueRef multi = ABRecordCopyValue(person, property);
CFIndex index = ABMultiValueGetIndexForIdentifier(multi, valueID);
CFDictionaryRef dic = ABMultiValueCopyValueAtIndex(multi, index);
CFStringRef street = CFDictionaryGetValue(dic, kABPersonAddressStreetKey);
NSString* StreetName =(NSString*)street;
streetNameText.text=StreetName;
NSLog(#"StreetName:%#",StreetName);
NSRange range = NSMakeRange (0, 5);
NSLog (#"Beer shortname: %#", [StreetName substringWithRange:range]);
int val = [StreetName intValue];
NSLog(#"StreetName:%d",val);
NSString *newChange = [[NSString alloc] initWithFormat:#"%d", val];
streetNOText.text = newChange;
[newChange release];
CFRelease(dic);
CFRelease(multi);
}
[self dismissModalViewControllerAnimated:YES];
return NO;
}
I am not able to give you the whole code. Following bare the steps :
1. On click to button go to new view which must have tableview
2. In that view get the address book
To get the addressbook
Add these frameworks:
AddressBook,
AddressBookUI
import them in your view
And for getting the contacts from addressbook refer the following tutorial
http://developer.apple.com/library/ios/#documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Chapters/QuickStart.html#//apple_ref/doc/uid/TP40007744-CH2-SW1
I know this is not the full solution for your question but this link will help you to get the remaining task...Good luck
May this method will help you, just call this method when you want to fetch records from addressbook. n ofcourse add the frameworks AddressBook, AddressBookUI
first create database (as i did if you want you can store it into NSMutable Array instead of database, as per your requirement.)
-(void)fetchRecordsFromAddressBook
{
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
//NSArray *addresses = (NSArray *) ABAddressBookCopyArrayOfAllPeople(addressBook);
// [arrayContacts removeAllObjects];
[self emptyDataContext];
for (int i = 0; i < nPeople; i++)
{
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
////////////////// get first name ///////////////////
CFStringRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
CFStringRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
CFStringRef nickName = ABRecordCopyValue(ref, kABPersonNicknameProperty);
CFStringRef middleName = ABRecordCopyValue(ref, kABPersonMiddleNameProperty);
////////////////// get image ///////////////////
// ABMultiValueRef ContactImage = (ABMultiValueRef) ABRecordCopyValue(ref,kABPersonImageFormatThumbnail);
NSData *data=nil;
// NSLog(#"Image Testing is : %#",ref);
if(ABPersonHasImageData(ref))
{
data = [(NSData *) ABPersonCopyImageData(ref) autorelease];
if(data)
{
// NSLog(#"Im Testing is : %#",data);
//image = [[UIImage alloc] initWithData:data];
}
}
// NSLog(#"Image is : %#",ContactImage);
// NSLog(#" Name is : %#",firstName);
////////////////// get email ///////////////////
ABMultiValueRef emails = (ABMultiValueRef) ABRecordCopyValue(ref, kABPersonEmailProperty);
NSString *emailID=#"";
if(ABMultiValueGetCount(emails)>=1)
{
emailID = (NSString *)ABMultiValueCopyValueAtIndex(emails,0);
}
////////////////// get phone number ///////////////////
ABMultiValueRef phones = (ABMultiValueRef) ABRecordCopyValue(ref, kABPersonPhoneProperty);
NSString *phone=#"";
NSString *homeNumber = #"";
NSString *worknumber = #"";
if(ABMultiValueGetCount(phones)>=1)
{
//int ph = [ABMultiValueCopyValueAtIndex(phones, 0) intValue];
phone = (NSString *)ABMultiValueCopyValueAtIndex(phones,0);
}
// NSLog(#"%#",(NSString*)phone);
if(ABMultiValueGetCount(phones)>=2)
{
homeNumber = (NSString *)ABMultiValueCopyValueAtIndex(phones,1);
}
if(ABMultiValueGetCount(phones)>=3)
{
worknumber = (NSString *)ABMultiValueCopyValueAtIndex(phones,2);
}
NSMutableArray *arrayContacts = [[NSMutableArray alloc] init ];
///////////////////////////// insert into array ////////////////////////////
arrayContacts = [CoreDataAPIMethods getObjectsFromContext:#"AllContactData" :#"Index" :NO :self.managedObjectContext];
//////////////////////////// insert Index ///////////////////////////////
int NewEntryID;
if ([arrayContacts count] > 0)
{
AllContactData * Contacdata = [arrayContacts objectAtIndex:0];
NewEntryID = [Contacdata.Index intValue] +1;
}
else
{
NewEntryID = 1;
}
NSString *capitalisedSentence =
[(NSString *)firstName stringByReplacingCharactersInRange:NSMakeRange(0,1)
withString:[[(NSString *)firstName substringToIndex:1] capitalizedString]];
AllContactData *Contactitem=(AllContactData *)[NSEntityDescription insertNewObjectForEntityForName:#"AllContactData" inManagedObjectContext:self.managedObjectContext];
// NSLog(#"%#",capitalisedSentence);
Contactitem.Name = capitalisedSentence;
Contactitem.LastName = (NSString*)lastName;
Contactitem.NickName = (NSString*)nickName;
Contactitem.MiddleName = (NSString*)middleName;
Contactitem.Email=(NSString*)emailID;
phone = [phone stringByReplacingOccurrencesOfString:#"(" withString:#""];
phone = [phone stringByReplacingOccurrencesOfString:#")" withString:#""];
phone = [phone stringByReplacingOccurrencesOfString:#"+" withString:#""];
phone = [phone stringByReplacingOccurrencesOfString:#" " withString:#""];
phone = [phone stringByReplacingOccurrencesOfString:#"-" withString:#""];
NSLog(#"The Replaced String is : %#", phone);
Contactitem.PhoneNumber=(NSString*)phone;
Contactitem.HomeNumber=(NSString*)homeNumber;
Contactitem.WorkNumber=(NSString*)worknumber;
Contactitem.Index = [NSNumber numberWithInt:NewEntryID];
Contactitem.Image = data;
// NSLog(#"Image in databse is : %#",(NSData *)ContactImage);
if(firstName!=nil)
{
CFRelease(firstName);
}
CFRelease(ref);
}
CFRelease(allPeople);
///////////////////////////// save entries ////////////////////////////
NSError *error;
if (![managedObjectContext save:&error]) {
// Handle the error...
}
}
I'm still trying to wrap my head around using NSDictionaries, and have come into a situation where I believe I need to use one. essentially, I would like to store all the phone numbers associated with each contact into a dictionary. so far I have this:
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *thePeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
for (id person in thePeople)
{
ABMultiValueRef phones =(NSString*)ABRecordCopyValue(person, kABPersonPhoneProperty);
NSString* name = (NSString *)ABRecordCopyCompositeName(person);
for (CFIndex i = 0; i < ABMultiValueGetCount(phones); i++)
{
NSString *phone = [(NSString *)ABMultiValueCopyValueAtIndex(phones,i) autorelease];
}
}
I was wondering how to use a nsdictionary to store each person, and then an array of each phone value that's associated with that person.
What are you trying to do?
You can put all names and phonenumbers into a plist like this:
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *thePeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSMutableArray* allPeoplesDicts = [NSMutableArray array];
for (id person in thePeople)
{
ABMultiValueRef phones =(NSString*)ABRecordCopyValue(person, kABPersonPhoneProperty);
NSString* name = (NSString *)ABRecordCopyCompositeName(person);
NSMutableArray* phones = [[NSMutableArray alloc] init];
for (CFIndex i = 0; i < ABMultiValueGetCount(phones); i++)
{
NSString *phone = [(NSString *)ABMultiValueCopyValueAtIndex(phones,i) autorelease];
[phones addObject:phone];
}
NSDictionary* personDict = [[NSDictionary alloc] initWithObjectsAndKeys:name,#"Name",phones,#"PhoneNumbers",nil];
[phones release];
[allPeoplesDicts addObject:personDict];
[personDict release];
}