首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Siri集成:使用Siri的音频呼叫?

Siri集成:使用Siri的音频呼叫?
EN

Stack Overflow用户
提问于 2016-12-29 13:25:21
回答 1查看 1.9K关注 0票数 0

我需要整合Siri,用我的应用程序打电话。Siri在应用程序支持设置上识别我的应用程序。但是当我试图给一些联系人打电话说“ContactName on MyApp”时,它只是显示了“打开MyApp”按钮。IntentHandler.swift包含以下功能:

代码语言:javascript
复制
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)

    }

我做错什么了?我错过了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-04 09:54:20

请核对下列文件:

在扩展的目标中为IntentsSupported设置IntentsSupported。

确认默认情况下提供的INStartAudioCallIntentHandling类中的IntentHandler协议,并实现以下方法:

代码语言:javascript
复制
-(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);
}

您可能需要与扩展共享主应用程序的联系人,使用应用程序分组。请跟随https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html获取更多信息。

确保扩展目标支持您的设备操作系统。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41380702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档