2017-01-18 12 views
0

Я хотел бы получить (в iOS с использованием Objective-C) только те контакты, у которых есть номер телефона, но как я могу это сделать? Я пытаюсь сформировать предикат, как в коде ниже, но, очевидно, это не работает.Список контактов с телефонами

contacts = [contactStore unifiedContactsMatchingPredicate:[NSPredicate predicateWithFormat:@"phoneNumbers <> nil"] keysToFetch:KEYS error:nil]; 

Итак, каков правильный способ сделать это? Спасибо за любую помощь!

+0

Что вы пробовали до сих пор? – user3182143

+0

Я пробовал то, что написал в коде snipplet. – Eir

+0

@ Ей попробуйте мой код для получения списка контактов http://stackoverflow.com/questions/41719037/list-contacts-with-phone-numbers/41720394#41720394 –

ответ

0

отфильтровывая контактов, которые не имеют номер телефона (или другое свойство) невозможно. В документации мы читаем:

CNContact Предикаты

Предикаты для соответствия контактов. Эти предикаты можно использовать только с CNContactStore и CNContactFetchRequest.

  • predicateForContactsMatchingName: возвращает предикат, чтобы найти контакты, соответствующие указанному имени.
  • predicateForContactsWithIdentifiers: возвращает предикат, чтобы найти контакты, соответствующие указанным идентификаторам.
  • predicateForContactsInGroupWithIdentifier: возвращает предикат, чтобы найти контакты, являющиеся членами указанной группы.
  • predicateForContactsInContainerWithIdentifier: возвращает предикат, чтобы найти контакты в указанном контейнере.

И дополнительно:

Составные сказуемые не поддерживаются.

Таким образом, единственный способ сделать фильтрацию - опустить добавление в массив результатов контактов без телефонных номеров. Это можно сделать, например, в блоке enumerateContactsWithFetchRequest.

0

использовать следующий метод и импортировать

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


-(void)contactsDetailsFromPhoneContactBook{ 
    CNContactStore *store = [[CNContactStore alloc] init]; 
    [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) { 
     if (granted == YES) { 
      //keys with fetching properties 
      NSArray *keys = @[CNContactFamilyNameKey,CNContactGivenNameKey]; 
      NSString *containerId = store.defaultContainerIdentifier; 
      NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId]; 
      NSError *error; 
      NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error]; 
      if (error) { 
       NSLog(@"error fetching contacts %@", error); 
      } else { 
       NSString *fullName; 
       NSString *firstName; 
       NSString *lastName; 
       for (CNContact *contact in cnContacts) { 
        // copy data to my custom Contacts class. 
        firstName = contact.givenName; 
        lastName = contact.familyName; 
        if (lastName == nil) { 
         fullName=[NSString stringWithFormat:@"%@",firstName]; 
        }else if (firstName == nil){ 
         fullName=[NSString stringWithFormat:@"%@",lastName]; 
        } 
        else{ 
         fullName=[NSString stringWithFormat:@"%@ %@",firstName,lastName]; 
        } 
        [self.contactsArray addObject:fullName]; 

        NSLog(@"working or not %@",self.contactsArray); 
       } 

      } 
     } 
    }]; 
} 
+0

Ну, похоже, это все контакты, независимо от того, есть ли у них номер телефона или нет. – Eir

0

Используйте ниже код для извлечения контакта с именем и детали

#import <AddressBook/ABAddressBook.h> 
#import <AddressBookUI/AddressBookUI.h> 

