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

How*_*irl 38 email iphone contacts uibutton ios

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

Rob*_*Rob 79

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

@import Contacts;
Run Code Online (Sandbox Code Playgroud)

您还需要更新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);
    }
}];
Run Code Online (Sandbox Code Playgroud)

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

@import Contacts;
@import ContactsUI;
Run Code Online (Sandbox Code Playgroud)

然后:

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];
Run Code Online (Sandbox Code Playgroud)

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

-

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

  1. 添加AddressBook.FrameworkAddressBookUI.Framework下列表链接二进制与图书馆 ;

  2. 导入.h文件:

    #import <AddressBook/AddressBook.h>
    #import <AddressBookUI/AddressBookUI.h>
    
    Run Code Online (Sandbox Code Playgroud)
  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);
    
    Run Code Online (Sandbox Code Playgroud)

请参阅" 通讯簿编程指南"中的" ABUnknownPersonViewController类参考"或" 提示用户从现有数据创建新人员记录"部分.