Obtaining CNContact from CNContactRelation - ios

I am trying to obtain all related contacts to a selected contact. The way to do this seems to be via mycontact.contactRelations. This gives an array of CNLabeledValue with each of those containing a CNContactRelation as their value. There is then a name property, but it appears nothing else.
The Xamarin documentation for CNContact.ContractRelations seems to suggest I should be able to obtain the corresponding CNContact from a CNContactRelation but I can see no way to do this in objc, other than searching for a contact with a matching name. This may or may not be the contact I'm after, even if they also have a relationship to a contact with the same name as mycontact.
The identifier on the CNLabeledValue seems to refer to the label rather than the related contact, or at least doesn't seem to match the identifier if I select that contact from a CNContactPickerViewController.
Is there a way to obtain the CNContact for the related contact in objc ?

The related names field in Contacts doesn't store linkages, just names. You'll notice this from a user perspective if you go to edit related names in the iOS or OS X Contacts app — it's just a freeform text field. Those apps (and other system apps) will recognize when a related name matches that of another contact (which is why you can ask Siri to call your mother, etc), but they also let you put down names for people you don't have contact info for.
So a CNContactRelation just contains a string, and the only way to find (if there are any) contacts matching a related name is to search the contact store. Use unifiedContactsMatchingPredicate:keysToFetch:error: to search, with a predicate constructed by calling predicateForContactsMatchingName:.

Related

Update existing 'Contacts' Phone number?

I have code to fetch and display User data from Contacts (various Name properties plus the array of Phone numbers). By making a CNMutableContact, I can update any of the Name properties. But I can only display Phone numbers (from CNLabeledValue via ".digits"). Is it possible to also update Phone numbers? I can't change "digits" in the CNMutableContact because it is 'read-only'. I have seen and understand cautions on accessing CNLabeledValue "digits", but would still like to proceed.
Suggestions?
Maybe is a little late to answer this question. However, on the given exemple, you can only add phone numbers. So, to update phone you would, at best, replace removing phone numbers and add new ones.
Replacing a phonenumber entry in this approach would result in changing the phonenumber's identifier.
This should be not the behaviour you are expecting, since you are changing a phone number of an existing entry. And we want to keep the phone identifier intact.
You should use settingValue from CNLabeledValue see: Apple Documentation
// Clone to a mutable contact
let mutableContact = contact.mutableCopy() as! CNMutableContact
// Here's the catch
let updatedPhone = mutableContact.phoneNumbers[0].settingValue(CNPhoneNumber(stringValue: "newPhone"))
// Be aware that in this example, I only have on phone number. For multiple phones, would need to handle multiple phones properly in the array.
mutableContact.phoneNumbers = [updatedPhone]

Firebase: Swift - Query value in child node without knowing the parent key

I have a firebase database which I have imported a list of approx. 8200 Universities with the details seen above.
I want to be able to enter an email address into a text field then query the "domain" part of this JSON. My issue is I need to query all the domains in the list of 8000, however I do not know how to search domain ad I do not have the "7542" to use a childByAppendingPath.
So I have a reference to "universities" but I need to be able to query "domain" without knowing the parent key (i.e. 7542 in the example above, but I want to search the domain, "iautb.ac.ir").
You need to create a reference and Query that reference, check this link to find more about how to retrieve data from firebase.
Basically you need to do something like this
let myRef = Firebase(url: "https://your.firebaseio.com/universities")
let query = myRef.queryOrderedByChild("domain").queryEqualToValue("yourDomainSearchValue")
and then observe the events you need to on your query

phone number predicate on CNContactStore

I am building an app in Swift. I would like to make predicate using a phoneNumber (as String) and retrieve the name of that contact -if it exists- from the CNContactStore. I can make a name predicate fairly easily by :
let pred = CNContact.predicateForContactsMatchingName(name: String)
But is there a way to do the same for a PhoneNumber. I can of course fetch the entire CNContactStore, loop through it and retrieve the contact. But I was wondering if there was any better way.
For anyone who sees this post.
In iOS11, Apple introduced this new method to fetch contact with phone number.
https://developer.apple.com/documentation/contacts/cncontact/3020511-predicateforcontacts
See:
https://nshipster.com/ios-12/
In short: you can't create a predicate to filter based on phone number. You have to pull all of the contacts and iterate. NOTE: For any given phone number, it 1) may not exist in contacts, or 2) exist more than once.
Check out this post:
https://forums.developer.apple.com/thread/19329

Is it possible to let ABPersonViewController display only a multivalued property with a specific label?

Assuming, I have an ABAddressBook with a person record that has a valid work address and an invalid home address.
I want to use an ABPersonViewController to let the user correct the invalid address. An ABPersonViewController has a property displayedProperties that allows to specify which properties are displayed. One can choose any ABPropertyID, among them kABPersonAddressProperty. If done so, the ABPersonViewController displays ALL addresses of the person record. Thus the user has no indication which one should be corrected.
I would like to specify that only an address with a specific label, say #"home" should be displayed. Is this possible?
It's not possible, as you've surmised. Beyond displayedProperties, the ABPersonViewController does not expose API for displaying only the kABHomeLabel property, say, of a multivalued property.

Google Contacts: Unique Contacts?

I am building an application that I will need to distinguish the Google Contacts from each other. I am just wondering, as long as google sends contacts as First Name/Last Name/mail.. etc (Example) without a unique ID, what will be the first approach to distinguish each contacts?
1) Should I create an ID based on the user's fields? -> by a minimal change, it can break down.
2) Should I create an ID based on First Name + Last Name? -> but most people can have duplicate contacts on their page, would that be a problem? Or married contacts, which can create a little mess.
The reason I am asking this I am trying to create relations and I need to store the data somewhere like that [person=Darth Vader, subject=Luke Skywalker, type=father(or son)], so I need a fast algorithm that can make a mapping for each contact and retrieve the related contacts fast.
I believe they do send back an ID. From the return schema:
<link rel='self' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/userEmail/full/contactId'/>
You could use the full HREF value as the ID, or parse out the contactID from the end of the URL, whichever you like better.

Resources