2013-03-25 16 views
32

Heyo! C'è un modo in cui quando un utente tocca un pulsante può aggiungere o aggiornare un contatto nell'effettiva rubrica dei contatti Apple? Alcuni festival hanno risposte via e-mail che includono un "biglietto da visita" che il destinatario può scaricare e trovare nella propria rubrica.iOS - aggiungi un contatto in Contatti?

risposta

68

Se facendo questo in iOS 9 o successivo, è necessario utilizzare il Contacts quadro:

@import Contacts; 

È inoltre necessario aggiornare il Info.plist, l'aggiunta di un NSContactsUsageDescription per spiegare il motivo per cui la vostra applicazione richiede l'accesso ai contatti.

Poi, quando poi si desidera aggiungere a livello di codice il contatto, allora si può fare qualcosa di simile:

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

O, meglio ancora, se si desidera aggiungere il contatto utilizzando il quadro ContactUI (dando all'utente conferma visiva del contatto e far loro personalizzare come meglio credono), è possibile importare entrambi i quadri:

@import Contacts; 
@import ContactsUI; 

e poi:

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

La mia risposta originale, utilizzando i framework AddressBook e AddressBookUI per versioni iOS precedenti 9, è riportata di seguito. Tuttavia, se si supporta solo iOS 9 e versioni successive, utilizzare i framework Contacts e ContactsUI come descritto sopra.

-

Se si desidera aggiungere un contatto alla rubrica dell'utente, si utilizza AddressBook.Framework per creare un contatto, e quindi si utilizza il AddressBookUI.Framework per presentare l'interfaccia utente per consentire all'utente di inserirlo a la loro rubrica personale usando ABUnknownPersonViewController. Così, è possibile:

  1. Aggiungi AddressBook.Framework e AddressBookUI.Framework alla tua lista sotto Link Binary With Libraries;

  2. importare i file .h:

    #import <AddressBook/AddressBook.h> 
    #import <AddressBookUI/AddressBookUI.h> 
    
  3. scrivere il codice per creare un contatto, ad esempio:

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

Vedere la ABUnknownPersonViewController Class Reference o la sezione Prompting the User to Create a New Person Record from Existing Data del Indirizzo Guida alla programmazione del libro.

+0

perché si inserisce "status == CNAuthorizationStatusDenied || stato == CNAuthorizationStatusDenied"? – fechidal89

+0

typo. dovrebbe essere negato || limitato. vedere la risposta rivista. – Rob

+0

Puoi aiutarmi a capire perché non riesco a utilizzare l'identificatore personalizzato quando creo un valore etichettato come segue: 'let app = CNLabeledValue (etichetta:" App ", valore: appURL); contact.urlAddresses.append (app) 'Per favore nota che sono in grado di usarlo se iPhone sta usando iCloud solo per salvare i contatti. Ma se sto usando i contatti di Google, non funziona. –

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

Presentare controller di contatto predefinito

Fase 1: Aggiungi ContactUi.quadro nel progetto e importare

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

Step2: aggiungere questo codice

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

Fase 3:

Per ottenere chiamata indietro quando si preme FATTO o annullare, Aggiungi <CNContactViewControllerDelegate> ed attuare le metodo delegato.

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