iOS Siri相关开发应用

一、苹果官方提供的Siri开发方法

1、iOS4 - iOS9:不开放Siri API

Siri助手首次出现在iOS4中,但是一直到iOS10之前,苹果都不开放Siri的接口,所以用户使用Siri时,只能使用苹果官方提供的服务,如:
1、帮我设定一个明天早上7点的闹钟
2、打电话给妈妈
3、20分钟后提醒我抢火车票

2、iOS10: SiriKit

在WWDC2016,iOS10版本中,苹果开放了Siri的API,开发者使用SiriKit也可以将自己APP的服务提供给用户,例如:
1、用QQ音乐播放谭咏麟的歌
2、微信发消息给小梦,说我10分钟后到达

命令中需要指定域(Domain,可理解为任务的类型)下的指定意图(Intent,可理解为具体任务),苹果提供的意图如下:
1、语音通话(VoIP Calling):打电话、查通话记录
2、信息 (Messaging):发信息、搜索信息
3、媒体(Media):播放或控制音频
4、任务或笔记(Lists and Notes) :创建或管理任务或笔记
5、付款(Payments):给用户付款或结算账单
6、餐馆预定(Restaurant Reservations):通过地图应用预定餐馆或管理预定
7、健身( Workouts):开始、暂停、管理健身
8、打车 (Ride Booking):查看附近可用的车辆、订车、查看订单
9、控制汽车(Car Commands):控制门锁、获取车辆状态

例如用微信发送消息给小梦,说我10分钟后到达,解析后为:
域(Domain):信息 (Messaging)
意图(Intent):发信息(INSendMessageIntent)
意图参数 (Intent Parameter):
收件人(recipients):小梦
消息内容(content):我10分钟后到达

随着iOS版本的迭代,可能支持更多意图,可以查看最新的官方文档

intwnt

3、iOS12: Siri ShortCut

在WWDC 2018,苹果进一步开放了Siri功能,推出了Siri Shortcuts,用户只需一句预先设定的短语,即可触发指定的操作,如
1、播放下雨声 (触发小睡眠APP播放下雨声的白噪音)
2、咖啡时间 (触发某咖啡APP下单一杯咖啡)

在这里插入图片描述

二、SiriKit示例

因为SiriKit和Siri ShortCut开发代码逻辑存在一定差异,为防止文章过长,这一篇先介绍使用SiriKit发送消息的实现。
当用户通过Siri给好友发送消息时,系统会识别为消息域中的发送消息意图,并创建一个 INSendMessageIntent,包含消息接受者、消息内容等参数,然后调用 app extension 的 handler,解析上下文,确认可以处理并发送完消息后返回 INSendMessageIntentResponse 类型的结果。下面我们一步步来实现

1、创建Demo项目:

打开Xcode,菜单选择File->New->Project,创建名为MySiriKitDemo的新项目
在这里插入图片描述

2、添加Intent Extension

菜单选择File->New->Target,选择Intents Extension,点Next,命名为MySirExtension,且勾选Include UI Extension,以便后面添加交互UI
在这里插入图片描述

3、配置

如图修改项目名称为聊天测试,或其它你喜欢的名称。Demo完成后,我们使用siri发送消息时,需要用到这个名称,如用“聊天测试发送消息给小梦告诉他我到了”。
在这里插入图片描述
打开MySirExtension下的Info.plist文件,创建Intents Extension时默认即为Message Intents,所以IntentsSupported下的项目不需要做修改(如果只用到发送消息,也可只保留INSendMessageIntent)。
在这里插入图片描述

如果是媒体播放,需更改为INPlayMediaIntent,如果是健身,需更改为INStartWorkoutIntent、INPauseWorkoutIntent、INResumeWorkoutIntent、INCancelWorkoutIntent、INEndWorkoutIntent等,具体可参考官方文档

在这里插入图片描述

4、共享的用户信息

在开始正式处理Siri数据前,我们先在主项目新建文件MyAccount.swift,并创建用户相关类,包括好友类MyUser和账号管理类MyAccount,记得同时添加到主项目及Extension中。

  • MyUser:好友对象 ,包含好友的昵称信息
  • MyAccount:账号管理类,单例,contact方法传入好友昵称返回好友对象,send方法为给指定好友发送消息
    在这里插入图片描述
    MyAccount.swift完整代码:
import Intents

class MyUser {
    var name:String?
    var handle: String?

    init(name: String? = nil, handle: String? = nil) {
        self.name = name
        self.handle = handle
    }
    
    func toInPerson() -> INPerson {
        return INPerson(handle: handle!, displayName: name, contactIdentifier: name)
    }
}

class MyAccount {
    private static let instance = MyAccount()
    
    class func share() -> MyAccount {
        return MyAccount.instance
    }
    
    func contact(matchingName: String) -> [MyUser] {
        return [MyUser(name: matchingName, handle: NSStringFromClass(MySendMessageIntentHandler.classForCoder()))]
    }
    
    func send(message: String,to recipients:[INPerson]) -> INSendMessageIntentResponseCode {
        print("模拟发送消息:\(message) 给 \(recipients)")
        return .success
    }

}

这里假设了用户通过Siri所呼叫的好友真实存在,即MyAccount的contact方法永远能返回昵称对应的好友,具体实现要根据项目原有的账号逻辑。

5、处理Siri数据

