Posts

Post marked as solved
2 Replies
791 Views
According to the WWDC19 video (Introducing Parameters for Shortcuts), the parameters are supposed to be resolved in the order you have placed them in the Intents Definition file in Xcode (see timestamp 13:02 through 13:16). In my objective C implementation, this is not happening. I deleted the derivedData and clean the build file, but that did not help. Here is a screenshot of my intents definition parameters: In my implementation, it seems to first process the parameters that do not have "Dynamic Options" check. Then it circles back and works on the ones that have "Dynamic Options". So in my case, it starts with partName, quantity, dimensions, thickness, width, and length. Then it works on partsListName. Furthermore, while the "Disambiguation Prompt" is spoken/written, the "Disambiguation Introduction" is NOT spoken/written. Is this a bug that is causing the parameters to be resolved in the wrong order, or do I need to do something differently to force it to resolve parameters in the order that I need it to go in? And are the "Disambiguation Introduction" supposed to work?
Posted
by jeffb6688.
Last updated
.
Post not yet marked as solved
0 Replies
234 Views
I have a custom intent with multiple parameters. Two of the parameters are set up to handle disambiguation dialog. The intent definition file for each of these parameters is almost identical except for the parameter names and the wording in the siri dialog. Similarly, the code in the intent handler to resolve these parameters is nearly identical. But when disambiguation is invoked, the Disambiguation Introduction is only spoken by siri for one of the two parameters. What triggers the Disambiguation Introduction to be spoken in one and not the other? Here is the intentHandler code to resolve the first parameter (in which siri will speak the Disambiguation Introduction: - (void)resolvePartsListNameForAddPart:(AddPartIntent *)intent withCompletion:(void (^)(INStringResolutionResult *resolutionResult))completion NS_SWIFT_NAME(resolvePartsListName(for:with:)) API_AVAILABLE(ios(13.0), macos(10.16), watchos(6.0)) { ... NSMutableArray *options; options = [[NSMutableArray alloc] init]; NSString *anOption = [NSString stringWithFormat:@"Use '%@' ", intent.partsListName]; // option 1 [options addObject:anOption]; anOption = [NSString stringWithFormat:@"test1"]; // option 2 [options addObject:anOption]; ... anOption = [NSString stringWithFormat:@"test5"]; // option 6 [options addObject:anOption]; completion([INStringResolutionResult disambiguationWithStringsToDisambiguate:[options copy]]); return; ... } Here is the intentHandler code to resolve the second parameter (in which siri DOES NOT speak the Disambiguation Introduction: - (void)resolveChangeForAddPart:(AddPartIntent *)intent withCompletion:(void (^)(INStringResolutionResult *resolutionResult))completion NS_SWIFT_NAME(resolveChange(for:with:)) API_AVAILABLE(ios(13.0), macos(10.16), watchos(6.0)) { ... NSMutableArray *options; options = [[NSMutableArray alloc] init]; NSString *anOption = [NSString stringWithFormat:WOOD_TYPE_PARM]; // option 1 [options addObject:anOption]; // Option 2 anOption = [NSString stringWithFormat:PART_NAME_PARM]; [options addObject:anOption]; // Option 3 anOption = [NSString stringWithFormat:QUANTITY_PARM]; [options addObject:anOption]; // Option 4 anOption = [NSString stringWithFormat:DIMENSION_PARM]; [options addObject:anOption]; // Option 5 anOption = [NSString stringWithFormat:CANCEL_PARM]; [options addObject:anOption]; completion([INStringResolutionResult disambiguationWithStringsToDisambiguate:[options copy]]); return; } Here is the Intents definition for the working parameter where Siri speaks the Disambiguation Introduction: Here is the Intents definition for the non-working parameter Again, what triggers the Disambiguation Introduction to be spoken in one and not the other? FYI: it does not make any difference whether or not the Disambiguation Introduction has the parameters 'count' and 'change' (i.e. if I make the introduction be Hello World, it still doesn't get spoken).
Posted
by jeffb6688.
Last updated
.
Post not yet marked as solved
1 Replies
1.2k Views
I have implemented a custom intent that has several parameters. One of the parameters is called "dimensions". I would like to give the user a hint on what to say to respond to the Siri Dialog Prompt for the dimensions parameter. For example, if the Siri Dialog Prompt is "What are the dimensions?", I would like to have a one time prompt that says "What are the dimensions? You can say something like 2 x 4 x 35 inches". Thereafter, I would like to fall back to having Siri only say "What are the dimensions?". Is this possible?
Posted
by jeffb6688.
Last updated
.
Post marked as solved
2 Replies
2.3k Views
The IntentHandler in my objective-C implementation of a custom intent fails to receive a call from a voice activated shortcut. When using Siri to invoke the donated interaction, I have observed that I receive the following errors in the Console app that claim the intent handler method for intent is unimplemented: -[INIntentDeliverer _invokeIntentHandlerMethodForIntent:intentHandler:parameterNamed:keyForSelectors:executionHandler:unimplementedHandler:] _invokeIntentHandlerMethodForIntent sirikit.intent.voice_commands.RunVoiceCommandIntent -[WFRVCIntentHandler stateMachineForIntent:] Created state machine <WFRVCStateMachine: 0x102e23970 state=WaitingForServer phase=Unknown> for intent with identifier 8A87FC68-329D-49FF-B534-B0A5821854CA -[INIntentDeliverer _invokeIntentHandlerMethodForIntent:intentHandler:parameterNamed:keyForSelectors:executionHandler:unimplementedHandler:] _invokeIntentHandlerMethodForIntent sirikit.intent.voice_commands.RunVoiceCommandIntent This error is consistent with the fact that an attempt to trigger the custom intent with a voice command results in iOS calling my appDelegate, and in particular the application:continueUserActivity:restorationHandler:. According to the documentation, the restorationHandler should only be called if the intent is not handled and must be handled by the main app. As there is very little documentation for an objective-C implementation, I cannot figure out what I am missing. I have tried to map the sample SoupChef app implementation of Siri Shortcuts to my implementation. I cannot figure out where I am going wrong. Here is my implementation (sorry for all the details, but I am hoping you can see something wrong): First, I have implemented two additional targets; a Shared Framework and an Intents Extension. I have also implemented an Intents Definition File. Here is an image of my targets: W_P_r is the main app, W_P_rKit is the shared framework, and PartsListManagerIntents is the Intents Extension. Next, here is my Intents Definition file and the target membership that it belongs to: I have also added an app group to the capabilities section of the add for both the main target and the PartsListIntentManager target. And I added Siri capability to the main target. All of this auto-creates some code, including a default IntentHandler.m and an info.plist in the PartsListManagerIntents target. I have updated the info.plist as follows: And here is the Auto-generated IntentHandler (which I have modified to log activity and to call a specific intent handler that resides in the W_P_rKit shared framework: #import "IntentHandler.h" #import <Intents/Intents.h> #import <W_P_rKit/W_P_rKit.h> #import "CreatePartsListIntentHandler.h" #import "P__tHandler.h" #import <os/log.h> @interface IntentHandler () /* <CreatePartsListIntentHandling, P__tHandling> */ @end @implementation IntentHandler - (id)handlerForIntent:(INIntent *)intent { os_log_with_type(OS_LOG_DEFAULT, OS_LOG_TYPE_DEBUG, "handlerForIntent: Reached IntentHandler."); if ([intent.identifier isEqualToString:@"P__rIntent"]) { NSLog(@"P__rIntent"); return [[P__rIntentHandler alloc] init]; } else if ([intent.identifier isEqualToString:@"CreatePartsListIntent"]) { NSLog(@"CreatePartsListIntent"); os_log_with_type(OS_LOG_DEFAULT, OS_LOG_TYPE_DEBUG, "handlerForIntent: IntentHandler Received CreatePartsListIntent."); return [[CreatePartsListIntentHandler alloc] init]; } return self; } Note that CreatePartsListIntentHandler is a class that implements the CreatePartsListIntentHandling protocol (resolve, confirm, and handle methods of the IntentHandler). Now here is the relevant implementation that should trigger iOS to call the IntentHandler: In my app at the point where the user fills in the name of a new project I make a call to donate the interaction as follows: CreatePartsListIntent *data = [[CreatePartsListIntent alloc] init]; data.projectName = [projectPlistName copy]; data.quantity = [NSNumber numberWithInteger : currentProjectQuantity]; [[W_P_rDonationManager sharedInstance] donateCreatePartsListIntent : data]; The call to donateCreatePartsListIntent does the following: data.suggestedInvocationPhrase = @"Create Parts List"; INInteraction* interaction = [[INInteraction alloc] initWithIntent:data response:nil]; [interaction donateInteractionWithCompletion:^(NSError * _Nullable error) { ... } Once the user has created the empty parts list (forcing the above interaction donation to occur), the view controller will present an "Add Siri Shortcut" button. The tapping of the button automatically calls the following method to create a shortcut: -(void) addCreatePartsListShortcutWasTapped { NSUserActivity *userActivity = [[W_P_rDonationManager sharedInstance] CreatePartsListShortcut]; INShortcut *shortcut = [[INShortcut alloc] initWithUserActivity:userActivity]; INUIAddVoiceShortcutViewController *addSiri = [[INUIAddVoiceShortcutViewController alloc] initWithShortcut:shortcut]; addSiri.delegate = self; [self presentViewController:addSiri animated:YES completion: nil]; } The call to CreatePartsListShortcut does the following: NSUserActivity *newActivity = [[NSUserActivity alloc] initWithActivityType: kW_P_rCreatePartsListActivityType]; newActivity.persistentIdentifier = kW_P_rCreatePartsListActivityType; newActivity.eligibleForSearch = TRUE; newActivity.eligibleForPrediction = TRUE; CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithContentType: UTTypeImage]; newActivity.title = @"Create Parts List"; attributeSet.contentDescription = @"Create a parts list for a new project"; newActivity.suggestedInvocationPhrase = @"Create Parts List"; UIImage *image = [UIImage imageNamed:@"W_P_r_Icon.jpg"]; NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)]; attributeSet.thumbnailData = imageData; newActivity.contentAttributeSet = attributeSet; return newActivity; This does create a shortcut that is visible in the shortcuts app. Clicking on the shortcut or saying the invocation phrase will take you directly to the the app delegate's application:userActivity:restorationHandler. But it does not call the IntentHandler. I know this because I have implemented logs that would tell me if the execution thread came there. Why is my IntentHandler not being called? Why is iOS sending the error message _invokeIntentHandlerMethodForIntent:intentHandler:parameterNamed:keyForSelectors:executionHandler:unimplementedHandler:? I have actually been struggling with this for weeks. Any help or hints would be so helpful.
Posted
by jeffb6688.
Last updated
.
Post not yet marked as solved
1 Replies
919 Views
I want to use Siri to perform a repetitive task in my app that inputs variable parameters, thus accelerating the input of that data. I have implemented a couple custom intents for background execution with the use of an intentDefinition file and implemented an IntentsExtension and associated plist to enable those custom intents. I can successfully donate an interaction that iOS matches with the supported suggestions in the intentsDefinition file that causes a Siri Suggestion to be displayed in Siri Search (or on the lock screen when enabled): CreatePartsListIntent* createPartsListIntent = [[CreatePartsListIntent alloc] init];     createPartsListIntent.projectName = intentData.projectName;     createPartsListIntent.quantity = intentData.quantity; INInteraction* interaction = [[INInteraction alloc] initWithIntent:createPartsListIntent response:nil];     [interaction donateInteractionWithCompletion:^(NSError * _Nullable error) {         if(!error) {             NSLog(@"CreatePartsList donation success");         }else {             NSLog(@"CreatePartsList donation fail %@",error.localizedDescription);         }     }]; I can then tap on this suggestion and it takes me to my appDelegate to process the interaction within the app - (id)application:(UIApplication *)application handlerForIntent:(INIntent *)intent { // This method is called when I tap on the Siri suggestion } But I want to process the interaction in the background using voice commands. When I speak the the command of the interaction I donated, the IntentHandler is never called. I cannot figure out what I need to do to get the IntentHandler to be called. According to the WWDC18 Intro to Siri Shortcuts, I should be able to invoke a dialog with Siri, which is my goal. Am I off track. Why isn't the IntentHandler being called? What should trigger it to be called?
Posted
by jeffb6688.
Last updated
.
Post not yet marked as solved
1 Replies
717 Views
I am attempting to donate an Interaction for a custom intent to create a Siri Shortcut. This is resulting in an execution error as follows: . . . *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x2837703c0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key pronunciationHint.' terminating with uncaught exception of type NSException This error occurs with the invocation of the following code block: `CreatePartsListIntent* createPartsListIntent = [[CreatePartsListIntent alloc] init];          createPartsListIntent.nameOfProject = intentData.nameOfProject;     createPartsListIntent.quantity = intentData.quantity;     INInteraction* interaction = [[INInteraction alloc] initWithIntent:createPartsListIntent response:nil];     [interaction donateInteractionWithCompletion:^(NSError * _Nullable error) {         if(!error) {             NSLog(@"CreatePartsList donation success");         }else {             NSLog(@"CreatePartsList donation fail %@",error.localizedDescription);         }     }];` I did a search for pronunciationHint. I found this in my intents.intentsDefinition file. It is a hidden parameter, but can be found when you open the file as propertyList. It is at the end of the file under INTypes. Below is a screenshot of the INTypes content found at the end of the intents.intentsDefinition file. If I delete Item 2 and Item 3 and delete the DerivedData, I still get the same NSException error, so I don't know where it is finding pronunciationHint and why it even cares that it is there. I am not even sure why the pronunciationHint parameter is being created. An excerpt of my intentDefinition file is shown below where it is showing the parameter TYPE that I created called Project. The auto creation of pronunciationHint is apparently related to the creation of this Project TYPE: Any ideas on how I can get by this error?
Posted
by jeffb6688.
Last updated
.
Post marked as solved
2 Replies
1.1k Views
I am implementing a couple custom intents in my app. Having completed the implementation of the custom intent definitions and the intent handlers which presumably should be called on voice command based on the suggestedInovocationPhrase, I am getting stumped with just getting IOS to recognize my shortcut donation. While the shortcut donation is executed multiple times from the view that I am trying to create the shortcut for, it is never being displayed in the shortcut app or on my lock screen as having been donated. In my settings App, I have turned on (under Developer) "Display Recent Shortcuts" and "Display Donations on Lock Screen". Here is the code that is executing each time I think I am making a donation: - (NSUserActivity *) CreateMyShortcut {     NSUserActivity *newActivity = [[NSUserActivity alloc] initWithActivityType: kMyShortCutActivityType];          if (@available(iOS 12.0, *)) {         newActivity.persistentIdentifier = kMyShortCutActivityType;         newActivity.eligibleForSearch = TRUE;         newActivity.eligibleForPrediction = TRUE;                  CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithContentType: UTTypeImage];                  newActivity.title = @"My Shortcut";         attributeSet.contentDescription = @"description";                  newActivity.suggestedInvocationPhrase = @"Create Widget";                  UIImage *image = [UIImage imageNamed:@"MyApp_Icon.jpg"];         NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];         attributeSet.thumbnailData = imageData;                  newActivity.contentAttributeSet = attributeSet;     }     return newActivity; } This is called from the view that I want to create the shortcut for with the following code:     // Donate a shortcut to allow Siri to assist with creating a parts list     NSUserActivity *activity = [[MyDonationManager sharedInstance] CreateMyShortcut];     NSLog(@"Donating Siri Shortcut");     [activity becomeCurrent]; Is there something else I need to do?
Posted
by jeffb6688.
Last updated
.
Post marked as solved
1 Replies
566 Views
I am trying to open the Apple Developer sample code Soup Chef. I get the error: SoupChef.xcodeproj' cannot be opened because it is in a future Xcode project file format. Adjust the project format using a compatible version of Xcode to allow it to be opened by this version of Xcode. When I open the project.PBXproj for this project, it has: compatibilityVersion = "Xcode 9.3"; I am currently running Xcode version 12.5.1. Does this mean that I have to revert back to an old version of Xcode to open this project? Doesn't make sense that their sample code for siri shortcuts wouldn't open with a current version of Xcode. Thoughts?
Posted
by jeffb6688.
Last updated
.