-(NSMutableArray*)fetchContactList{ 
    ABAddressBookRef addressBook = ABAddressBookCreate(); 

    __block BOOL accessGranted = NO; 

    if (&ABAddressBookRequestAccessWithCompletion != NULL) { // We are on iOS 6 
     dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 

     ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { 
      accessGranted = granted; 
      dispatch_semaphore_signal(semaphore); 
     }); 

     dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 
    } 

    else { // We are on iOS 5 or Older 
     accessGranted = YES; 
     [self getContactsWithAddressBook:addressBook]; 
    } 

    if (accessGranted) { 
     return [self getContactsWithAddressBook:addressBook]; 
    } 
    return [[NSMutableArray alloc] init]; 
} 
// Get the contacts. 
- (NSMutableArray*)getContactsWithAddressBook:(ABAddressBookRef)addressBook { 

    NSMutableArray *contactList = [[NSMutableArray alloc] init]; 
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook); 
    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook); 

    NSMutableArray *arrWithoutPhoneContact = [[NSMutableArray alloc] init]; 

    for (int i=0;i < nPeople;i++) { 
     NSMutableDictionary *dOfPerson=[NSMutableDictionary dictionary]; 

     ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i); 

     //For username and surname 
     ABMultiValueRef phones =(__bridge ABMultiValueRef)((__bridge NSString*)ABRecordCopyValue(ref, kABPersonPhoneProperty)); 

     CFStringRef firstName, lastName; 
     firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty); 
     if (firstName == nil) { 
      firstName = CFStringCreateWithCString (NULL, "", kCFStringEncodingUTF8);; 
     } 
     lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty); 
     if (lastName == nil) { 
      lastName = CFStringCreateWithCString (NULL, "", kCFStringEncodingUTF8);; 
     } 
     [dOfPerson setValue:[NSString stringWithFormat:@"%@", firstName] forKey:@"name"]; 

     //For Email ids 
     ABMutableMultiValueRef eMail = ABRecordCopyValue(ref, kABPersonEmailProperty); 
     if(ABMultiValueGetCount(eMail) > 0) { 
      [dOfPerson setValue:(__bridge NSString *)ABMultiValueCopyValueAtIndex(eMail, 0) forKey:@"email"]; 
     } 

     NSData *imgData = (__bridge NSData *)(ABPersonCopyImageData(ref)); 
     UIImage *imgProfile = [[UIImage alloc] initWithData:imgData]; 
     if (imgProfile != nil) { 
      [dOfPerson setValue:imgProfile forKey:@"image"]; 
     }else{ 
      [dOfPerson setValue:[UIImage imageNamed:@"DefaultProfile"] forKey:@"image"]; 
     } 

     //For Phone number 
     NSString* mobileLabel; 
     if (ABMultiValueGetCount(phones)) { 
      for(CFIndex j = 0; j < ABMultiValueGetCount(phones); j++) { 
       mobileLabel = (__bridge NSString*)ABMultiValueCopyLabelAtIndex(phones, j); 
       if([mobileLabel isEqualToString:(NSString *)kABPersonPhoneMobileLabel]) 
       { 
        [dOfPerson setValue:[Utility cleanedPhoneNumber:(__bridge NSString*)ABMultiValueCopyValueAtIndex(phones, j)] forKey:@"Phone"]; 
       } 
       else if ([mobileLabel isEqualToString:(NSString*)kABPersonPhoneIPhoneLabel]) 
       { 
        [dOfPerson setValue:[Utility cleanedPhoneNumber:(__bridge NSString*)ABMultiValueCopyValueAtIndex(phones, j)] forKey:@"Phone"]; 
        break ; 
       }else{ 
        [dOfPerson setValue:[Utility cleanedPhoneNumber:(__bridge NSString*)ABMultiValueCopyValueAtIndex(phones, j)] forKey:@"Phone"]; 
       } 
      } 
     }else{ 
      NSLog(@"else"); 
      [arrWithoutPhoneContact addObject:[NSString stringWithFormat:@"%d",i]]; 
     } 


     //Contact Id 
     ABRecordID recordID = ABRecordGetRecordID(ref); 
     [dOfPerson setValue:[NSString stringWithFormat:@"%d",recordID] forKey:@"contactId"]; 

     [contactList addObject:dOfPerson]; 

    } 

    NSLog(@"Withot Phone %@", arrWithoutPhoneContact); 
    for (int j = 0; j < arrWithoutPhoneContact.count; j++) { 
     [contactList removeObjectAtIndex:[[arrWithoutPhoneContact objectAtIndex:j] intValue] - j]; 
    } 
    NSLog(@"Contacts = %@",contactList); 
    return contactList; 
} 
1
#import <Contacts/Contacts.h> 


