Imad Ali
Imad Ali

Reputation: 3301

SiriKit INPayBillIntentHandling - Siri says, "I wish I could, but <App> hasn't set that up with me yet."

I'm integrating Sirikit, Bill Payment using the intent:

INPayBillIntentHandling (which was released recently in iOS 10.3+, 27 Mar 2017).

Apple Documentation is here.

Note: I'm using Obj-C Language, XCode 8.3, Device iPhone 6S with iOS 10.3 & Demo Project iOS Deployment target is iOS 10.3 AND also enabled the Siri when asked the permission for the first time and also verified that In Settings, Siri is enabled.

When I launch the app on device and say "Bill Payment using DemoApp", Siri says "I wish I could, but DemoApp hasn't set that up with me yet"

Please help me. Thanks in Advance!

So far I did the following steps:

1) Create a Demo Xcode project

2) In Main App Capabilities, Enabled Siri.

3) Added Sirikit extension using

File -> New -> Add Target -> Intent Extension -> Next ->Add ProductName and say Finish

Note: I've disabled the Sirikit UI Extension.

4) In Main AppDelegate added the following:

#import <Intents/Intents.h>
    [INPreferences requestSiriAuthorization:^(INSiriAuthorizationStatus status) {
        NSLog(@"Siri Authorization status...%ld", status);
    }];

5) In Main app Info.plist, added key NSSiriUsageDescription with usage description

6) In IntentExtension, Info.plist, NSExtension->IntentsSupported->added key INPayBillIntent

7) In IntentHandler.m, added all the delegate methods for INPayBillIntentHandling

@interface IntentHandler () <INPayBillIntentHandling>

@end

@implementation IntentHandler

- (id)handlerForIntent:(INIntent *)intent {
    // This is the default implementation.  If you want different objects to handle different intents,
    // you can override this and return the handler you want for that particular intent.

    return self;
}

