Anyone luck using CNContactMBS?

I’m trying to modernize an app using ABAddressBook to CNContact framework.
Which is giving me troubles.

Var keys() As String = app.cstore.AllFetchKeys

produces an exception:

A Cocoa NSInvalidArgumentException was not handled: -[CNAggregateKeyDescriptor length]: unrecognized selector sent to instance 0x600001ae4b20

And trying to use a predicate

Var pred As NSPredicateMBS = CNContactMBS.predicateForContactsMatchingName(s)
Var result() As CNContainerMBS = app.cStore.containersMatchingPredicate (pred,error)

results in

Error Domain=CNErrorDomain Code=400 “Ungültiges Prädikat” UserInfo={NSLocalizedDescription=Ungültiges Prädikat, NSLocalizedFailureReason=Der Vorgang konnte nicht abgeschlossen werden, da das Prädikat ungültig ist.} (Invalid predicate)

Any ideas what I might be doing wrong?

Nothing. Apple changed this key to not be a string :frowning:

You mean I should install the next PR? :wink:

no. Give me time to change plugin…

That’s what I meant. I know your speed. :smile:
Take your time, not urgent for me.

Sure, will not go in 20.4, but 20.5pr1.

2 Likes

Problem fixed. I’ll send you an email with fixed plugin.

1 Like

Thanks, working!
The class predicate still gives me that error, but I think I should be able to move around that by setting up a custom predicate.

That works now. Thanks a lot, Christian!

Var s As String = Me.View.StringValue
Var error As  NSErrorMBS 
If Not s.IsEmpty Then
  Var keys() As String = app.cstore.AllFetchKeys
  Var buffer() As CNKeyDescriptorMBS
  For Each k As String In keys
    Var desc As New CNKeyDescriptorMBS(k)
    buffer.Append desc
  Next
  Var req As New CNContactFetchRequestMBS(buffer)
  req.predicate = CNContactMBS.predicateForContactsMatchingName(s) 
  Var result() As CNContactMBS = app.cStore.ContactsWithFetchRequest(req, error)
  If error <> Nil Then
    MessageBox error.Description+EndOfLine+error.LocalizedDescription
  Else
    For Each c As CNContactMBS In result
      If Not c.familyName.IsEmpty Then 
        Break
      End If
    Next
  End If
End If

BTW: CNContact gained more class predicate methods, like search for phone number or email. No hurry at all, but if you should have list of future additions …
Also, with ObjCBlock being a part of Xojo now, I wonder if block callbacks would be possible.

I can add more if needed.
Let me know.

And the plugins does the blocks thread safe, which is difficult in pure Xojo.

Predicate functions for email and phone number are also added.

1 Like

A chance to have an example with next release ?

1 Like

Should work quite similar to this one. s being the search string.

for matching by name:

Dim keysToFetch() As CNKeyDescriptorMBS
keysToFetch.append CNContactVCardSerializationMBS.descriptorForRequiredKeys

Dim predicate As NSPredicateMBS = CNContactMBS.predicateForContactsMatchingName("Peter")

Dim error As NSErrorMBS
Dim contacts() As CNContactMBS  = m.unifiedContactsMatchingPredicate(predicate, keysToFetch, error)

If error <> Nil Then
  List.AddRow "Error: "+error.LocalizedDescription
Else
  List.AddRow Str(contacts.Ubound+1)+" contacts found"
End If

for email similar:

Dim keysToFetch() As CNKeyDescriptorMBS
keysToFetch.append CNContactVCardSerializationMBS.descriptorForRequiredKeys

Dim predicate As NSPredicateMBS = CNContactMBS.predicateForContactsMatchingEmailAddress("test@test.test")

Dim error As NSErrorMBS
Dim contacts() As CNContactMBS  = m.unifiedContactsMatchingPredicate(predicate, keysToFetch, error)

If error <> Nil Then
  List.AddRow "Error: "+error.LocalizedDescription
Else
  List.AddRow Str(contacts.Ubound+1)+" contacts found"
End If

and for phone number:

Dim keysToFetch() As CNKeyDescriptorMBS
keysToFetch.append CNContactVCardSerializationMBS.descriptorForRequiredKeys

Dim phone As New CNPhoneNumberMBS("123456789‬")
Dim predicate As NSPredicateMBS = CNContactMBS.predicateForContactsMatchingPhoneNumber(phone)

Dim error As NSErrorMBS
Dim contacts() As CNContactMBS  = m.unifiedContactsMatchingPredicate(predicate, keysToFetch, error)

If error <> Nil Then
  List.AddRow "Error: "+error.LocalizedDescription
Else
  List.AddRow Str(contacts.Ubound+1)+" contacts found"
End If
1 Like

Found another wish, Christian: Would it be possible to add a delegate and a propertySelected event to CSContactViewControllerMBS? I’d like to add custom actions and this seems to be the only way.

What item exactly?
I don’t find a propertySelected thing in Apple’s framework.

We have

DidSelectContactProperty(contactProperty as CNContactPropertyMBS)

in CNContactPickerMBS class.

Yes. But CNContactPicker doesn’t show a single card and its properties, or am I missing something?

(And in the same manner I meant to use the delegate for an artificial event. There is indeed no propertySelected API item. In your naming style the same name as for the ContactPicker ever would be great.)

Edit: Oh I see. I can set display keys in ContactPicker as well.

if something is missing, let me know.