打开IntentHandler.swift,苹果已经为我们生成了消息的示例代码,虽然可以在这基础上修改,但我们这里只实现发消息的效果,防止过多冗余代码,我们删除之。这里我们只需实现INSendMessageIntentHandling协议下的三个阶段方法:

  • Resolve:处理阶段,解析Siri数据(处理收件人、处理发送的文字内容,这里使用了上一步的好友类、账号类进行匹配)
  • Confirm:确认阶段,可以判断用户是否有权限(如是否已登录)、可以获取intent事件中的值,并可对其做最终修改
  • Handle: 处理阶段,实现app消息发送的代码逻辑
    processing
    这里我们创建MySendMessageIntentHandler.swift类,实现INSendMessageIntentHandling中的这几个方法:
import UIKit
import Intents

class MySendMessageIntentHandler: NSObject,INSendMessageIntentHandling {
    // MARK: - INSendMessageIntentHandling
    
    // Implement resolution methods to provide additional information about your intent (optional).
    // 处理收件人
    func resolveRecipients(for intent: INSendMessageIntent, with completion: @escaping ([INSendMessageRecipientResolutionResult]) -> Void) {
        if let recipients = intent.recipients {
            
            // If no recipients were provided we'll need to prompt for a value.
            if recipients.count == 0 {
                completion([INSendMessageRecipientResolutionResult.needsValue()])
                return
            }
            
            var resolutionResults = [INSendMessageRecipientResolutionResult]()
            for recipient in recipients {
                let matchingContacts = MyAccount.share().contact(matchingName: recipient.displayName)
                // 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.
                    let disambiguations = matchingContacts.map{ $0.toInPerson() }
                    resolutionResults += [INSendMessageRecipientResolutionResult.disambiguation(with: disambiguations)]
                    
                case 1:
                    // We have exactly one matching contact
                    let recipient = matchingContacts[0].toInPerson()
                    resolutionResults += [INSendMessageRecipientResolutionResult.success(with: recipient)]
                    
                case 0:
                    // We have no contacts matching the description provided
                    resolutionResults += [INSendMessageRecipientResolutionResult.unsupported()]
                    
                default:
                    break
                    
                }
            }
            completion(resolutionResults)
        } else {
            completion([INSendMessageRecipientResolutionResult.needsValue()])
        }
    }
    
    // 处理发送的文字内容
    func resolveContent(for 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).
    // 确认阶段,可以判断用户是否有权限(如是否已登录)、可以获取intent事件中的值,并可对其做最终修改
    func confirm(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).
    // 处理阶段,实现app消息发送的代码逻辑
    func handle(intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) {
        // Implement your application logic to send a message here.
        if let content = intent.content,let recipients = intent.recipients {
            let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self))
            let sendResult = MyAccount.share().send(message: content, to: recipients)
            completion(INSendMessageIntentResponse(code: sendResult, userActivity: userActivity))
        }else {
            let response = INSendMessageIntentResponse(code: .failure, userActivity: nil)
            completion(response)
        }
        
    }
}

最后在IntentHandler中,返回MySendMessageIntentHandler对象:

import Intents

// As an example, this class is set up to handle Message intents.
// You will want to replace this or add other intents as appropriate.
// The intents you wish to handle must be declared in the extension's Info.plist.

// You can test your example integration by saying things to Siri like:
// "Send a message using <myApp>"
// "<myApp> John saying hello"
// "Search for messages in <myApp>" INSendMessageIntentHandling

class IntentHandler: INExtension {
    
    override func handler(for intent: INIntent) -> Any? {
        if intent is INSendMessageIntent {
            return MySendMessageIntentHandler()
        }
        return nil
    }
    
}
6、运行测试

对Siri说用聊天测试发消息给小梦说我马上到,运行效果如下:
请添加图片描述

完整代码:下载

  • 21
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SIP(Session Initiation Protocol)是一种用于实时通信的协议,常用于语音通话、视频通话和即时消息传递。IOS开发SIP应用需要使用第三方库或框架来实现SIP协议。 以下是IOS开发SIP应用的一般步骤: 1. 选择合适的SIP库或框架,目前比较流行的有pjsip、Linphone、Siphon等。 2. 下载并安装所选库或框架。 3. 创建Xcode项目,并在项目中添加所选库或框架的头文件和库文件。 4. 配置SIP服务器信息,包括服务器地址、端口、用户名、密码等。 5. 实现SIP协议的各种功能,如注册、呼叫、接听、挂断等。 6. 实现音频和视频的采集、编解码、传输等功能。 7. 实现即时消息传递功能,包括文本、图片、文件等。 8. 测试并调试应用,确保其功能正常。 9. 发布应用到App Store,供用户下载和使用。 在实现IOS开发SIP应用时,需要注意以下几点: 1. SIP应用需要使用网络进行通信,因此需要保证网络连接的稳定性和安全性。 2. SIP应用需要使用麦克风和摄像头等硬件设备进行音视频采集和传输,因此需要考虑设备兼容性和性能问题。 3. SIP应用需要与其他SIP应用互通,因此需要考虑与其他SIP应用的兼容性和互操作性。 4. SIP应用需要保护用户的隐私和安全,因此需要采取相应的安全措施,如加密传输、用户认证等。 总之,IOS开发SIP应用需要具备一定的网络通信、音视频处理和安全保障方面的知识,同时需要熟悉所选SIP库或框架的使用方法和API。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值