- (void)confirmPayBill:(INPayBillIntent *)intent
            completion:(void (^)(INPayBillIntentResponse *response))completion NS_SWIFT_NAME(confirm(payBill:completion:)) {
    NSLog(@"\n%s", __func__);
    INPayBillIntentResponse *response = [[INPayBillIntentResponse alloc] initWithCode:INPayBillIntentResponseCodeSuccess userActivity:nil];
    completion(response);
}
- (void)handlePayBill:(INPayBillIntent *)intent
          completion:(void (^)(INPayBillIntentResponse *response))completion NS_SWIFT_NAME(handle(payBill:completion:)) {
    NSLog(@"\n%s", __func__);
    NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass([INPayBillIntent class])];

    INPayBillIntentResponse *response = [[INPayBillIntentResponse alloc] initWithCode:INPayBillIntentResponseCodeReady userActivity:userActivity];
    completion(response);

}
- (void)resolveBillPayeeForPayBill:(INPayBillIntent *)intent
                    withCompletion:(void (^)(INBillPayeeResolutionResult *resolutionResult))completion NS_SWIFT_NAME(resolveBillPayee(forPayBill:with:)) {
    NSLog(@"\n%s", __func__);

    INSpeakableString *speakableStr = [[INSpeakableString alloc] initWithIdentifier:@"XYZ Bill" spokenPhrase:@"XYZ Bill" pronunciationHint:@"XYZ Bill"];
    INSpeakableString *speakableStr1 = [[INSpeakableString alloc] initWithIdentifier:@"XYZ Bill Payments" spokenPhrase:@"XYZ Payments" pronunciationHint:@"XYZ Bills"];

    INBillPayee *billPayee = [[INBillPayee alloc] initWithNickname:speakableStr number:@"10112122112" organizationName:speakableStr1];

    INBillPayeeResolutionResult *finalResult = [INBillPayeeResolutionResult successWithResolvedBillPayee:billPayee];

    completion(finalResult);
}
- (void)resolveFromAccountForPayBill:(INPayBillIntent *)intent
                      withCompletion:(void (^)(INPaymentAccountResolutionResult *resolutionResult))completion NS_SWIFT_NAME(resolveFromAccount(forPayBill:with:)) {
    NSLog(@"\n%s", __func__);
    INSpeakableString *speakableStr2 = [[INSpeakableString alloc] initWithIdentifier:@"john.smith" spokenPhrase:@"john.smith" pronunciationHint:@"john.smith"];
    INSpeakableString *speakableStr3 = [[INSpeakableString alloc] initWithIdentifier:@"" spokenPhrase:@"" pronunciationHint:@"organisation"];

    INPaymentAccount *fromAccount = [[INPaymentAccount alloc] initWithNickname:speakableStr2 number:@"10112122112" accountType:INAccountTypeCredit organizationName:speakableStr3];


    INPaymentAccountResolutionResult *finalResult = [INPaymentAccountResolutionResult successWithResolvedPaymentAccount:fromAccount];

    completion(finalResult);

}
- (void)resolveTransactionAmountForPayBill:(INPayBillIntent *)intent
                            withCompletion:(void (^)(INPaymentAmountResolutionResult *resolutionResult))completion NS_SWIFT_NAME(resolveTransactionAmount(forPayBill:with:)) {
    NSLog(@"\n%s", __func__);

    INCurrencyAmount *currencyAmt = [[INCurrencyAmount alloc] initWithAmount:[NSDecimalNumber decimalNumberWithString:@"100"] currencyCode:@"784"];

    INPaymentAmount *transactionAmt = [[INPaymentAmount alloc] initWithAmountType:INAmountTypeAmountDue amount:currencyAmt];

    INPaymentAmountResolutionResult *finalResult = [INPaymentAmountResolutionResult successWithResolvedPaymentAmount:transactionAmt];

    completion(finalResult);

}
- (void)resolveTransactionScheduledDateForPayBill:(INPayBillIntent *)intent
                                  withCompletion:(void (^)(INDateComponentsRangeResolutionResult *resolutionResult))completion NS_SWIFT_NAME(resolveTransactionScheduledDate(forPayBill:with:)) {

    completion([INDateComponentsRangeResolutionResult notRequired]);

}
- (void)resolveTransactionNoteForPayBill:(INPayBillIntent *)intent
                          withCompletion:(void (^)(INStringResolutionResult *resolutionResult))completion NS_SWIFT_NAME(resolveTransactionNote(forPayBill:with:)) {
    NSLog(@"\n%s", __func__);
    INStringResolutionResult *finalResult = [INStringResolutionResult successWithResolvedString:@"Bill Payment"];

    completion(finalResult);
}
- (void)resolveBillTypeForPayBill:(INPayBillIntent *)intent
                  withCompletion:(void (^)(INBillTypeResolutionResult *resolutionResult))completion NS_SWIFT_NAME(resolveBillType(forPayBill:with:)) {
    NSLog(@"\n%s", __func__);
    INBillTypeResolutionResult *finalResult = [INBillTypeResolutionResult successWithResolvedValue:INBillTypeElectricity];

    completion(finalResult);

}
- (void)resolveDueDateForPayBill:(INPayBillIntent *)intent
                  withCompletion:(void (^)(INDateComponentsRangeResolutionResult *resolutionResult))completion NS_SWIFT_NAME(resolveDueDate(forPayBill:with:)) {
    NSLog(@"%s", __func__);
    completion([INDateComponentsRangeResolutionResult notRequired]);
}

Upvotes: 5

Views: 1602

Answers (3)

rockdaswift
rockdaswift

Reputation: 9983

Check that the handler(for intent: INIntent) function, the App info.plist and intent extension plist have the right supported intents.

Upvotes: 0

Cherry_thia
Cherry_thia

Reputation: 696

Try it on iOS 11 beta version. I am trying using swift on iOS 11 beta 5, it is a lot more stable.

Upvotes: 0

Michael Ortiz
Michael Ortiz

Reputation: 777

I found the problem, and is found on the following line:

INCurrencyAmount *currencyAmt = [[INCurrencyAmount alloc] initWithAmount:[NSDecimalNumber decimalNumberWithString:@"100"] currencyCode:@"784"];

to

INCurrencyAmount *currencyAmt = [[INCurrencyAmount alloc] initWithAmount:[NSDecimalNumber decimalNumberWithString:@"100"] currencyCode:@"USD"]; 

Swift 3.0

let currencyAmmount = INCurrencyAmount(amount: NSDecimalNumber(string: "100"), currencyCode: "USD")

You are using an incorrect currency format with causes Siri to throw this message.

Upvotes: 2

Related Questions