iOS - 在联系人中添加联系人?

时间:2013-03-25 21:49:06

标签: iphone ios email uibutton contacts

Heyo! 有没有办法当用户点击按钮时,它可以将联系人添加或更新到实际的Apple通讯录中?一些节日的电子邮件回复包括接收者可以在他们的联系簿中下载和查找的“名片”。

3 个答案:

答案 0 :(得分:79)

如果在iOS 9或更高版本中执行此操作,则应使用Contacts框架:

@import Contacts;

您还需要更新Info.plist,添加NSContactsUsageDescription来解释您的应用需要访问联系人的原因。

然后,当您想以编程方式添加联系人时,您可以执行以下操作:

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);
    }
}];

或者,更好的是,如果您想使用ContactUI框架添加联系人(让用户直观地确认联系人并让他们按照自己的意愿定制),您可以导入两个框架:< / p>

@import Contacts;
@import ContactsUI;

然后:

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];

我的原始答案,使用9之前的iOS版本的AddressBookAddressBookUI框架,如下所示。但如果仅支持iOS 9及更高版本,请使用上述ContactsContactsUI框架。

-

如果要将联系人添加到用户的地址簿,可以使用AddressBook.Framework创建联系人,然后使用AddressBookUI.Framework显示用户界面以允许用户添加联系人使用ABUnknownPersonViewController到他们的个人通讯录。因此,您可以:

  1. AddressBook.FrameworkAddressBookUI.Framework添加到Link Binary With Libraries下的列表中;

  2. 导入.h文件:

    #import <AddressBook/AddressBook.h>
    #import <AddressBookUI/AddressBookUI.h>
    
  3. 编写代码以创建联系人,例如:

    // 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);
    
  4. 请参阅通讯簿编程指南的ABUnknownPersonViewController Class ReferencePrompting the User to Create a New Person Record from Existing Data部分。

答案 1 :(得分:2)

提供默认联系人控制器

第1步: 将ContactUi.framework添加到项目中并导入

    #import <Contacts/Contacts.h>
    #import <ContactsUI/ContactsUI.h>

<强>步骤2: 添加此代码

 -(void)showAddContactController{
        //Pass nil to show default contact adding screen
        CNContactViewController *addContactVC = [CNContactViewController viewControllerForNewContact:nil];
        addContactVC.delegate=self;
        UINavigationController *navController   = [[UINavigationController alloc] initWithRootViewController:addContactVC];
        [viewController presentViewController:navController animated:NO completion:nil];
    }

<强>步骤3:

要在按DONE或CANCEL时收到回叫,请添加<CNContactViewControllerDelegate>并实施委托方法。

- (void)contactViewController:(CNContactViewController *)viewController didCompleteWithContact:(nullable CNContact *)contact{
    //You will get the callback here
}

答案 2 :(得分:0)

@import Contacts;
-(void)addToContactList
 {
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];

if (status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusRestricted) {

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"This app previously was refused permissions to contacts; Please go to settings and grant permission to this app so it can add the desired contact" preferredStyle:UIAlertControllerStyleAlert];

    [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault 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.givenName = @"Test";

    contact.familyName = @"User";

    CNLabeledValue *homePhone = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:[CNPhoneNumber phoneNumberWithStringValue:@"91012-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);

    }

}];

 }