unifiedContacts identifier vs contactRelations identifier

The documentation specifies that when Contacts framework returns unified contacts that each fetched unified contact object (CNContact) has its own unique identifier that’s different from any individual contact’s identifier in the set of linked contacts and that when refetching a unified contact, that this identifier should be used.

There is also an analogous identifier within the list of contactRelations, but each of these don't seem to corespondent to the unified contacts. For example, is a new contact (Sheryl Zakroff) is created in the simulator Contacts and their spouse is set to Hank Zakroff. However, the GUID created for the contactRelations identifier does not correlate to the original Hank Zakroff GUID and cannot be searched.

Is this a bug or what is the indent of the contactRelations identifier?

Here's a debug output of walking the unifiedContacts:

Name: Hank Zakroff
      2E73EE73-C03F-4D5F-B1E8-44E85A70F170
- Other : (555) 766-4823
- Other : (707) 555-1854
Name: David Taylor
      E94CD15C-7964-4A9B-8AC4-10D7CFB791FD
- Other : 555-610-6679
Name: Sheryl Zakroff
      DE783BC8-7917-4138-93F6-3AF0FD4CE083
- Other : (707) 555-1854
- Spouse: <CNContactRelation: 0x60000000dd60: name=Hank M. Zakroff>
-         534B467D-CA00-46D3-897C-16EEA782C9CF
 - Looking for ["534B467D-CA00-46D3-897C-16EEA782C9CF"]
[]

Is there a better channel or documentation to understand the details of relationship between the GUID for unifiedContacts identifier vs contactRelations identifier?

Does anyone monitor these queries?

We are looking into your issue. Stay tuned.

The contact relation field is a name (a string), not a reference to another card.

Where or how are you getting your mentioned identifier?

Here's the test code where I was attempting to find the relationship between records.

//  ContentView.swift
//  TestContactsProject
//

import SwiftUI
import Contacts

import OSLog

extension Logger {
    private static var subsystem = Bundle.main.bundleIdentifier ?? "com.myelin.TestContactsProject"
    static let logic = Logger(subsystem: subsystem, category: "logic")
    static let analitics = Logger(subsystem: subsystem, category: "analitics")
}

struct ContentView: View {
    
    var body: some View {
        Text("Hello, World!")
            .padding()
            .onAppear {
                Task.init {
                    await fetchAllContacts()
                    //await fetchSpecificContacts()
                }
            }
        
    }
    func fetchSpecificContacts(keyStrings: [String]) {
        // Run this in the background async
        
        // Get access to the Contacts Store
        let store = CNContactStore()
        
        // Keys to fetch
        let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey, CNContactIdentifierKey, CNContactRelationsKey] as [CNKeyDescriptor]
        
        // Search criteria
        let predicate = CNContact.predicateForContacts(withIdentifiers: keyStrings)
        
        do {
            // Perform fetch
            Logger.logic.trace( " - Looking for \(keyStrings)" )
            let contacts = try store.unifiedContacts(matching: predicate, keysToFetch: keys)
            
            Logger.logic.trace ("\(contacts)")
        }
        catch {
            // If there was an error, Handle it here
            Logger.logic.trace("Error")
        }
    }
    
    func fetchAllContacts() async {
        // Run this in the background async
        
        // Get access to the Contacts Store
        let store = CNContactStore()
        
        // Specify which data keys we want to fetch
        let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey, CNContactIdentifierKey, CNContactRelationsKey] as [CNKeyDescriptor]
        
        // Create Fetch Request
        let fetchRequest = CNContactFetchRequest(keysToFetch: keys)
        fetchRequest.unifyResults = false 
        
        // CHANGE - Try to find a way to look for both unified and non-unified contacts
        //      per https://developer.apple.com/forums/thread/694471?answerId=694923022#694923022
        
        // Specify which data keys we want to return
        do {
            try store.enumerateContacts(with: fetchRequest, usingBlock: { contact, results in
                
                // Do something with the contact
                Logger.logic.trace("Name: \(contact.givenName) \(contact.familyName)")
                Logger.logic.trace("      \(contact.id)")
                for number in contact.phoneNumbers {
                    switch number.label {
                    case CNLabelPhoneNumberMobile:
                        Logger.logic.trace("- Mobile: \(number.value.stringValue)")
                    case CNLabelPhoneNumberMain:
                        Logger.logic.trace("- Main  : \(number.value.stringValue)")
                    default:
                        Logger.logic.trace("- Other : \(number.value.stringValue)")
                        
                    }
                
                    for relation in contact.contactRelations {
                        switch relation.label {
                        case CNLabelContactRelationSpouse:
                            Logger.logic.trace("- Spouse: \(relation.value)")
                            Logger.logic.trace("-         \(relation.identifier)")
                            fetchSpecificContacts(keyStrings: [relation.identifier])
                        case CNLabelContactRelationMother:
                            Logger.logic.trace("- Mother: \(relation.value)")
                            Logger.logic.trace("-         \(relation.identifier)")
                            fetchSpecificContacts(keyStrings: [relation.identifier])
                        default:
                            Logger.logic.trace("- Other: \(relation.value)")
                            Logger.logic.trace("-        \(relation)")
                            Logger.logic.trace("-        \(relation.identifier)")
                        }
                    }
                }
            })
        } catch {
                    // If there was an error, Handle it here
            Logger.logic.trace("Error")
                }
            }
        }
        
        struct ContentView_Previews: PreviewProvider {
            static var previews: some View {
                ContentView()
            }
        }
unifiedContacts identifier vs contactRelations identifier
 
 
Q