你 App 的Indents extension扩展的接口点是INExtension Object,它的主要作用是把indents引导给Siri去处理。
在extension里有三类objects来处理intents
一种Indents Object保存Siri收集的用户数据
一种Handler Object是你自定义的用以解析,确定并处理indents
一种Response object保存你的处理结果
当SiriKit有一个Indent需要处理时,它会请求INExtension寻找一个匹配的Handler,Handler都继承了相应的Protocol协议对应不同种类的indents。
这些Protocols都有相似的结构,有相应的方法解析,确认并处理相应等indent
实现一个handler必须实现相对应处理所配indents的方法,其他方法都为可选方法,利用这些方法优先解析和确认indents,再进行处理。
在进行验证过程中,Siri和用户进行交互获取额外需要的信息
下图为Siri和handler的流程图
向Handler Objects派发Intents
当intent被app接收,SiriKit请求Intents extension提供相应的handler object,SiriKit调用INExtension子类的 handlerForIntent: 方法,这就是你extension的接入点。
这个方法会返回SiriKit解析,确认和处理的Objects
下面代码块显示实现了 handlerForIntent: 方法提供的针对文本信息和VoIP(语音协议)的intents的handler objects。 这个结构同样可以用于其他的不同handler。
你先检查发过来的intent的类并返回相应的handler object。 你可以利用单一handler来处理所有你支持的intents或者创建分别不同的handler针对不同的intent。
下面例子,intents extension为所有文本相关的intents返回同一个handler object,为语音和视频intents返回不同的handler
overridefunchandler(forintent:INIntent) -> AnyObject? {
varhandler = nil
ifintentisINSendMessageIntent ||
intentisINSearchForMessagesIntent ||
intentisINSetMessageAttributeIntent {
handler = MyMessageHandler()
}
elseifintentisINStartAudioCallIntent {
handler = MyAudioCallHandler()
}
elseifintentisINStartVideoCallIntent {
handler = MyVideoCallHandler()
}
returnhandler
}
SiriKit通常会在一次单个intent的处理时要求提供handler object多次,它也许会花一些时间处理所有intent的参数,特别是,当Siri要求用户提供更多信息或解释其参数。
每次要求一个新的handler object保证了handler的有效性,同样也表示handler的方法不应当依赖cache起来的数据,她们应当永远处理新的请求。
解析Intent的参数
每一个解析indent的方法结构必须相同:
从indent object那获得parameter
验证并且去匹配你app的值
初始化合适的INIntentResolutionResult子类与你的解决方案
解决并返回结果
Indents Framework会为每一个parameter定义一个INIntentResolutionResult, 每一个子类必须实现类方法以返回是否完成任务或需要更多信息,
同样父类INIntentResolutionResult会包含解决通常的解决方案。 下面表列出了一些常见的解决方案:
Resolution |
Examples |
---|---|
You successfully matched the value. |
Specify this resolution if you can use the provided value to handle the intent. You should always strive toward a resolution of parameters, even if that means making educated guesses about what the user meant. For example, if the user specified the name “John” for a person and has only one contact with that name, you could resolve the parameter successfully to that contact. See the documentation for the appropriate resolution result object for the name of the method to use for successful results. |
A value was not required. |
Specify this resolution when you do not need the value of the parameter to handle the intent. For example, you might return this result when the intent contains a goal for an open workout, which normally has no goal. Use the |
Values need disambiguation. |
Specify this result when you identify two or more possible results and cannot choose one definitively. This result may lead to additional interactions with the user to choose one of the provided values. See the documentation for the appropriate resolution result object for the name of the method to use for disambiguating results. |
The value needs user confirmation. |
Specify this result when you want the user to confirm the value you chose. Use this result when you identify a value, but you are not completely sure that it is the right value. For example, you might use this result when the value you chose is different than the one the user provided but you think the new value is what the user intended. Siri always asks the user to confirm values for some types of intents, such as those involving financial transactions. See the documentation for the appropriate resolution result object for the name of the method to use for confirming results. |
A value is required. |
Specify this result when the value is missing for a parameter that you require. For example, you might return this result if the user requests a payment from another person but does not specify the payment amount. Use the |
The value is unsupported. |
Specify this result when your app does not support a specific value or when that value conflicts with the values of other parameters. For example, you might return this result when the user wants to send a payment in Swiss francs but your app requires transactions to be in Euros or US Dollars. Use the |
下面代码例举了交通出行app如何验证终点位置,如果终点位置提供了并且在服务范围内,方法返回成功结果,如果超出范围会返回不支持该结果。
如果没有提供数据,方法会询问用户输入:
Listing 3-2Resolving a required parameter of an intent
func resolveDropOffLocation(forRequestRide intent: INRequestRideIntent,
with completion: (INPlacemarkResolutionResult) -> Void) {
let location = intent.dropOffLocation
var result : INPlacemarkResolutionResult = nil
if location != nil {
// If the locaiton is valid, use it; otherwise,
// let the user know it is not supported
if self.locationIsInsideServiceArea(location) {
result = INPlacemarkResolutionResult.successWithResolvedValue(location)
}
else {
result = INPlacemarkResolutionResult.unsupported()
}
}
else {
// Ask for the drop-off location.
result = INPlacemarkResolutionResult.needsValue()
}
// Return the result.
completion(result)
}
OBJECTIVE-C
func confirmStartWorkout(startWorkout intent: INStartWorkoutIntent,
completion: (INStartWorkoutIntentResponse) -> Void) {
// Make sure the app is ready.
// Provide the response.
let response = INStartWorkoutIntentResponse(code: .ready, userActivity: nil)
completion(response)
}
Swift
func handleStartWorkout(startWorkout intent: INStartWorkoutIntent,
completion: (INStartWorkoutIntentResponse) -> Void) {
let response = INStartWorkoutIntentResponse(code: .continueInApp, userActivity: nil)
completion(response)
}
OBJECTIVE-C