Bug 32634 - Binding issue in the CNContactStore.GetUnifiedContacts method
Summary: Binding issue in the CNContactStore.GetUnifiedContacts method
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: XI 8.99 (iOS9 previews)
Hardware: PC Mac OS
: High major
Target Milestone: Untriaged
Assignee: Sebastien Pouliot
Depends on:
Reported: 2015-07-30 15:55 UTC by Kevin Mullins
Modified: 2015-08-01 11:19 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Kevin Mullins 2015-07-30 15:55:52 UTC
Yeah, the binding is unusable in some areas. For example: `CNContactStore.GetUnifiedContacts` is mapped in such a way it can’t be called from Xamarin.iOS. It’s trying to enforce an interface (`ICNKeyDescriptor`) in the wrong way.

Kevin Mullins
So in Swift they do this:

let store = CNContactStore()
let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName("Appleseed"), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey])

Which doesn’t work in C#:
var predicate = new CNContact().GetPredicateForContacts("Appleseed”);
var fetchKeys = new NSObject[] {CNContactKey.GivenName, CNContactKey.FamilyName};
var store = new CNContactStore();
NSError error;
var contacts = store.GetUnifiedContacts(predicate, fetchKeys, out error);
Comment 1 Sebastien Pouliot 2015-07-30 17:16:58 UTC
In the headers the CNKeyDescriptor (protocol) is kind of given to NSString (thru a category).

/*! This protocol is reserved for Contacts framework usage. */
@protocol CNKeyDescriptor <NSObject, NSSecureCoding, NSCopying>

/*! Allows contact property keys to be used with keysToFetch. */
@interface NSString (Contacts) <CNKeyDescriptor>

That's why it works in swift and, right now, we missing the 2nd piece.
Comment 2 Sebastien Pouliot 2015-07-30 22:33:40 UTC
There's no cute way to generated this (at least automatically). We might have to bind a general/internal version (using plain NSObject) and make public a version similar to:

public void GetUnifiedContacts<T>(...) where T : NSObjectProtocol, NSSecureCoding, NSCopying
Comment 3 Sebastien Pouliot 2015-07-31 10:50:03 UTC
This will work in the next preview

	var fetchKeys = new [] { CNContactKey.GivenName, CNContactKey.FamilyName };
	NSError error;
	using (var predicate = CNContact.GetPredicateForContacts ("Appleseed"))
	using (var store = new CNContactStore ())
		var contacts = store.GetUnifiedContacts (predicate, fetchKeys, out error);

just need to review all API using CNKeyDescriptor...
Comment 4 Sebastien Pouliot 2015-08-01 11:19:54 UTC
Fixed in maccore/xcode7 fdc62b1338513913ece91dbdcab126573506ac8d