iOS - 将联系人添加到通讯录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15625447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 22:52:28  来源:igfitidea点击:

iOS - add contact into Contacts?

iphoneiosemailuibuttoncontacts

提问by HowbeitGirl

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.

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

回答by Rob

If doing this in iOS 9 or later, you should use the Contactsframework:

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

@import Contacts;

You also need to update your Info.plist, adding a NSContactsUsageDescriptionto explain why your app requires access to contacts.

您还需要更新您的Info.plist,添加一个NSContactsUsageDescription来解释为什么您的应用需要访问联系人。

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 ContactUIframework (giving the user visual confirmation of the contact and let them tailor it as they see fit), you can import both frameworks:

或者,更好的是,如果您想使用ContactUI框架添加联系人(向用户提供联系人的视觉确认并让他们根据他们认为合适的方式进行定制),您可以导入两个框架:

@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 AddressBookand AddressBookUIframeworks for iOS versions before 9, is below. But if only supporting iOS 9 and later, use the Contactsand ContactsUIframeworks as outlined above.

我最初的答案是使用9 之前的 iOS 版本的AddressBookAddressBookUI框架,如下所示。但是,如果只支持iOS的9和更高版本,使用ContactsContactsUI框架上面列出。

--

——

If you want to add a contact to the user's address book, you use AddressBook.Frameworkto create a contact, and then you use the AddressBookUI.Frameworkto present the user interface to allow the user to add it to their personal address book using ABUnknownPersonViewController. Thus, you can:

如果要将联系人添加到用户的通讯录,请使用AddressBook.Framework来创建联系人,然后使用AddressBookUI.Framework来呈现用户界面,以允许用户使用 将其添加到他们的个人通讯录中ABUnknownPersonViewController。因此,您可以:

  1. Add AddressBook.Frameworkand AddressBookUI.Frameworkto your list under Link Binary With Libraries;

  2. Import the .h files:

    #import <AddressBook/AddressBook.h>
    #import <AddressBookUI/AddressBookUI.h>
    
  3. 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);
    
  1. Link Binary With Libraries下将AddressBook.Framework和添加AddressBookUI.Framework到您的列表中;

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

See the ABUnknownPersonViewController Class Referenceor the Prompting the User to Create a New Person Record from Existing Datasection of the Address Book Programming Guide.

请参阅ABUnknownPersonViewController 类参考地址簿编程指南提示用户从现有数据创建新人员记录部分

回答by Hari R Krishna

To present default contact controller

显示默认联系人控制器

Step 1:Add ContactUi.framework into project and import

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

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

Step2:Add this code

Step2:添加此代码

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

Step3:

第三步:

For getting call back when pressing DONE or CANCEL, Add <CNContactViewControllerDelegate>and implement the delegate method.

为了在按下 DONE 或 CANCEL 时获得回调,添加<CNContactViewControllerDelegate>并实现委托方法。

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

回答by Deepak Kumar

@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);

    }

}];

 }