2013-03-25 95 views
32

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

回答

68

如果在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框架的接触(给用户接触的视觉确认,让他们调整它,因为他们认为合适的),你可以导入两种框架:

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

我的原始答案,使用AddressBookAddressBookUI iOS之前的版本9的框架如下。但是,如果仅支持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); 
    

地址的ABUnknownPersonViewController Class ReferencePrompting the User to Create a New Person Record from Existing Data节图书编程指南。

+0

为什么你把“状态== CNAuthorizationStatusDenied ||状态== CNAuthorizationStatusDenied”? – fechidal89

+0

错字。应该被拒绝||限制。看修改后的答案。 – Rob

+0

您可以帮我了解为什么我无法在创建标签值时使用自定义标识符,如下所示:'let app = CNLabeledValue (label:“App”,value:appURL); contact.urlAddresses.append(app)'请注意,如果iPhone仅使用iCloud保存联系人,我可以使用它。但是,如果我使用Google联系人,它不起作用。 –

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

    } 

}]; 

} 
2

为了呈现默认联系人控制器

步骤1: 添加ContactUi。框架到项目和进口

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

第二步: 添加该代码

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

第三步:

为了得到呼叫后挤压完成时或取消,添加<CNContactViewControllerDelegate>和实施委托方法。

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