2012-09-22 31 views
6

Tôi muốn người dùng của mình điền vào trường email bằng cách chọn email của người liên hệ từ sổ địa chỉ của họ. Tôi không muốn họ cuộn tất cả các địa chỉ liên hệ có email không được đặt, vì vậy tôi muốn lọc những địa chỉ liên hệ có địa chỉ email.Làm cách nào để yêu cầu ABPeoplePickerNavigationController chỉ liệt kê các liên hệ có địa chỉ email?

Đây là mã tôi đã viết cho đến thời điểm này. Tôi có thể tìm ra ai có địa chỉ email và ai không có nhưng tôi không thể nói số ABPeoplePickerNavigationController để chỉ liệt kê các liên hệ phù hợp. Là nó không thể đạt được điều này, tôi có nghĩa là tôi phải thực hiện lớp chọn liên hệ của riêng tôi bằng cách sử dụng một bảng xem hoặc là có cái gì đó sai với đoạn mã này?

ABAddressBookRef addressBook = ABAddressBookCreate(); 
NSArray *peopleList = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); 
NSLog(@"%ld people exist in the addressBook", ABAddressBookGetPersonCount(addressBook)); 
for (id peopleRecord in peopleList) { 
    ABMultiValueRef mv = ABRecordCopyValue((ABRecordRef)peopleRecord, kABPersonEmailProperty); 
    CFIndex numberOfAddresses = ABMultiValueGetCount(mv); 
    if(numberOfAddresses == 0) { 
     CFErrorRef err; 
     ABAddressBookRemoveRecord(addressBook, (ABRecordRef)peopleRecord, &err); 
    } 
} 
[peopleList release]; 

NSLog(@"%ld people have an email", ABAddressBookGetPersonCount(addressBook)); 

ABPeoplePickerNavigationController *peoplePicker = [[ABPeoplePickerNavigationController alloc] init]; 
NSNumber* emailProp = [NSNumber numberWithInt:kABPersonEmailProperty]; 
[peoplePicker setAddressBook:addressBook]; 
peoplePicker.displayedProperties = [NSArray arrayWithObject:emailProp]; 
[peoplePicker setPeoplePickerDelegate:self]; 
[self presentModalViewController:peoplePicker animated:YES]; 

Trả lời

1

Tôi không tin rằng có cách để giúp iOS thực hiện việc lọc này. Tôi làm điều đó trong mã quá. Lưu ý rằng bạn cần phải tìm tất cả các loại địa chỉ email - bạn phải lặp qua từ điển mà bạn có thể nhận được. Làm việc với điều này là một PITA chắc chắn - tôi đã thực hiện nó trước đây - và bạn phải cẩn thận để không bị rò rỉ bộ nhớ.

Những gì tôi làm là bạn đề xuất - lặp lại thông qua tất cả liên hệ, sau đó tôi bật chế độ xem với một bảng và sau đó chọn tên của những người họ muốn. Tôi giữ liên kết xung quanh để tôi biết địa chỉ nào được liên kết với tên nào, sau đó sử dụng khung email hệ thống và sau đó điền địa chỉ gửi đến.

+0

OK, cảm ơn đề xuất! – aslisabanci

15

Tôi biết điều này là cũ, nhưng tôi tình cờ gặp vấn đề này trong khi nghiên cứu một chủ đề liên quan, vì vậy tôi nghĩ tôi sẽ cập nhật điều này với những phát hiện của mình.

  1. Trong khi nó không lọc các kết quả, nó có giá trị lưu ý rằng iOS 8 có một tính năng cho việc vô hiệu hóa địa chỉ liên lạc mà không có địa chỉ email:

    peoplePickerController.predicateForEnablingPerson = [NSPredicate predicateWithFormat:@"[email protected] > 0"]; 
    

    Bạn vẫn thấy tất cả các địa chỉ liên hệ, nhưng ít nhất những người không có địa chỉ email bị vô hiệu hóa. Rõ ràng, nếu hệ điều hành mục tiêu tối thiểu của bạn xảy ra trước iOS 8, bạn muốn làm các việc trên có điều kiện:

    if ([peoplePickerController respondsToSelector:@selector(predicateForEnablingPerson)]) { 
        peoplePickerController.predicateForEnablingPerson = [NSPredicate predicateWithFormat:@"[email protected] > 0"]; 
    } 
    
  2. Nếu bạn muốn lọc ra những mục không có địa chỉ, bạn sẽ phải trình bày giao diện người dùng riêng của bạn (ví dụ như tạo tableview của riêng bạn) cho việc này. Vì vậy, đầu tiên, xây dựng mảng riêng của bạn về địa chỉ liên lạc với địa chỉ email như vậy:

    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { 
        if (granted) { 
         NSArray *allPeople = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook)); 
         NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id person, NSDictionary *bindings) { 
          ABMultiValueRef emails = ABRecordCopyValue((__bridge ABRecordRef)person, kABPersonEmailProperty); 
          NSInteger count = ABMultiValueGetCount(emails); 
          CFRelease(emails); 
          return count > 0; 
         }]; 
    
         NSArray *peopleWithEmails = [allPeople filteredArrayUsingPredicate:predicate]; 
    
         // You now have an array of `ABRecordRef` associated with 
         // those contacts with email addresses. You can use this as 
         // the model backing your own table view, or populate your 
         // own model. 
        } else { 
         NSLog(@"Access not granted"); 
         if (error) { 
          CFRelease(error); 
         } 
        } 
    }); 
    

    Sau khi làm điều đó, sau đó bạn có thể xây dựng tableview của riêng bạn liệt kê các chi tiết có liên quan từ peopleWithEmails đó.

+0

Lưu ý, mã dưới điểm 2 dành cho iOS 6 trở lên. Nếu bạn cần hỗ trợ cho các phiên bản iOS cũ hơn, bạn không kiểm tra sự cho phép với 'ABAddressBookRequestAccessWithCompletion'. – Rob