前言
最近公司App要实现下图这样一个功能,对iPhone手机喊 " 嘿,Siri,余额 ”
或者 " 嘿,Siri,转账 ”
出现下面的列表,结果列表中展示我们的APP。
百度了很久,没有找到这个是什么功能,有大佬指点我到官网查询一下,通过查阅发现官网有一个这样的文档 Adding User Interactivity with Siri Shortcuts and the Shortcuts App ,但是通过查阅配置步骤,貌似感觉讲的像是设置如何捷径,感觉自己这个需求又不像是Siri Shortcuts(捷径)功能。最后有一个朋友给我指点,应该是Siri语音转账类。
至此,找对了方向开始调研。
步骤:
一、 工程基本配置
创建一个普通的xcode工程,然后进行如下配置1、 在工程的 Signing&Capabilities 中,点击 +Capability ,添加Siri
2、 添加siri权限申请Privacy - Siri Usage Description
使用siriKit,进行快捷转账
3、 在 AppDelegate 中,导入 #import <Intents/Intents.h>
头文件,添加如下代码
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {// Override point for customization after application launch.[INPreferences requestSiriAuthorization:^(INSiriAuthorizationStatus status) {NSLog(@"%ld", (long)status);}];return YES;
}
此时运行工程,会出现下图申请权限的界面
点击好
,至此,基本工程配置完毕。
二、 添加Siri扩展
1、 点击 Xcode
-> File
-> New
-> Target
,选择 iOS
-> Intents Extension
。
填写 Product Name 点击 Finish 完成操作, 此时会弹出提示框,选择 Active 。
至此,会新增两个 Target , SiriExtension
和 SiriExtensionUI
三、 Target , SiriExtension
和 SiriExtensionUI
配置
1、 对 SiriExtension -> info.plist -> NSExtension -> NSExtensionAttributes 中的键值对进行调整,调整前和调整后如下所示:
调整后为:INSendPaymentIntent
2、 对 SiriExtensionUI 也进行相同的配置, SiriExtensionUI 只需要配置 IntentsSupported ,调整后如下:
调整后为:INSendPaymentIntent
基本准备完成,接下来进入代码编写。
四、 SiriExtension 编写代码
1、 在SiriExtension目录下,创建一个SiriExtensionIntentHandler : NSObject
的类。
2、接下来我们编写 SiriExtensionIntentHandler
类中的代码
@implementation SiriExtensionIntentHandlerResolve - payee 解析收款人 iOS10.0
//- (void)resolvePayeeForSendPayment:(INSendPaymentIntent *)intent withCompletion:(void (^)(INPersonResolutionResult * _Nonnull))completion {
// if (intent.payee == nil || !intent.payee.displayName.length) {
// //如果收款人为空,那么请求siri,需要收款人
// INPersonResolutionResult *resolutionResult = [INPersonResolutionResult notRequired];
// completion(resolutionResult);
// }
// else {
// //收款人不为空,确认收款人信息
// INPersonResolutionResult *resolutionResult = [INPersonResolutionResult successWithResolvedPerson:intent.payee];
// completion(resolutionResult);
// }
//}Resolve - payee 解析收款人 iOS11.0
//- (void)resolvePayeeForSendPayment:(INSendPaymentIntent *)intent completion:(void (^)(INSendPaymentPayeeResolutionResult * _Nonnull))completion API_AVAILABLE(ios(11.0)){
// if (intent.payee == nil) {
// INSendPaymentPayeeResolutionResult *resolutionResult = [INSendPaymentPayeeResolutionResult needsValue];
// completion(resolutionResult);
// }
// else {
// INSendPaymentPayeeResolutionResult *resolutionResult = [INSendPaymentPayeeResolutionResult successWithResolvedPerson:intent.payee];
// completion(resolutionResult);
// }
//}
////Resolve - currency 解析货币 iOS10.0
- (void)resolveCurrencyAmountForSendPayment:(INSendPaymentIntent *)intent withCompletion:(void (^)(INCurrencyAmountResolutionResult * _Nonnull))completion {INCurrencyAmount *currencyAmount = intent.currencyAmount;if (currencyAmount == nil) {//金额为空,请求siri,需要转账金额INCurrencyAmountResolutionResult *resolutionResult = [INCurrencyAmountResolutionResult needsValue];completion(resolutionResult);}else if ([currencyAmount.currencyCode isEqualToString:@"CNY"]) {//如果币种不是人民币,将接收到的币种转化为人民币INCurrencyAmount *newCurrencyAmount = [[INCurrencyAmount alloc] initWithAmount:currencyAmount.amount currencyCode:@"CNY"];INCurrencyAmountResolutionResult *resolutionResult = [INCurrencyAmountResolutionResult successWithResolvedCurrencyAmount:newCurrencyAmount];completion(resolutionResult);}else {INCurrencyAmountResolutionResult *resolutionResult = [INCurrencyAmountResolutionResult successWithResolvedCurrencyAmount:currencyAmount];completion(resolutionResult);}
}//Resolve - currency 解析货币单位 iOS11.0
- (void)resolveCurrencyAmountForSendPayment:(INSendPaymentIntent *)intent completion:(void (^)(INSendPaymentCurrencyAmountResolutionResult * _Nonnull))completion API_AVAILABLE(ios(11.0)){INCurrencyAmount *currencyAmount = intent.currencyAmount;if (currencyAmount == nil || currencyAmount.amount == nil) {INSendPaymentCurrencyAmountResolutionResult *resolutionResult = [INSendPaymentCurrencyAmountResolutionResult needsValue];completion(resolutionResult);}else if (![currencyAmount.currencyCode isEqualToString:@"CNY"]) {//货币格式转化为人民币INCurrencyAmount *newCurrencyAmount = [[INCurrencyAmount alloc] initWithAmount:currencyAmount.amount currencyCode:@"CNY"];INSendPaymentCurrencyAmountResolutionResult *resolutionResult = [INSendPaymentCurrencyAmountResolutionResult successWithResolvedCurrencyAmount:newCurrencyAmount];completion(resolutionResult);} else {INSendPaymentCurrencyAmountResolutionResult *resolutionResult = [INSendPaymentCurrencyAmountResolutionResult successWithResolvedCurrencyAmount:currencyAmount];completion(resolutionResult);}
}//Confirm - 确认金额信息
- (void)confirmSendPayment:(INSendPaymentIntent *)intent completion:(void (^)(INSendPaymentIntentResponse * _Nonnull))completion {NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass([INSendPaymentIntent class])];userActivity.title = @"转账";userActivity.userInfo = @{@"displayName": intent.payee.displayName?:@"",@"amount": intent.currencyAmount.amount};//确认支付货币,否则系统会默认展示USD(美元)INPaymentMethod *paymentMethod = [INPaymentMethod applePayPaymentMethod];//status字段决定了siri转账页面底部的UIINPaymentRecord *paymentRecord = [[INPaymentRecord alloc] initWithPayee:intent.payee payer:nil currencyAmount:intent.currencyAmount paymentMethod:paymentMethod note:intent.note status:(INPaymentStatusPending)];INSendPaymentIntentResponse *sendPaymentIntentResponse = [[INSendPaymentIntentResponse alloc] initWithCode:(INSendPaymentIntentResponseCodeReady) userActivity:userActivity];sendPaymentIntentResponse.paymentRecord = paymentRecord;completion(sendPaymentIntentResponse);
}//Handle - 转账处理
- (void)handleSendPayment:(INSendPaymentIntent *)intent completion:(void (^)(INSendPaymentIntentResponse * _Nonnull))completion {NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass([INSendPaymentIntent class])];userActivity.title = @"转账";userActivity.userInfo = @{@"displayName": intent.payee.displayName?:@"",@"amount": intent.currencyAmount.amount};INSendPaymentIntentResponse *sendPaymentIntentResponse = [[INSendPaymentIntentResponse alloc] initWithCode:(INSendPaymentIntentResponseCodeInProgress) userActivity:userActivity];completion(sendPaymentIntentResponse);
}@end
3、 编写SiriExtensionUI --> IntentViewController 类中代码的实现
3.1 首先编写SiriExtensionUI --> MainInterface.storyboard的UI界面
3.2 编写IntentViewController类中代码的实现:
#import "IntentViewController.h"
#import <Intents/Intents.h>@interface IntentViewController ()<INUIHostedViewSiriProviding>
@property (weak, nonatomic) IBOutlet UILabel *amountLabel;
@end@implementation IntentViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.
}#pragma mark - INUIHostedViewSiriProviding- (BOOL)displaysPaymentTransaction {return YES;;
}#pragma mark - INUIHostedViewControlling
- (void)configureWithInteraction:(INInteraction *)interaction context:(INUIHostedViewContext)context completion:(void (^)(CGSize))completion {if ([interaction.intent isKindOfClass:[INSendPaymentIntent class]] && (interaction.intentHandlingStatus == INIntentHandlingStatusReady)) {INSendPaymentIntent *sendPaymentIntent = (INSendPaymentIntent *)interaction.intent;self.amountLabel.text = [NSString stringWithFormat:@"¥%.2f", sendPaymentIntent.currencyAmount.amount.doubleValue];if (completion) {completion(CGSizeMake([self desiredSize].width, 200));}} else {if (completion) {completion(CGSizeZero);}}
}// Prepare your view controller for the interaction to handle.
- (void)configureViewForParameters:(NSSet <INParameter *> *)parameters ofInteraction:(INInteraction *)interaction interactiveBehavior:(INUIInteractiveBehavior)interactiveBehavior context:(INUIHostedViewContext)context completion:(void (^)(BOOL success, NSSet <INParameter *> *configuredParameters, CGSize desiredSize))completion API_AVAILABLE(ios(11.0)){// Do configuration here, including preparing views and calculating a desired size for presentation.if ([interaction.intent isKindOfClass:[INSendPaymentIntent class]] &&(interaction.intentHandlingStatus == INIntentHandlingStatusReady) &&[[parameters anyObject].parameterKeyPath isEqualToString:@"currencyAmount"]) {INSendPaymentIntent *sendPaymentIntent = (INSendPaymentIntent *)interaction.intent;self.amountLabel.text = [NSString stringWithFormat:@"¥%.2f", sendPaymentIntent.currencyAmount.amount.doubleValue];completion(YES, parameters, CGSizeMake([self desiredSize].width, 200));} else {completion(YES, parameters, CGSizeZero);}
}- (CGSize)desiredSize {return [self extensionContext].hostedViewMaximumAllowedSize;
}@end
至此,所有代码的编写已经完成,此时我们跑一下真机,可以看到APP已经安装到我们手机,对iPhone手机喊 " 嘿,Siri,余额 ”
或者 " 嘿,Siri,转账 ”
出现下面的列表,结果列表中展示我们的APP了。
Demo下载
注意:
- 我们的Demo中有
SiriExtension
和SiriExtensionUI
扩展,所以这两个扩展的bundleID要和主工程保持一样的规范。例:
主工程bundleID:com.ddq.siriextension
SiriExtension扩展的bundleID:com.ddq.siriextension.SiriExtension
SiriExtensionUI扩展的bundleID:com.ddq.siriextension.SiriExtensionUI
要在主工程的后面,添加对应的点“.”
后缀名。
证书的创建亦是如此:
2.主工程的bundleID需要开启证书的Siri功能;
3.如果小伙伴下载我的demo运行报错,需要替换主工程和target为你们自己的bundleID。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/19306.html
如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!相关文章
多种多样的语音连麦方式
《人类简史》笔记三—— 历史从无正义
是什么让你意识到打工没出路的?
男子与 AI 对话 6 周后,选择自杀!一时难分“魔鬼”还是“救星”?
LangChain大型语言模型(LLM)应用开发(五):评估
你不知道的 async、await 魔鬼细节
我与ChatGPT又聊了聊:什么是真正的云原生大数据平台
【云原生】我将ChatGPT变成Kubernetes 和Helm 终端
关于云原生,我问了 ChatGPT 几个问题......
教你接入GPT4,不用梯子也能玩
GPT:你知道这五年我怎么过的么?
【2023.5.3~2023.5.9】CTF刷题记录
浅尝Transformer和LLM
【stable diffusion原理解读通俗易懂,史诗级万字爆肝长文,喂到你嘴里】
旋转的base,你见过吗wp
OtterCTF—内存取证wp
电商打工人的饭碗,AIGC还端不走
巴比特 | 元宇宙每日必读:用虹膜信息换基本收入?OpenAI创始人顶着质疑声为其Web3项目Worldcoin再寻1亿美元融资...
类 ChatGPT 开源软件,开发者用的上吗?
【原创】运维工程师涨薪计划,chatGPT帮你做规划
- LeetCode解法汇总83. 删除排序链表中的重复元素
- ORACLE wallet实现无需输入用户名与密码登陆数据库
- 如果没有pos信息,只有一些近景的照片,可以用编辑重建大师进行建模吗?
- 一篇关于密码学的概念性文章
- (1)(1.9) MSP (version 4.2)
- (15)线程的实例认识:同步,异步,并发,并发回调,事件,异步线程,UI线程
- (N-141)基于springboot,vue网上拍卖平台
- (蓝桥杯C/C++)——基础算法(下)
- (十六)大数据实战——安装使用mysql版的hive服务
- .ai域名是什么后缀?
- .NET周报 【3月第2期 2023-03-12】
- @ConfigurationProperties使用