Contacts.framework 는 iOS9 부터 기존 ABAddressBook.framework 를 대체합니다.


샘플프로젝트는 깃허브에 올려놓았습니다.

https://github.com/minjoongkim/iOS9-Contacts.framework-AddressBook-Sample



1. 주소록 불러오기

CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
if( status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusRestricted)
{
    NSLog(@"access denied");
}
else
{
    //Create repository objects contacts
    CNContactStore *contactStore = [[CNContactStore alloc] init];

    //Select the contact you want to import the key attribute  ( https://developer.apple.com/library/watchos/documentation/Contacts/Reference/CNContact_Class/index.html#//apple_ref/doc/constant_group/Metadata_Keys )

    NSArray *keys = [[NSArray alloc]initWithObjects:CNContactIdentifierKey, CNContactEmailAddressesKey, CNContactBirthdayKey, CNContactImageDataKey, CNContactPhoneNumbersKey, CNContactViewController.descriptorForRequiredKeys, nil];

    // Create a request object
    CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
    request.predicate = nil;

    [contactStore enumerateContactsWithFetchRequest:request
                                              error:nil
                                         usingBlock:^(CNContact* __nonnull contact, BOOL* __nonnull stop)
     {
         // Contact one each function block is executed whenever you get
         NSString *phoneNumber = @"";
         if( contact.phoneNumbers)
             phoneNumber = [[[contact.phoneNumbers firstObject] value] stringValue];

         NSLog(@"phoneNumber = %@", phoneNumber);
         NSLog(@"givenName = %@", contact.givenName);
         NSLog(@"familyName = %@", contact.familyName);
         NSLog(@"email = %@", contact.emailAddresses);


         [contactList addObject:contact];
     }];

    [contactTableView reloadData];
}

2. 피커뷰로 불러오기

// Create a new contact view
CNContactViewController *contactController = [CNContactViewController viewControllerForContact:contact];
contactController.delegate = self;
contactController.allowsEditing = YES;
contactController.allowsActions = YES;

// Display the view
[self.navigationController pushViewController:contactController animated:YES];

3. 주소록 추가하기

-(void)saveContact:(NSString*)familyName givenName:(NSString*)givenName phoneNumber:(NSString*)phoneNumber {
    CNMutableContact *mutableContact = [[CNMutableContact alloc] init];

    mutableContact.givenName = givenName;
    mutableContact.familyName = familyName;
    CNPhoneNumber * phone =[CNPhoneNumber phoneNumberWithStringValue:phoneNumber];

    mutableContact.phoneNumbers = [[NSArray alloc] initWithObjects:[CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberiPhone value:phone], nil];
    CNContactStore *store = [[CNContactStore alloc] init];
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
    [saveRequest addContact:mutableContact toContainerWithIdentifier:store.defaultContainerIdentifier];

    NSError *error;
    if([store executeSaveRequest:saveRequest error:&error]) {
        NSLog(@"save");
        [self reloadContactList];
    }else {
        NSLog(@"save error");
    }
}

4. 주소록 업데이트 하기

-(void)updateContact:(CNContact*)contact memo:(NSString*)memo{
    CNMutableContact *mutableContact = contact.mutableCopy;

    mutableContact.note = memo;

    CNContactStore *store = [[CNContactStore alloc] init];
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
    [saveRequest updateContact:mutableContact];

    NSError *error;
    if([store executeSaveRequest:saveRequest error:&error]) {
        NSLog(@"save");
    }else {
        NSLog(@"save error : %@", [error description]);
    }
}

5. 주소록 삭제하기

-(void)deleteContact:(CNContact*)contact {
    CNMutableContact *mutableContact = contact.mutableCopy;

    CNContactStore *store = [[CNContactStore alloc] init];
    CNSaveRequest *deleteRequest = [[CNSaveRequest alloc] init];
    [deleteRequest deleteContact:mutableContact];

    NSError *error;
    if([store executeSaveRequest:deleteRequest error:&error]) {
        NSLog(@"delete complete");
        [self reloadContactList];
    }else {
        NSLog(@"delete error : %@", [error description]);
    }

}

6. 주소록 상세보기

-(void)loadContactView:(CNContact*)contact {
    // Create a new contact view
    CNContactViewController *contactController = [CNContactViewController viewControllerForContact:contact];
    contactController.delegate = self;
    contactController.allowsEditing = YES;
    contactController.allowsActions = YES;

    // Display the view
    [self.navigationController pushViewController:contactController animated:YES];
}



WRITTEN BY
블로blow
iOS 개발자 생활이야기

트랙백  0 , 댓글  2개가 달렸습니다.
  1. 김련호 2016.02.26 09:36
    안녕하세요,

    샘플 코드 잘 보았습니다^^ 많은 도움이 되었네요~

    제 코드에서 뭔가 문제가 있는 줄 알았는데, Github에 올려두신 샘플에서도 동일한 문제가 있는 부분이 있어서 댓글 남깁니다.

    연락처 Detail에 들어가서 Share Contact를 눌렀을 때 상단 네비게이션 바가 사라지는 현상이 있는데
    이 부분 때문에 골치네요...

    ABPersonViewcontroller를 iOS 9 이상에서 쓰면 네비게이션 바가 사라지는건 버그로 리포팅이 된것같은데,
    CNContactViewController로 대체하면 해결될줄알았으나 해결이 안되는 것 처럼 보이네요...
    iOS 기본 연락처는 아무 문제가 없는데...흠...
    • 그런문제가 있네요.
      잠깐 봤는데, 아무래도 ios버그인거 같네요.
      지금 잠깐 생각해본 해결법으로는

      timer를 돌려서 계속해서 네비게이션의 상태를 체크합니다.
      그리고 네비게이션이 hide되었다면 show를 해주고..
      타이머를 쓰게되면 퍼포먼스상 문제가 있을수 있지만, 그렇게 무거운 동작을 하는게 아니라 괜찮다고 생각합니다.
      이거 보시고 참고하시고, 나중에 좋은정보 있으면 또 알려주세요.
      -(void)loadContactView:(CNContact*)contact {
      // Create a new contact view
      [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(navigationCheck:) userInfo:nil repeats:NO];
      CNContactViewController *contactController = [CNContactViewController viewControllerForContact:contact];
      contactController.delegate = self;
      contactController.allowsEditing = YES;
      contactController.allowsActions = YES;

      // Display the view
      [self.navigationController pushViewController:contactController animated:YES];
      }

      -(void)navigationCheck:(id*)id {
      if(self.navigationController.navigationBarHidden == true) {
      [self.navigationController setNavigationBarHidden:NO];
      }
      [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(navigationCheck:) userInfo:nil repeats:NO];

      }
secret