How to filter contacts using a set of phone numbers with CNContactPickerViewController?

寵の児 提交于 2019-12-11 00:26:23

问题


I try to filter some contacts from address book with a set of existing phone numbers. CNContactPickerViewController should disable selection of these contacts when they have matching phone number from existing phone numbers.

I need to use phone number as a filter because these phone number can be from other app platforms. And the service should not allow user to use contact with same phone number that is already existed. I don't want to create my own contact picker for just this quick action.

Here is what I've tried so far.

NSArray<CNPhoneNumber *> *existingPhoneNumbers = @[@"1111", @"2222"];

CNContactPickerViewController *contactPicker = [[CNContactPickerViewController alloc] init];
contactPicker.delegate = self;
contactPicker.displayedPropertyKeys = @[CNContactNamePrefixKey,
                                        CNContactGivenNameKey,
                                        CNContactFamilyNameKey,
                                        CNContactOrganizationNameKey,
                                        CNContactPhoneNumbersKey];

NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:@"NOT (ANY phoneNumbers.value.stringValue IN %@)", existingPhoneNumbers];

contactPicker.predicateForEnablingContact = predicates;

Error message:

[CNUI ERROR] Error when showing picker: Error Domain=CNErrorDomain Code=300 "(null)" UserInfo={CNValidationErrors=(
"Error Domain=CNErrorDomain Code=400 \"Invalid Predicate\" UserInfo={CNKeyPaths=(\n    \"phoneNumbers.value.stringValue\"\n), NSLocalizedDescription=Invalid Predicate, NSLocalizedFailureReason=The operation couldn't be completed because its predicate is invalid.}")}

With SUBQUERY it is still not working.

NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:@"SUBQUERY(phoneNumbers, $CNLabeledValue,$CNLabeledValue.value.stringValue IN %@).@count == 0"];

Error message:

[CNUI ERROR] Error when showing picker: Error Domain=CNErrorDomain Code=300 "(null)" UserInfo={CNValidationErrors=(
"Error Domain=CNErrorDomain Code=400 \"Invalid Predicate\" UserInfo={CNKeyPaths=(\n    \"value.stringValue\"\n), NSLocalizedDescription=Invalid Predicate, NSLocalizedFailureReason=The operation couldn't be completed because its predicate is invalid.}")}

Also tried with predicateWithBlock:. It doesn't support block-based predicate at all.

From WWDC 2015 Introducing the Contacts Framework for iOS and OS X session. They said predicateForEnablingContact is evaluated on 'CNContact'. The document doesn't say that predicate must be from CNContact+Predicates like CNContactFetchRequest does.


回答1:


Already found the issue. My hair almost fell out when I encoutered this problem. The solution is to add apostrophe to value. Like this

let predicate = NSPredicate(format: "ANY self.phoneNumbers.'value'.'digits' BEGINSWITH %@", "+420" 

I hope this helps you.




回答2:


I hope you've found the solution you were looking for. I'm going to share how I've dealt with this kind of issue. It may help others.

I wanted to limit the CNContactPickerViewController to show only contacts, let's say the only contacts(phone numbers) I have in a set. So basically, unlike your case, I wanted to show only existing users. So, In viewDidLoad...

let exsitingNumbers = Set(["1111", "2222"])
let predicate = NSPredicate(format: "SUBQUERY(phoneNumbers, $x, $x.'value'.'stringValue' IN %@).@count > 0", exsitingNumbers)
self.contactPicker.predicateForEnablingContact = predicate

For more details about SUBQUERY in NSPredicate, take a look at it.



来源:https://stackoverflow.com/questions/37481483/how-to-filter-contacts-using-a-set-of-phone-numbers-with-cncontactpickerviewcont

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!