本文介绍: 前言最近公司App实现下图这样一个功能,对iPhone手机喊 ” 嘿,Siri,余额 ”或者 ” 嘿,Siri,转账 ” 出现下面的列表结果表中展示我们的APP。列表.png百度了很久,没有找到这个什么功能,有大佬指点我到官网查询一下,通过查阅发现官网一个这样的文档 Adding User Interactivity with Siri Shortcuts and t

前言

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

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

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

步骤

一、 工程基本配置

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

image02.png

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

image03.png

3、 在 AppDelegate 中,导入 #import <Intents/Intents.h&gt; 头文件添加如下代码

- (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

至此,会新增两个 TargetSiriExtensionSiriExtensionUI

image09.png
三、 TargetSiriExtensionSiriExtensionUI 配置

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 SiriExtensionIntentHandler

Resolve - 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转账页面底部的UI
    INPaymentRecord *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]] &amp;&amp; (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]] &amp;&amp;
        (interaction.intentHandlingStatus == INIntentHandlingStatusReady) &amp;&amp;
        [[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。

原文地址:https://blog.csdn.net/u010707262/article/details/127613538

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_33514.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注