Last active
August 11, 2023 09:31
-
-
Save quintonpryce/1f6c2444a11e3ccb5f1d97cfb3018552 to your computer and use it in GitHub Desktop.
IntentHandler for INStartCallHandling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Contacts | |
import Intents | |
class IntentHandler: INExtension, INStartCallIntentHandling { | |
/// CNContactsStore implementation to get a person from contacts. | |
/// | |
/// See https://gist.github.com/quintonpryce/d69499bf40bdef208bd35d00aba188db | |
lazy var personProvider = IntentPersonProvider() | |
@available(iOSApplicationExtension 13.0, *) | |
func handle(intent: INStartCallIntent, completion: @escaping (INStartCallIntentResponse) -> Void) { | |
let userActivity = NSUserActivity(activityType: "INStartCallIntent") | |
guard intent.contacts?.first?.personHandle?.value != nil else { | |
completion(INStartCallIntentResponse(code: .failureContactNotSupportedByApp, userActivity: userActivity)) | |
return | |
} | |
let response = INStartCallIntentResponse(code: .continueInApp, userActivity: userActivity) | |
completion(response) | |
} | |
@available(iOSApplicationExtension 13.0, *) | |
func resolveContacts(for intent: INStartCallIntent, with completion: @escaping ([INStartCallContactResolutionResult]) -> Void) { | |
guard let contacts = intent.contacts else { | |
completion([.unsupported(forReason: .invalidHandle)]) | |
return | |
} | |
// Guard that there is only 1 contact. | |
guard contacts.count == 1 else { | |
completion([.unsupported(forReason: .multipleContactsUnsupported)]) | |
return | |
} | |
guard let person = contacts.first else { | |
completion([.unsupported(forReason: .invalidHandle)]) | |
return | |
} | |
let personHasPhoneNumber = person.personHandle?.value != nil | |
if personHasPhoneNumber { | |
completion([.success(with: person)]) | |
return | |
} | |
// Now we need to search the contacts for the user they specified. | |
let authorizedToUseContacts = CNContactStore.authorizationStatus(for: .contacts) == .authorized | |
guard authorizedToUseContacts else { | |
completion([.unsupported(forReason: .noContactFound)]) | |
return | |
} | |
// CNContactsStore implementation to get a person from contacts. | |
// See https://gist.github.com/quintonpryce/d69499bf40bdef208bd35d00aba188db | |
let persons = personProvider.getPersonsInContacts(person) | |
// Guard that there are more than one contacts matching the person indicated by the user. | |
guard persons.count > 0 else { | |
completion([.unsupported(forReason: .noContactFound)]) | |
return | |
} | |
// If there is only one person in the users contacts. | |
if persons.count == 1, let person = persons.first { | |
completion([.success(with: person)]) | |
return | |
} | |
// There is multiple persons in this users contacts that match the name they provided. | |
completion([.disambiguation(with: persons)]) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment