iOS-Siri唤起银行类app (语音转账)

前言

最近公司App要实现下图这样一个功能,对iPhone手机喊 " 嘿,Siri,余额 ”或者 " 嘿,Siri,转账 ” 出现下面的列表,结果列表中展示我们的APP。

列表.png

百度了很久,没有找到这个是什么功能,有大佬指点我到官网查询一下,通过查阅发现官网有一个这样的文档 Adding User Interactivity with Siri Shortcuts and the Shortcuts App ,但是通过查阅配置步骤,貌似感觉讲的像是设置如何捷径,感觉自己这个需求又不像是Siri Shortcuts(捷径)功能。最后有一个朋友给我指点,应该是Siri语音转账类。

image.png

至此,找对了方向开始调研。

步骤:

一、 工程基本配置

创建一个普通的xcode工程,然后进行如下配置1、 在工程的 Signing&Capabilities 中,点击 +Capability ,添加Siri

image01.png
image02.png

2、 添加siri权限申请Privacy - Siri Usage Description 使用siriKit,进行快捷转账

image03.png

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;
}

此时运行工程,会出现下图申请权限的界面

image04.png

点击,至此,基本工程配置完毕。

二、 添加Siri扩展

1、 点击 Xcode -> File -> New -> Target ,选择 iOS -> Intents Extension

image05.png
image06.png
image07.png

填写 Product Name 点击 Finish 完成操作, 此时会弹出提示框,选择 Active 。

image08.png

至此,会新增两个 Target , SiriExtensionSiriExtensionUI

image09.png
三、 Target , SiriExtensionSiriExtensionUI 配置

1、 对 SiriExtension -> info.plist -> NSExtension -> NSExtensionAttributes 中的键值对进行调整,调整前和调整后如下所示:

image10.png

调整后为:INSendPaymentIntent

image11.png

2、 对 SiriExtensionUI 也进行相同的配置, SiriExtensionUI 只需要配置 IntentsSupported ,调整后如下:

image12.png

调整后为:INSendPaymentIntent

image13.png

基本准备完成,接下来进入代码编写。

四、 SiriExtension 编写代码

1、 在SiriExtension目录下,创建一个SiriExtensionIntentHandler : NSObject的类。

image14.png

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界面

image15.png

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了。

image16.png

Demo下载

注意:

  1. 我们的Demo中有 SiriExtensionSiriExtensionUI扩展,所以这两个扩展的bundleID要和主工程保持一样的规范。例:
    主工程bundleID: com.ddq.siriextension
    SiriExtension扩展的bundleID: com.ddq.siriextension.SiriExtension
    SiriExtensionUI扩展的bundleID: com.ddq.siriextension.SiriExtensionUI
    要在主工程的后面,添加对应的点 “.”后缀名。
    证书的创建亦是如此:
    image.png

2.主工程的bundleID需要开启证书的Siri功能;

image.png

3.如果小伙伴下载我的demo运行报错,需要替换主工程和target为你们自己的bundleID。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/19306.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多种多样的语音连麦方式

前言 语音连麦&#xff0c;视频通话这种基础功能大家都已经非常熟悉了&#xff0c;应用场景也十分广泛&#xff0c;例如连麦直播、游戏开黑、在线合唱、视频相亲等。 anyRTC为了让开发者们可以最找到适合自己的开发系统&#xff0c;目前我们已经适配了iOS、Androd、Web、小程…

《人类简史》笔记三—— 历史从无正义

目录 一、尽管把人人生而平等喊得震天响&#xff0c;其实还是把人分成了上下等级 二、恶性循环 三、当男人究竟有什么好的&#xff1f; 一、尽管把人人生而平等喊得震天响&#xff0c;其实还是把人分成了上下等级 古时候&#xff1a; 上等人 平民和奴隶 现在&#xff1a;…

是什么让你意识到打工没出路的?

前两年有篇爆款文&#xff0c;叫《困在算法里的外卖骑手》——算法的最终目标&#xff0c;是将骑手的体力压榨到极限&#xff0c;将成本降低到极限。 很多人看完&#xff0c;都替外卖小哥叫惨。 但回头仔细一盘&#xff0c;发现自己也惨&#xff0c;那套残酷的资本主义算法&a…

男子与 AI 对话 6 周后,选择自杀!一时难分“魔鬼”还是“救星”?

整理 | 朱珂欣 出品 | CSDN程序人生&#xff08;ID&#xff1a;coder_life&#xff09; 伴随着 ChatGPT 的火热出圈&#xff0c;让 AI 在全球范围内掀起一股浪潮&#xff1a;“往赛道里挤&#xff01;” 当各大公司秉承着“冲就对了”的心态迎接 AI 带来的一切&#xff0c;却…

LangChain大型语言模型(LLM)应用开发(五):评估

LangChain是一个基于大语言模型&#xff08;如ChatGPT&#xff09;用于构建端到端语言模型应用的 Python 框架。它提供了一套工具、组件和接口&#xff0c;可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互&#x…

你不知道的 async、await 魔鬼细节

点击上方 前端Q&#xff0c;关注公众号 回复加群&#xff0c;加入前端Q技术交流群 作者&#xff1a;Squirrel_ https://juejin.cn/post/7194744938276323384 0、前言 关于promise、async/await的使用相信很多小伙伴都比较熟悉了&#xff0c;但是提到事件循环机制输出结果类似的…

我与ChatGPT又聊了聊:什么是真正的云原生大数据平台

图片来源 | 文心一格 小智&#xff1a;传统大数据平台是什么样的&#xff1f;企业使用传统大数据平台有哪些弊端&#xff1f; 小智&#xff1a;云原生为什么这么火&#xff1f;企业如何借助云原生实现数据驱动&#xff1f; 小智&#xff1a;你听过在Kubernetes上部署的容器化云…

