[英]Siri Integration: Audio call using Siri?
I need to integrate Siri to make a calls using my app.我需要集成 Siri 才能使用我的应用程序拨打电话。 Siri recognises my app on App Support on Settings. Siri 在“设置”上的“应用支持”上识别出我的应用。 But when Im trying to call some contact saying "call ContactName on MyApp" it just shows me button "open MyApp".但是当我试图打电话给一些联系人说“在 MyApp 上调用 ContactName”时,它只显示我按钮“打开 MyApp”。 IntentHandler.swift contains this function: IntentHandler.swift 包含这个函数:
class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessagesIntentHandling, INSetMessageAttributeIntentHandling, INStartAudioCallIntentHandling {
override func handler(for intent: INIntent) -> Any {
// This is the default implementation. If you want different objects to handle different intents,
// you can override this and return the handler you want for that particular intent.
return self
}
func handle(startAudioCall intent: INStartAudioCallIntent, completion: @escaping (INStartAudioCallIntentResponse) -> Swift.Void) {
let response: INStartAudioCallIntentResponse
defer {
completion(response)
}
let contacts = (intent.contacts ?? []).filter({ (contact) -> Bool in
return contact.personHandle?.type == .phoneNumber && contact.personHandle?.value != nil
})
// Ensure there is a contact and a handle
guard contacts.count > 0 else {
response = INStartAudioCallIntentResponse(code: .failure, userActivity: nil)
return
}
let userActivity = NSUserActivity(activityType: "INStartAudioCallIntent")
response = INStartAudioCallIntentResponse(code: .continueInApp, userActivity: userActivity)
completion(response)
}
func resolveContacts(forStartAudioCall intent: INStartAudioCallIntent, with completion: @escaping ([INPersonResolutionResult]) -> Void) {
var resolutionResults = [INPersonResolutionResult]()
if let recipients = intent.contacts {
if recipients.count == 0 {
let response = [INPersonResolutionResult.needsValue()]
completion(response)
return
} else if recipients.count == 1 {
if let recipient = recipients.first {
if self.containContact(displayName: (recipient.displayName)) {
resolutionResults.append(INPersonResolutionResult.success(with: recipient))
} else {
resolutionResults.append(INPersonResolutionResult.unsupported())
}
}
} else if recipients.count > 1 {
resolutionResults.append(INPersonResolutionResult.disambiguation(with: recipients))
} else {
resolutionResults.append(INPersonResolutionResult.unsupported())
}
}
completion(resolutionResults)
}
func confirm(startAudioCall intent: INStartAudioCallIntent, completion: @escaping (INStartAudioCallIntentResponse) -> Swift.Void) {
let userActivity = NSUserActivity(activityType: "INStartAudioCallIntent")
let response = INStartAudioCallIntentResponse(code: .ready, userActivity: userActivity)
completion(response)
}
// MARK: - INSendMessageIntentHandling
// Implement resolution methods to provide additional information about your intent (optional).
func resolveRecipients(forSendMessage intent: INSendMessageIntent, with completion: @escaping ([INPersonResolutionResult]) -> Void) {
if let recipients = intent.recipients {
// If no recipients were provided we'll need to prompt for a value.
if recipients.count == 0 {
completion([INPersonResolutionResult.needsValue()])
return
}
var resolutionResults = [INPersonResolutionResult]()
for recipient in recipients {
let matchingContacts = [recipient] // Implement your contact matching logic here to create an array of matching contacts
switch matchingContacts.count {
case 2 ... Int.max:
// We need Siri's help to ask user to pick one from the matches.
resolutionResults += [INPersonResolutionResult.disambiguation(with: matchingContacts)]
case 1:
// We have exactly one matching contact
resolutionResults += [INPersonResolutionResult.success(with: recipient)]
case 0:
// We have no contacts matching the description provided
resolutionResults += [INPersonResolutionResult.unsupported()]
default:
break
}
}
completion(resolutionResults)
}
}
func resolveContent(forSendMessage intent: INSendMessageIntent, with completion: @escaping (INStringResolutionResult) -> Void) {
if let text = intent.content, !text.isEmpty {
completion(INStringResolutionResult.success(with: text))
} else {
completion(INStringResolutionResult.needsValue())
}
}
// Once resolution is completed, perform validation on the intent and provide confirmation (optional).
func confirm(sendMessage intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) {
// Verify user is authenticated and your app is ready to send a message.
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self))
let response = INSendMessageIntentResponse(code: .ready, userActivity: userActivity)
completion(response)
}
// Handle the completed intent (required).
func handle(sendMessage intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) {
// Implement your application logic to send a message here.
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self))
let response = INSendMessageIntentResponse(code: .success, userActivity: userActivity)
completion(response)
}
// Implement handlers for each intent you wish to handle. As an example for messages, you may wish to also handle searchForMessages and setMessageAttributes.
// MARK: - INSearchForMessagesIntentHandling
func handle(searchForMessages intent: INSearchForMessagesIntent, completion: @escaping (INSearchForMessagesIntentResponse) -> Void) {
// Implement your application logic to find a message that matches the information in the intent.
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSearchForMessagesIntent.self))
let response = INSearchForMessagesIntentResponse(code: .success, userActivity: userActivity)
// Initialize with found message's attributes
response.messages = [INMessage(
identifier: "identifier",
content: "I am so excited about SiriKit!",
dateSent: Date(),
sender: INPerson(personHandle: INPersonHandle(value: "sarah@example.com", type: .emailAddress), nameComponents: nil, displayName: "Sarah", image: nil, contactIdentifier: nil, customIdentifier: nil),
recipients: [INPerson(personHandle: INPersonHandle(value: "+1-415-555-5555", type: .phoneNumber), nameComponents: nil, displayName: "John", image: nil, contactIdentifier: nil, customIdentifier: nil)]
)]
completion(response)
}
// MARK: - INSetMessageAttributeIntentHandling
func handle(setMessageAttribute intent: INSetMessageAttributeIntent, completion: @escaping (INSetMessageAttributeIntentResponse) -> Void) {
// Implement your application logic to set the message attribute here.
let userActivity = NSUserActivity(activityType: NSStringFromClass(INSetMessageAttributeIntent.self))
let response = INSetMessageAttributeIntentResponse(code: .success, userActivity: userActivity)
completion(response)
}
func containContact(displayName: String) -> Bool {
//fetch contacts and check, if exist retun YES else NO
return true
}
}
}
let contacts = (intent.contacts ?? []).filter({ (contact) -> Bool in
return contact.personHandle?.type == .phoneNumber && contact.personHandle?.value != nil
})
// Ensure there is a contact and a handle
guard contacts.count > 0 else {
response = INStartAudioCallIntentResponse(code: .failure, userActivity: nil)
return
}
let userActivity = NSUserActivity(activityType: "INStartAudioCallIntent")
response = INStartAudioCallIntentResponse(code: .continueInApp, userActivity: userActivity)
}
What I'm doing wrong?我做错了什么? what I'm missing?我错过了什么?
Please check the followings:请检查以下内容:
-(void)resolveContactsForStartAudioCall:(INStartAudioCallIntent *)intent
withCompletion:(void (^)(NSArray<INPersonResolutionResult *> *resolutionResults))completion{
NSArray<INPerson *> *recipients = intent.contacts;
NSMutableArray<INPersonResolutionResult *> *resolutionResults = [NSMutableArray array];
if (recipients.count == 0) {
completion(@[[INPersonResolutionResult needsValue]]);
return;
}else if(recipients.count==1){
if ([self contactExist:recipients.firstObject.displayName]) {// check if person contains in contact or not
[resolutionResults addObject:[INPersonResolutionResult successWithResolvedPerson:recipients.firstObject]];
}else [resolutionResults addObject:[INPersonResolutionResult unsupported]];
}else if(recipients.count>1){
[resolutionResults addObject:[INPersonResolutionResult disambiguationWithPeopleToDisambiguate:recipients]];
}else{
[resolutionResults addObject:[INPersonResolutionResult unsupported]];
}
completion(resolutionResults);
}
-(void)confirmStartAudioCall:(INStartAudioCallIntent *)intent
completion:(void (^)(INStartAudioCallIntentResponse *response))completion{
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass([INStartAudioCallIntent class])];
INStartAudioCallIntentResponse *response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeReady userActivity:userActivity];
completion(response);
}
-(void)handleStartAudioCall:(INStartAudioCallIntent *)intent
completion:(void (^)(INStartAudioCallIntentResponse *response))completion{
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass([INStartAudioCallIntent class])];
INStartAudioCallIntentResponse *response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeContinueInApp userActivity:userActivity];
completion(response);
}
You may need to share contacts of main applciaiton with extension, use App Grouping.您可能需要与扩展程序共享主应用程序的联系人,使用应用程序分组。 Follow apple document for more information.关注苹果文档以获取更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.