0

I have created a person object

ABRecordRef person = ABPersonCreate(); 

I set the properties of person from my web services. person has all the properties set, like first name, last name, email id, phone number, address, url etc.

I want to load a map view, with multiple pins, where each particular pin holds the information about a particular person. On the click of each pin, I need to load the ABPersonViewController class of each person. I am not sure about how to add annotation with the information I have and how a particular pin could hold information about a particular person. In this case the person may or may not be in my address book, and I don't need to save the person in my address book . I am really confused about how to do this. Need help.

Edit:

I have 3 classes:

!. Web service class: where I have the person object. 2. MapView class: where I load the map view. 3. Annotation class: which has the details about my annotation.

How will I use person records and present it through ABPersonViewController. How should my annotation class be?

Jean Paul
  • 2,389
  • 5
  • 27
  • 37
  • Where specifically is the confusion? Do you have to store the person info in a ABPerson? Maybe you can just create the ABPerson when you need to actually display the ABPersonViewController. Though you should be able to create an annotation class with an ABPerson ivar. –  Mar 22 '12 at 13:29
  • Will storing `person` in `ABPerson` automatically save the `person` in the phone addressbook? In my case I dont need to save `person` in my addressbook, I just need to display the vCard of `person`, when I click a pin in the `mapview` – Jean Paul Mar 22 '12 at 13:40
  • In the web service class, are you creating an ABPerson or do you have your own "Person" class? I don't think just creating an ABPerson record in memory adds it to the address book. –  Mar 22 '12 at 14:30
  • I am not creating `ABPerson`, I just have the `person` record. I use `ABRecordSetValue` to set properties to `person`. Should I subclass `ABPerson` in this case. And how should my `annotation`class look like. – Jean Paul Mar 22 '12 at 14:37

1 Answers1

1

What I would do to start is create a Person class (subclass of NSObject) that also implements the MKAnnotation protocol. You could create two separate classes ("Person" and "PersonAnnotation") if you wanted to but it's not necessary.

In the Person class, you could either declare your own person-related properties such as First Name, Last Name, Email Address, etc. or you could just have an ABRecordRef ivar and let it store the individual fields for you.

I would only create an ABPerson record when I want to actually show the ABPersonViewController to keep the AB-specific code isolated and to manage the ABPerson record's creation and release more easily. Regardless, just creating an ABRecordRef does not add it to the address book. As the ABPerson Reference documentation says:

Person records don’t necessarily have to be stored in the Address Book database. You can use person records as a way to group contact information in memory and present it to the user through, for example, a person view controller (ABPersonViewController).

So the Person class could look like this:

@interface Person : NSObject<MKAnnotation>
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, copy) NSString *emailAddress;
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@end


@implementation Person

@synthesize firstName;
@synthesize lastName;
@synthesize emailAddress;
@synthesize coordinate;

-(NSString *)title
{
    return [NSString stringWithFormat:@"%@ %@", firstName, lastName];
}

-(NSString *)subtitle
{
    return emailAddress;
}

@end

The web service class would create an instance of Person and set the properties. Then the map view class would add that instance directly to the map (since Person already implements MKAnnotation):

[mapView addAnnotation:person];

When the pin is tapped, the map view will call the didSelectAnnotationView delegate method. Or, you could add a disclosure button to the annotation's callout in viewForAnnotation and respond to that in the calloutAccessoryControlTapped delegate method.

Whichever action method you decide to use, in that method you could then create an ABRecordRef, set its values from the annotation object, and then show the ABPersonViewController. In both delegate methods, the Person annotation object could be retrieved using:

Person *personTapped = (Person *)view.annotation;
  • I have got one more question. How to pass `ABRecordref` as an arguement of a method. – Jean Paul Mar 22 '12 at 17:08
  • 1
    In the [sample app ABUIGroups in GroupViewController.m](http://developer.apple.com/library/ios/#samplecode/ABUIGroups/Listings/Classes_GroupViewController_m.html#//apple_ref/doc/uid/DTS40011307-Classes_GroupViewController_m-DontLinkElementID_8), search for the `nameForSource` method for an example. –  Mar 22 '12 at 17:19
  • I get the following warning `Sending 'ABRecordRef' (aka 'const void *') to parameter of type 'ABRecordRef *' (aka 'const void **') discards qualifiers` – Jean Paul Mar 22 '12 at 17:35
  • 2
    In the method argument, don't declare it as `(ABRecordRef *)`. Just declare it as `(ABRecordRef)`. Notice the method declaration in the sample app: `- (NSString *)nameForSource:(ABRecordRef)source` –  Mar 22 '12 at 17:40
  • OK. My bad. I tried to pass 'ABRecordRef' as an object. Now everything sorted. – Jean Paul Mar 22 '12 at 17:41