Need only phone number from default contact - iphone

I'm opening a default address book contact in my app, but it's opening all the detail of the contact. I only want the phone number, not the other details. How do I do this?
Below is the code I use.
ABPersonViewController *personController = [[ABPersonViewController alloc] init];
personController.personViewDelegate = self;
personController.allowsEditing = NO;
personController.displayedPerson = person;
personController.addressBook = ABAddressBookCreate();
personController.displayedProperties = [NSArray arrayWithObjects: [NSNumber numberWithInt:kABPersonPhoneProperty], nil];
[[self navigationController] pushViewController:personController animated:YES];

ABContact *contact = [collection objectAtIndex:indexPath.row];
cell.textLabel.text = contact.contactName;
cell.detailTextLabel.text=contact.phonenumbers;
i used abcontactshelper class for this.

Related

Memory management advice - how to handle Zombies?

In the below sample code, I am a bit lost as to why I am getting a NZombie on the line:
[Category getInitialDataToDisplay:[self getDBPath]];
I have looked through SO posts and other documentation but am new to objective-c and am spinning my wheels on this.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
//Copy database to the user's phone if needed.
[self copyDatabaseIfNeeded];
// Init the Array
activeCategories = [[NSMutableArray alloc] init];
activeSubjects = [[NSMutableArray alloc] init];
categories = [[NSMutableArray alloc] init];
subjects = [[NSMutableArray alloc] init];
quotes = [[NSMutableArray alloc] init];
quoteMaps = [[NSMutableArray alloc] init];
//Initialize the Category array.
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
self.categories = tempArray;
[tempArray release];
//Once the db is copied, get the initial data to display on the screen.
[Category getInitialDataToDisplay:[self getDBPath]];
//populate active subjects and categories:
activeCategories = [self getActiveCategories];
activeSubjects = [self getActiveSubjects];
// sort data
NSSortDescriptor *categorySorter;
NSSortDescriptor *subjectSorter;
categorySorter = [[NSSortDescriptor alloc]initWithKey:#"category_title" ascending:YES];
subjectSorter = [[NSSortDescriptor alloc]initWithKey:#"title" ascending:YES];
NSArray *sortDescriptorsCat = [NSArray arrayWithObject:categorySorter];
NSArray *sortDescriptorsSub = [NSArray arrayWithObject:subjectSorter];
[self.categories sortUsingDescriptors:sortDescriptorsCat];
[self.subjects sortUsingDescriptors:sortDescriptorsSub];
[categorySorter release];
[subjectSorter release];
// Configure and show the window
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}
...
- (void)dealloc {
[activeSubjects release];
[activeCategories release];
[categories autorelease];
[subjects autorelease];
[quotes autorelease];
[quoteMaps autorelease];
[navigationController release];
[window release];
[super dealloc];
}
Here is the getInitialDataToDisplay:
+ (void) getInitialDataToDisplay:(NSString *)dbPath {
// Use this section to bring in database and populate the array
FMDatabase *database = [FMDatabase databaseWithPath:dbPath];
[database open];
QuotesAppDelegate *appDelegate = (QuotesAppDelegate *)[[UIApplication sharedApplication] delegate];
//appDelegate.categories = [appDelegate.categories sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
//POPULATE THE SUBJECT
FMResultSet *result_subjects = [database executeQuery:#"select * from SUBJECT"];
while([result_subjects next]) {
NSInteger primaryKey = [result_subjects intForColumn:#"SUBJECT_ID"];
Subject *sub = [[Subject alloc] initWithPrimaryKey:primaryKey];
sub.title = [result_subjects stringForColumn:#"SUBJECT"];
sub.category_title = [result_subjects stringForColumn:#"CATEGORY"];
sub.active = [result_subjects intForColumn:#"ACTIVE"];
sub.isDirty = NO;
[appDelegate.subjects addObject:sub];
[sub release];
}
FMResultSet *result_categories = [database executeQuery:#"select distinct category from SUBJECT"];
while([result_categories next]) {
Category *cat = [[Category alloc] init];
cat.category_title = [result_categories stringForColumn:#"CATEGORY"];
NSLog(#"loading category: %#", cat.category_title);
QuotesAppDelegate *appDelegate = (QuotesAppDelegate *)[[UIApplication sharedApplication] delegate];
for (Subject *sb in appDelegate.subjects){
if([cat.category_title isEqualToString:sb.category_title]){
[cat.subjects addObject:sb];
NSLog(#" Adding subject: %# cat.subjects.count=%i", sb.title, cat.subjects.count);
}
}
[appDelegate.categories addObject:cat];
[cat release];
}
//POPULATE THE QUOTES
FMResultSet *result_quotes = [database executeQuery:#"select * from QUOTE"];
while([result_quotes next]) {
Quote *sub = [Quote alloc];
sub.quote_id = [result_quotes stringForColumn:#"QUOTE_ID"];
sub.quote_date = [result_quotes stringForColumn:#"DATE"];
sub.title = [result_quotes stringForColumn:#"DESC1"];
sub.desc2 = [result_quotes stringForColumn:#"DESC2"];
sub.excerpt = [result_quotes stringForColumn:#"EXCERPT"];
sub.note = [result_quotes stringForColumn:#"NOTES"];
sub.isDirty = NO;
[appDelegate.quotes addObject:sub];
[sub release];
}
//POPULATE THE QUOTE_MAPS
FMResultSet *result_quote_map = [database executeQuery:#"select * from QUOTE_MAP"];
while([result_quote_map next]) {
QuoteMap *sub = [QuoteMap alloc];
sub.quote_id = [result_quote_map stringForColumn:#"QUOTE_ID"];
sub.quote_map_id = [result_quote_map stringForColumn:#"QUOTE_MAP_ID"];
sub.subject_id = [result_quote_map stringForColumn:#"SUBJECT_ID"];
sub.isDirty = NO;
[appDelegate.quoteMaps addObject:sub];
[sub release];
}
[database close];
NSLog(#"Count of categories: %i", appDelegate.categories.count);
NSLog(#"Count of subjects: %i", appDelegate.subjects.count);
NSLog(#"Count of quotes: %i", appDelegate.quotes.count);
NSLog(#"Count of quoteMaps: %i", appDelegate.quoteMaps.count);
}
Here is the getDbPath:
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"reference.db"];
}
Sometimes, the best thing to do is build->analyze ( cmd shift b ). This will point out your bug right away in almost all cases.
Best of luck!
categories = [[NSMutableArray alloc] init];
.
.
//Initialize the Category array.
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
self.categories = tempArray;
[tempArray release];
u've setup categories, then setup the tempArray, replaced the one in categories with it thus making a leak, then released the temp arrayObject, which what categories is now also pointing on, so unless "self.categories" is a retained property it will be a zombie. there seems to be something wrong there.
I may need to see some more of your code (the property declarations and their synthesis to make sure.
is the Zombie called on "getInitialDataToDisplay" or on "getDBPath"
try dividing it on 2 lines to know pin point more
I think you have not declare Category as retained property in .h file.If not, add following line in your .h file
#property (nonatomic, retain) NSArray Category;
And synthesize the property in .m as-
#synthesize Category;
I think it will help ....

Load mapview in the correct way

I am loading a mapview with annotation. I have written the code as shown below. As I am new to OOPS I know that I may have committed a lot of mistakes. It would be really helpful, if someone would review my code and give some suggestions.
- (void)viewDidLoad
{
[super viewDidLoad];
if(groupOrContactSelected){
UIBarButtonItem *infoButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.infoButton];
UIBarButtonItem *segmentedButton = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
NSArray *toolbarItems = [NSArray arrayWithObjects: infoButtonItem, flexibleSpace, segmentedButton, nil];
[self setToolbarItems:toolbarItems];
self.navigationController.toolbar.translucent = true;
self.navigationController.toolbarHidden = NO;
[infoButtonItem release];
[segmentedButton release];
[flexibleSpace release];
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
mapView.delegate=self;
[self.view addSubview:mapView];
addressbook = ABAddressBookCreate();
for (i = 0; i<[groupContentArray count]; i++) {
person = ABAddressBookGetPersonWithRecordID(addressbook,[[groupContentArray objectAtIndex:i] intValue]);
ABMultiValueRef addressProperty = ABRecordCopyValue(person, kABPersonAddressProperty);
NSArray *address = (NSArray *)ABMultiValueCopyArrayOfAllValues(addressProperty);
for (NSDictionary *addressDict in address)
{
addAnnotation = nil;
firstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
lastName = (NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
NSString *country = [addressDict objectForKey:#"Country"];
NSString *streetName = [addressDict objectForKey:#"Street"];
NSString *cityName = [addressDict objectForKey:#"City"];
NSString *stateName = [addressDict objectForKey:#"State"];
NSString *fullAddress = [streetName stringByAppendingFormat:#"%#/%#/%#", cityName, stateName, country];
mapCenter = [self getLocationFromAddressString:fullAddress];
if(stateName != NULL || country != NULL || streetName != NULL || cityName != NULL){
addAnnotation = (SJAddressAnnotation *)[mapView dequeueReusableAnnotationViewWithIdentifier:[groupContentArray objectAtIndex:i]];
if(addAnnotation == nil){
addAnnotation = [[[SJAddressAnnotation alloc] initWithCoordinate:mapCenter title:firstName SubTitle:lastName Recordid:[groupContentArray objectAtIndex:i] ] autorelease];
[mapView addAnnotation:addAnnotation];}
}
}
CFRelease(addressProperty);
}
[self zoomToFitMapAnnotations:mapView];
[self.navigationItem setHidesBackButton:YES animated:YES];
NSString *mapTitle = localizedString(#"MAP_TITLE");
[self setTitle:mapTitle];
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
NSString *close = localizedString(#"CLOSE");
UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:close style:UIBarButtonItemStylePlain target:self action:#selector(onClose:)];
self.navigationItem.rightBarButtonItem = closeButton;
self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
[closeButton release];
}
[searchDirectionSegmentedControl release];
[mapView release];
}
I may have committed a lot of mistakes. All suggestions will be appreciated. Thanks
Here is link which you can prefer and know how to structure the code properly http://www.highoncoding.com/Articles/804_Introduction_to_MapKit_Framework_for_iPhone_Development.aspx
Hope this help you.

donot open ABPersonViewController

i am trying to open ABPersonViewController at table delegate method (DidSelectRowAtIndex). but when i tap on one of my contact person in table view it shows "obj msg send". help me
here is my code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Fetch the address book
if ((people != nil) && [people count])
{
ABAddressBookRef addressBook = ABAddressBookCreate();
//ABPersonViewController *personController = [[ABPersonViewController alloc] initWithNibName:#"ABPersonViewController" bundle:nil];
ABRecordRef person = (ABRecordRef)[people objectAtIndex:indexPath.row];
ABPersonViewController *personController = [[ABPersonViewController alloc] init];
personController.addressBook = addressBook;
personController.personViewDelegate = self;
personController.displayedPerson = person;
personController.allowsEditing = YES;
//navigationController = [[UINavigationController alloc] init] ;
[self presentModalViewController:personController animated:YES];
//[self.navigationController pushViewController:personController animated:YES];
[personController release];
} else
{
// Show an alert if "KETAN" is not in Contacts
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Could not find naina in the Contacts application"
delegate:nil
cancelButtonTitle:#"Cancel"
otherButtonTitles:nil];
[alert show];
[alert release];
}
[people release];
}
You are doing an unnecessary release here, CFRelease(person);. You are just getting the value directly from an array so you shouldn't release it. Moreover, the ABPersonViewController object doesn't retain the person object assigned to displayedPerson so this results in an error when it tries to access the object which has been released.
If you want the personview to open in edit mode, in addition to allowsEditing = YES, you need to specify setEditing:YES:
[personController setEditing:YES animated:NO];
Use this line instead of that in your code,
ABPersonViewController *personController = [[ABPersonViewController alloc] initWithNibName:#"ABPersonViewController" bundle:nil];

adding all person in form of array in ABRecordRef

how can i add the people from the contacts to 'people'- array then to abrecordref.??? Actually i want all the contacts in tableview and can able to edit individual record. here is my code:
-(void)showPersonViewController
{
// Fetch the address book
ABAddressBookRef addressBook = ABAddressBookCreate();
// Search for the person named "rubal" in the address book
NSArray *people = (NSArray *)ABAddressBookCopyPeopleWithName(addressBook, CFSTR("naina"));
// Display "KETAN" information if found in the address book
if ((people != nil) && [people count])
{
ABRecordRef person = (ABRecordRef)[people objectAtIndex:0];
ABPersonViewController *picker = [[[ABPersonViewController alloc] init] autorelease];
picker.personViewDelegate = self;
picker.displayedPerson = person;
// Allow users to edit the person’s information
picker.allowsEditing = YES;
[self.navigationController pushViewController:picker animated:YES];
}
else
{
// Show an alert if "KETAN" is not in Contacts
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Could not find naina in the Contacts application"
delegate:nil
cancelButtonTitle:#"Cancel"
otherButtonTitles:nil];
[alert show];
[alert release];
}
[people release];
CFRelease(addressBook);
}
instead of only 'naina' i want all record in table view and edit individually
Look at ABPerson Class Reference. There is a list of other copy functions, including the one you seek, ABAddressBookCopyArrayOfAllPeople(ABAddressBookRef ab)
comment out your function and add this one and see if it works
-(BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
[peoplePicker dismissModalViewControllerAnimated:NO];
ABPersonViewController *picker = [[ABPersonViewController alloc] init];
picker.personViewDelegate = self;
picker.displayedPerson = person;
// Allow users to edit the person’s information
picker.allowsEditing = YES;
[picker setValue:[NSNumber numberWithBool:YES] forKey:#"allowsDeletion"];
[self.navigationController pushViewController:picker animated:YES];
return YES;
}

UITabBarItems in UITabBar show after I click the item not when application launches

This application I'm writing has a problem.
I'm setting up the UITabBar in my application window and set the icons in the view files.
But when i run the app, the first icons show up (because the view is loaded I guess) and the other icons do not show up until I click them.
Do i need to implement self.tabBarItem in some other method not viewDidLoad?
Thanks in advance to everyone!
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
tabBar = [[UITabBarController alloc] init];
SubscriptionsController *subscriptionsController = [[SubscriptionsController alloc] init];
FavoritesController *favoritesController = [[FavoritesController alloc] init];
CategoriesController *categoriesController = [[CategoriesController alloc] init];
TagsController *tagsController = [[TagsController alloc] init];
HelpScreenController *helpScreenController = [[HelpScreenController alloc] init];
tabBar.viewControllers = [NSArray arrayWithObjects:
subscriptionsController,
favoritesController,
categoriesController,
tagsController,
helpScreenController,
nil
];
[window addSubview:tabBar.view];
// Override point for customization after application launch.
[window makeKeyAndVisible];
return YES;
}
//The View
- (void)viewDidLoad {
[super viewDidLoad];
tabIcon = [[UITabBarItem alloc] initWithTitle:#"Abonime" image:[UIImage imageNamed:#"subscr.png"] tag:0];
self.tabBarItem = tabIcon;
[tabIcon release];
}
I think you should set the tabBarItem property in a view controller's designated initializer (judging from your code, it must be -init for each of the controllers). In fact, the tab bar controller is smart enough to load the views on demand, that is, the tabBarItem property should be set before viewDidLoad gets sent.
Also, you seem to be leaking all the view controllers. To fix that, do the following:
SubscriptionsController *subscriptionsController = [[[SubscriptionsController alloc] init] autorelease];
Correct. The icons don't show up because the view (other than the first one, isn't loaded yet). And doesn't get loaded until you tap a view because viewDidLoad isn't called until then.
Remove the code in the individual UIViewControllers viewDidLoad and Do this...
NSArray *controllers = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:#"SubscriptionsController", #"class", [UIImage imageNamed:#"btn_tax.png"], #"icon", #"Abonime", #"title", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"FavoritesController", #"class", [UIImage imageNamed:#"btn_tax.png"], #"icon", #"Abonime", #"title", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"CategoriesController", #"class", [UIImage imageNamed:#"btn_tax.png"], #"icon", #"Abonime", #"title", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"TagsController", #"class", [UIImage imageNamed:#"btn_tax.png"], #"icon", #"Abonime", #"title", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"HelpScreenController", #"class", [UIImage imageNamed:#"btn_tax.png"], #"icon", #"Abonime", #"title", nil],
nil];
NSMutableArray *controllerArray = [NSMutableArray array] ;
for (NSUInteger i = 0; i < [controllers count]; i++)
{
id newClass = [[NSClassFromString([[controllers objectAtIndex:i] objectForKey:#"class"]) alloc] init];
UITabBarItem *tabItem = [[UITabBarItem alloc] init];
tabItem.image = [[controllers objectAtIndex:i] objectForKey:#"icon"];
tabItem.title = [[controllers objectAtIndex:i] objectForKey:#"title"];
tabItem.tag = i;
[(UIViewController*)newClass setTabBarItem:tabItem];
[tabItem release];
[controllerArray addObject:newClass];
[newClass release];
}
tabBar.viewControllers = controllerArray;