Подтвердить что ты не робот

IOS - добавить контакт в Контакты?

Heyo! Есть ли способ, когда пользователь нажимает кнопку, он может добавлять или обновлять контакт в фактическую книгу контактов Apple? На некоторых фестивалях есть ответы на электронную почту, включающие "карточку имени", которую получатель может загрузить и найти в своей контактной книге.

4b9b3361

Ответ 1

Если вы сделаете это в 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 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];

Мой первоначальный ответ, используя рамки AddressBook и AddressBookUI для версий iOS до 9, приведен ниже. Но если поддерживать только iOS 9 и более поздние версии, используйте рамки Contacts и ContactsUI, как описано выше.

-

Если вы хотите добавить контакт в адресную книгу пользователя, вы можете использовать AddressBook.Framework для создания контакта, а затем вы используете AddressBookUI.Framework для представления пользовательского интерфейса, чтобы пользователь мог добавить его на свой личный адрес используя ABUnknownPersonViewController. Таким образом, вы можете:

  • Добавьте AddressBook.Framework и AddressBookUI.Framework в ваш список под Link Binary With Libraries;

  • Импортируйте файлы .h:

    #import <AddressBook/AddressBook.h>
    #import <AddressBookUI/AddressBookUI.h>
    
  • Введите код для создания контакта, например:

    // 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 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 или Запрос пользователю создать Запись нового человека из существующих данных в Руководстве по программированию адресной книги.

Ответ 2

Представить контроллер контактов по умолчанию

Шаг 1: Добавить ContactUi.framework в проект и импортировать

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

Шаг 2: Добавьте этот код

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

Шаг 3:

Чтобы получить обратный вызов при нажатии DONE или CANCEL, добавьте <CNContactViewControllerDelegate> и реализуйте метод делегата.

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

Ответ 3

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

    }

}];

 }