2013-03-25 16 views
32

Heyo! Czy istnieje sposób, w jaki sposób, gdy użytkownik dotknie przycisku, może dodać lub zaktualizować kontakt do rzeczywistej książki kontaktów Apple? Niektóre festiwale mają odpowiedzi na wiadomości e-mail zawierające "wizytówkę", którą odbiorca może pobrać i znaleźć w książce kontaktowej.iOS - dodać kontakt do Kontaktów?

Odpowiedz

68

Jeśli robi to w iOS 9 lub nowszy, należy użyć Contacts ramowa:

@import Contacts; 

należy również zaktualizować Info.plist, dodając NSContactsUsageDescription wyjaśnić, dlaczego aplikacja wymaga dostępu do kontaktów.

Następnie, po czym chce programowo dodać kontakt, a następnie można zrobić coś takiego:

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

albo jeszcze lepiej, jeśli chcesz dodać kontakt za pomocą ramy ContactUI (dając użytkownikowi wizualne potwierdzenie kontaktu i niech dostosować go według własnego uznania), można importować zarówno ramy:

@import Contacts; 
@import ContactsUI; 

, a następnie:

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

Moja oryginalna odpowiedź, korzystająca z frameworków AddressBook i AddressBookUI dla wersji iOS przed 9, znajduje się poniżej. Ale jeśli tylko obsługujesz iOS 9 i nowsze, użyj frameworków Contacts i ContactsUI jak opisano powyżej.

-

Jeśli chcesz dodać kontakt do książki adresowej użytkownika, należy użyć AddressBook.Framework aby utworzyć kontakt, a następnie użyć AddressBookUI.Framework zaprezentowanie interfejsu użytkownika, aby umożliwić użytkownikowi, aby dodać go do ich osobistą książkę adresową przy użyciu ABUnknownPersonViewController. W ten sposób, można:

  1. Dodaj AddressBook.Framework i AddressBookUI.Framework do listy pod Link Binary With Libraries;

  2. Importuj pliki .h:

    #import <AddressBook/AddressBook.h> 
    #import <AddressBookUI/AddressBookUI.h> 
    
  3. napisać kod, aby utworzyć kontakt, np:

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

Zobacz ABUnknownPersonViewController Class Reference lub sekcję Prompting the User to Create a New Person Record from Existing Data z Adres Podręcznik programowania książek.

+0

dlaczego umieszczasz "status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusDenied"? – fechidal89

+0

literówka. należy odmówić || ograniczony. zobacz poprawioną odpowiedź. – Rob

+0

Czy możesz mi pomóc, aby dowiedzieć się, dlaczego nie mogę użyć niestandardowego identyfikatora podczas tworzenia wartości oznaczonej etykietą: 'let app = CNLabeledValue (etykieta:" App ", wartość: appURL); contact.urlAddresses.append (app) 'Zwróć uwagę, że jestem w stanie go użyć, jeśli iPhone używa tylko iCloud do zapisywania kontaktów. Ale jeśli korzystam z kontaktów Google, to nie działa. –

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

Aby przedstawić regulatorowi Kontakt domyślny

Krok 1: Dodaj ContactUi.Ramy do projektu i imporcie

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

Krok 2: Dodaj ten kod

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

Krok 3:

Dla uzyskania połączenia z powrotem po naciśnięciu Sporządzono lub CANCEL Dodaj <CNContactViewControllerDelegate> i wdrożenia Przekaż metodę.

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