【云原生】我将ChatGPT变成Kubernetes 和Helm 终端

{kubectl get po&#xff0c;deploy&#xff0c;svc}{kubectl run --imagenginx nginx-app --port80 --env“DOMAINcluster”}{kubectl expose deployment nginx-app --port80 --namenginx-http}{kubectl get po&#xff0c;svc&#xff0c;deploy}{curl 10.100.67.94:80}{helm…

关于云原生,我问了 ChatGPT 几个问题......

2 个月用户破亿&#xff0c;一举超过 Tik Tok 成为史上增速最快的消费级应用程序&#xff0c;ChatGPT 的诞生给沉寂的科技圈丢下了一块巨大的石头。这场生成式 AI 掀起的浪潮&#xff0c;让人不禁重回到当年人类智慧的大溃败——AlphaGo 战胜李世石&#xff0c;震撼依旧但其背后…

教你接入GPT4,不用梯子也能玩

介绍 chatgpt最近十分火爆&#xff0c;但大多少开发接入的都是gpt3.5&#xff0c;今天教教大家如何快速接入gpt4 使用 接入很简单&#xff0c;需要去API文档获取你的token填入&#xff0c;每个账号都有白嫖次数&#xff0c;以下是node代码 const { data } await axios({url…

GPT:你知道这五年我怎么过的么?

时间轴 GPT 首先最初版的GPT&#xff0c;来源于论文Improving Language Understanding by Generative Pre-Training&#xff08;翻译过来就是&#xff1a;使用通用的预训练来提升语言的理解能力&#xff09;。GPT这个名字其实并没有在论文中提到过&#xff0c;后人将论文名最后…

【2023.5.3~2023.5.9】CTF刷题记录

目录 日期&#xff1a;2023.5.3 题目&#xff1a;[GWCTF 2019]pyre 日期&#xff1a;2023.5.4 题目&#xff1a;[ACTF新生赛2020]easyre 题目&#xff1a;DASCTF Apr.2023 X SU战队2023开局之战 【简单】easyRE 日期&#xff1a;2023.5.5 题目&#xff1a;findit 题目&…

浅尝Transformer和LLM

文章目录 TransformerTransformer的衍生BERTPre-trainingBERT与其他方法的关系怎么用BERT做生成式任务&#xff1f; GPTPre-trainingFine-Tuning Transformer工具开源库特点 LLM系列推理服务 大语言模型势不可挡啊。 哲学上来说&#xff0c;语言就是我们的一切&#xff0c;语言…

【stable diffusion原理解读通俗易懂,史诗级万字爆肝长文,喂到你嘴里】

文章目录 一、前言&#xff08;可跳过&#xff09;二、stable diffusion1.clip2.diffusion modelforward diffusion &#xff08;前向扩散&#xff09;逆向扩散&#xff08;reverse diffusion&#xff09;采样图阶段小结 3.Unet modeltimestep_embedding采用正余弦编码 三、sta…

旋转的base,你见过吗wp

一、题目 前几天在ctfshow的qq交流群里看到有个师傅在问一道名为“旋转的base&#xff0c;你见过吗”的题目&#xff08;但这道题不是ctfshow平台上的啦&#xff0c;后来听说好像是个比赛题&#xff09;&#xff0c;题目给出了一串编码过的字符串&#xff0c;但看题目名也能知…

OtterCTF—内存取证wp

目录 前言 一、工具说明 二、题目解析 1.What the password? 2.General Info 3.Play Time 4.Name Game 5.Name Game 2 6.Silly Rick 7.Hide And Seek 8.Path To Glory 9.Path To Glory 2 10.Bit 4 Bit 11.Graphics For The Weak 12.Recovery 13.Closure 总结 前言 前几天有幸…

电商打工人的饭碗,AIGC还端不走

文 | 螳螂观察 作者 | 鲸胖胖 以ChatGPT、Midjourney、文心一言等为代表的AIGC产品&#xff0c;已经在全球掀起新一轮的AI技术变革新浪潮&#xff0c;再度刷新了人们对AI的认知&#xff0c;多个行业的商业模式和生态必然在未来会被彻底重构。 前不久&#xff0c;36氪就测使用…

巴比特 | 元宇宙每日必读:用虹膜信息换基本收入?OpenAI创始人顶着质疑声为其Web3项目Worldcoin再寻1亿美元融资...

摘要&#xff1a;据元宇宙日爆报道&#xff0c;OpenAl的CEO要为他两年前创办的币圈项目worldcoin再寻1亿美元融资&#xff0c;该项目于5月8日面向全球推出加密钱包WorldApp&#xff0c;要给“无条件为全民空投代币”&#xff0c;此外&#xff0c;项目方还为这款钱包的推出发行了…

类 ChatGPT 开源软件,开发者用的上吗?

声明&#xff1a;本文是 Preethi Cheguri 所著文章《ChatGPT Equivalent Is Open-Source, But it Is of No Use to Developers》的中文译文。 原文链接&#xff1a;https://www.analyticsinsight.net/chatgpt-equivalent-is-open-source-but-it-is-of-no-use-to-developers/ 类…

【原创】运维工程师涨薪计划,chatGPT帮你做规划

文章目录 1、运维工程师怎么涨薪呢&#xff1f;a&#xff09;加大深度b&#xff09;加大广度 2、运维工程师何处去呢&#xff1f;3、chatGPT告诉你3年、5年、10年运维和开发的现状&#xff1b;有运维经验的工程师&#xff0c;搞开发好吗薪资会有显著提升吗以数据证明&#xff0…