CNContactStore *store = [[CNContactStore alloc] init]; 
    [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) { 
     if (granted == YES) { 
      //keys with fetching properties 
      NSArray *keys = @[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey, CNContactEmailAddressesKey]; 
      CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys]; 
      request.sortOrder = CNContactSortOrderGivenName; 
      request.unifyResults = YES; 
      NSError *error; 

      __block NSString* email; 

      BOOL success = [store enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * __nonnull contact, BOOL * __nonnull stop) 
          { 
           if (error) { 
            NSLog(@"error fetching contacts %@", error); 
           } else { 
            NSString *fullName; 
            NSString* phone; 

            //     for (CNContact *contact in cnContacts) { 
            DeviceContact *aContact = [DeviceContact new]; 

            // copy data to my custom Contacts class. 
            NSString *firstName = contact.givenName; 
            NSString *lastName = contact.familyName; 

            if (lastName == nil) { 
             fullName=[NSString stringWithFormat:@"%@",firstName]; 
            }else if (firstName == nil){ 
             fullName=[NSString stringWithFormat:@"%@",lastName]; 
            } 
            else{ 
             fullName=[NSString stringWithFormat:@"%@ %@",firstName,lastName]; 
            } 

            if ([firstName trim].length > 0) { 
             aContact.nameForSorting = firstName; // 141116 
            }else if ([lastName trim].length>0 && aContact.nameForSorting.length<=0) { 
             aContact.nameForSorting = lastName; // 141116 
            } 

            aContact.name = fullName; 


            if (contact.phoneNumbers!=nil && [contact.phoneNumbers count]>0) { 
             for (CNLabeledValue *label in contact.phoneNumbers) { 
              phone = [CommonUtils removeAllSpecialCharactersFromPhoneNumber:[label.value stringValue]]; 
              if ([phone length] > 0) { 
               [aContact.phoneNumber addObject:phone]; 
              } 
             } 
            } 

            ////Get all E-Mail addresses from contacts 
            /// if ([CommonUtils checkIsNullObject:[contact emailAddresses]] && [[contact emailAddresses] count]>0) { 
            for (CNLabeledValue *label in contact.emailAddresses) { 
             email = label.value; 
             if ([email length] > 0) 
             { 
              [aContact.email addObject:email]; 
             } 
            } 
            // } 

            // 141116 
            if ([aContact.name trim].length <= 0) { 
             if (aContact.email.count>0) { 
              aContact.name = [aContact.email objectAtIndex:0]; 
             }else if (aContact.phoneNumber.count>0){ 
              aContact.name = [aContact.phoneNumber objectAtIndex:0]; 
             } 
            } 
            if ([aContact.nameForSorting trim].length <= 0){ 
             if (aContact.email.count>0) { 
              aContact.nameForSorting = [aContact.email objectAtIndex:0]; 
             }else if (aContact.phoneNumber.count>0){ 
              aContact.nameForSorting = [aContact.phoneNumber objectAtIndex:0]; 
             } 
            } 

            [self.arrAllContacts addObject:aContact]; 
           } 

          }]; 

      if(success){ 

       dispatch_async(dispatch_get_main_queue(), ^{ 
        [CommonUtils hideLoader]; 

        completionhandler(self.arrAllContacts); 
       }); 
      } 
     } 
     else 
     { 
      // [CommonUtils showAlertMessageWithMessage:@"fdfdggfsgfdgfd" withDelegate:self withCancelTitle:OKAY isOtherButton:NO withOtherButtonTitle:nil withTag:0]; 
      [CommonUtils hideLoader]; 

     } 
    }]; 
+0

Я добавил к этому решению плюс, потому что он приятный и чистый. Тем не менее, я не отмечаю это как принятый ответ, потому что я просил об устранении бесстыдных контактов в момент получения, когда делал запрос. Возможно, это невозможно. Если это так, это будет правильный ответ на мой вопрос. – Eir

+0

Несмотря на то, что в вашем коде, в конце концов, вы получаете также контакты без телефонных номеров. – Eir