How to find a specific contact in INSendPaymentIntent (SiriKit)?

Summary I
tried to code INSendPaymentIntent, but I had problems with the differences between contacts using the same name. Siri seems to be looping right afterINPersonResolutionResult.disambiguation(with: matchedContacts)

Thoughts behind the code
I decided to use the contact name to search for contacts initially, as using the display name INPersonreturns the first contact that matches the query if the user specifies only the name. (ie, "Pay Kevin $ 50" will automatically select Kevin Bacon over Kevin Spacey).

Unfortunately, using this name sends Siri into a loop, asking the user to set the contact again and again ...

Question
Is there a way to search for contacts through a contact name without sending Siri in a loop?

The code

func resolvePayee(forSendPayment intent: INSendPaymentIntent, with completion: (INPersonResolutionResult) -> Void) {
    if let payee = intent.payee {
        var resolutionResult: INPersonResolutionResult?
        var matchedContacts: [INPerson] = []
        let predicate = CNContact.predicateForContacts(matchingName: (payee.nameComponents?.givenName)!)

        do {
            let searchContactsResult = try CNContactStore().unifiedContacts(matching: predicate, keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactMiddleNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey, CNContactIdentifierKey])
            for contact in searchContactsResult {
                matchedContacts.append(createContact((contact.phoneNumbers.first?.value.stringValue)!, contact: contact))
            }
        } catch {
            completion(INPersonResolutionResult.unsupported())
        }

        switch matchedContacts.count {
            case 2 ... Int.max:
                resolutionResult = INPersonResolutionResult.disambiguation(with: matchedContacts)
            case 1:
                let recipientMatched = matchedContacts[0]
                print("Matched a recipient: \(recipientMatched.displayName)")
                resolutionResult = INPersonResolutionResult.success(with: recipientMatched)
            case 0:
                print("This is unsupported")
                resolutionResult = INPersonResolutionResult.unsupported()
            default:
                break
        }

        completion(resolutionResult!)
    } else {
        completion(INPersonResolutionResult.needsValue())
    }
}
+4
source share
1 answer

Siri will ask you to confirm the person’s name when you return it:

completion(INPersonResolutionResult.needsValue())

Or that:

completion(INPersonResolutionResult.disambiguation(with: matchedContacts))

In this case, I think it is more likely that it goes into a loop because you were returning a second result ( INPersonResolutionResult.disambiguation). This means that your query on this line continued to return 2 or more people:

let searchContactsResult = try CNContactStore().unifiedContacts(matching: predicate, keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactMiddleNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey, CNContactIdentifierKey])

I suggest you debug this line and see if you tell Siri about this value:

INPersonResolutionResult.success
+1
source

Source: https://habr.com/ru/post/1650173/


All Articles