iOS - add contact into Contacts?
contacts, email, ios, iphone, uibutton
Solution
If doing this in iOS 9 or later, you should use the `Contacts` framework:
@import Contacts;
You also need to update your `Info.plist`, adding a `NSContactsUsageDescription` to explain why your app requires access to contacts.
Then, when you then want to programmatically add the contact, then you can do something like:
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
if (status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusRestricted) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Access to contacts." message:@"This app requires access to contacts because ..." preferredStyle:UIAlertControllerStyleActionSheet];
[alert addAction:[UIAlertAction actionWithTitle:@"Go to Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alert animated:TRUE completion:nil];
return;
}
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!granted) {
dispatch_async(dispatch_get_main_queue(), ^{
// user didn't grant access;
// so, again, tell user here why app needs permissions in order to do it's job;
// this is dispatched to the main queue because this request could be running on background thread
});
return;
}
// create contact
CNMutableContact *contact = [[CNMutableContact alloc] init];
contact.familyName = @"Doe";
contact.givenName = @"John";
CNLabeledValue *homePhone = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:[CNPhoneNumber phoneNumberWithStringValue:@"312-555-1212"]];
contact.phoneNumbers = @[homePhone];
CNSaveRequest *request = [[CNSaveRequest alloc] init];
[request addContact:contact toContainerWithIdentifier:nil];
// save it
NSError *saveError;
if (![store executeSaveRequest:request error:&saveError]) {
NSLog(@"error = %@", saveError);
}
}];
Or, even better, if you want to add the contact using the `ContactUI` framework (giving the user visual confirmation of the contact and let them tailor it as they see fit), you can import both frameworks:
@import Contacts;
@import ContactsUI;
And then:
CNContactStore *store = [[CNContactStore alloc] init];
// create contact
CNMutableContact *contact = [[CNMutableContact alloc] init];
contact.familyName = @"Smith";
contact.givenName = @"Jane";
CNLabeledValue *homePhone = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:[CNPhoneNumber phoneNumberWithStringValue:@"301-555-1212"]];
contact.phoneNumbers = @[homePhone];
CNContactViewController *controller = [CNContactViewController viewControllerForUnknownContact:contact];
controller.contactStore = store;
controller.delegate = self;
[self.navigationController pushViewController:controller animated:TRUE];
My original answer, using the `AddressBook` and `AddressBookUI` frameworks for iOS versions before 9, is below. But if only supporting iOS 9 and later, use the `Contacts` and `ContactsUI` frameworks as outlined above.
--
If you want to add a contact to the user's address book, you use `AddressBook.Framework` to create a contact, and then you use the `AddressBookUI.Framework` to present the user interface to allow the user to add it to their personal address book using `ABUnknownPersonViewController`. Thus, you can:
Add `AddressBook.Framework` and `AddressBookUI.Framework` to your list under Link Binary With Libraries;
Import the .h files:
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
Write the code to create a contact, e.g.:
// create person record
ABRecordRef person = ABPersonCreate();
// set name and other string values
ABRecordSetValue(person, kABPersonOrganizationProperty, (__bridge CFStringRef) venueName, NULL);
if (venueUrl) {
ABMutableMultiValueRef urlMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(urlMultiValue, (__bridge CFStringRef) venueUrl, kABPersonHomePageLabel, NULL);
ABRecordSetValue(person, kABPersonURLProperty, urlMultiValue, nil);
CFRelease(urlMultiValue);
}
if (venueEmail) {
ABMutableMultiValueRef emailMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(emailMultiValue, (__bridge CFStringRef) venueEmail, kABWorkLabel, NULL);
ABRecordSetValue(person, kABPersonEmailProperty, emailMultiValue, nil);
CFRelease(emailMultiValue);
}
if (venuePhone) {
ABMutableMultiValueRef phoneNumberMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
NSArray *venuePhoneNumbers = [venuePhone componentsSeparatedByString:@" or "];
for (NSString *venuePhoneNumberString in venuePhoneNumbers)
ABMultiValueAddValueAndLabel(phoneNumberMultiValue, (__bridge CFStringRef) venuePhoneNumberString, kABPersonPhoneMainLabel, NULL);
ABRecordSetValue(person, kABPersonPhoneProperty, phoneNumberMultiValue, nil);
CFRelease(phoneNumberMultiValue);
}
// add address
ABMutableMultiValueRef multiAddress = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
NSMutableDictionary *addressDictionary = [[NSMutableDictionary alloc] init];
if (venueAddress1) {
if (venueAddress2)
addressDictionary[(NSString *) kABPersonAddressStreetKey] = [NSString stringWithFormat:@"%@\n%@", venueAddress1, venueAddress2];
else
addressDictionary[(NSString *) kABPersonAddressStreetKey] = venueAddress1;
}
if (venueCity)
addressDictionary[(NSString *)kABPersonAddressCityKey] = venueCity;
if (venueState)
addressDictionary[(NSString *)kABPersonAddressStateKey] = venueState;
if (venueZip)
addressDictionary[(NSString *)kABPersonAddressZIPKey] = venueZip;
if (venueCountry)
addressDictionary[(NSString *)kABPersonAddressCountryKey] = venueCountry;
ABMultiValueAddValueAndLabel(multiAddress, (__bridge CFDictionaryRef) addressDictionary, kABWorkLabel, NULL);
ABRecordSetValue(person, kABPersonAddressProperty, multiAddress, NULL);
CFRelease(multiAddress);
// let's show view controller
ABUnknownPersonViewController *controller = [[ABUnknownPersonViewController alloc] init];
controller.displayedPerson = person;
controller.allowsAddingToAddressBook = YES;
// current view must have a navigation controller
[self.navigationController pushViewController:controller animated:YES];
CFRelease(person);
See the ABUnknownPersonViewController Class Reference or the Prompting the User to Create a New Person Record from Existing Data section of the Address Book Programming Guide.
Problem
Heyo! Is there a way how when a user taps a button it can add or update a contact into the actual Apple Contacts Book? Some festivals have email responses include a "name card" that the receiver can download and find in their contact book.