5

In my app, users can add tasks to lists via Sirikit (example Siri intent query: "In MyApp add to expense list 100 dollars for jeans"). if the list suggested is not available in the app, I ask for disambiguation.

the result from multiple choice in disambiguation is not captured in resolveTargetTaskList.

intent.targetTaskList?.title is the value I passed in the first try. as a result, it enters an infinite loop.

func resolveTargetTaskList(for intent: INAddTasksIntent, with completion: @escaping (INTaskListResolutionResult) -> Void) {  
    guard let title = intent.targetTaskList?.title else {  
        completion(.needsValue())  
        print("no title value")              
    }  
    completeResolveTaskList(listName: intent.targetTaskList!.title, with: completion)  
}  



public func completeResolveTaskList(listName: INSpeakableString, with completion: @escaping (INTaskListResolutionResult) -> Void) {  
    print("completeResolveTaskList")  
    let allLists = getAllLists()  
    for index in 0...(allLists.count - 1) {  
        if allLists[index].spokenPhrase.lowercased() == listName.spokenPhrase.lowercased() {  
            completion(.success(with: taskLists[index]))  
        }  
    }  

    switch allLists.count {  
    case 0:  
        completion(.unsupported())  
    default:  
        completion(.disambiguation(with: taskLists))  
    }  
}  

screenshot for reference:

screenshot

Please help me.

rajeswari ratala
  • 650
  • 7
  • 14
  • The screenshots don't help as much as probably some debugging output would. Have you inspected what values `title` and `spokenPhrase` have? As a side-note, when using `guard let title = ...` you don't need to force-unwrap it from the targetTaskList later on, just use `title` directly. – Gero Jul 09 '19 at 12:35

1 Answers1

0

On second reading I think I see it:

You need to return right after completion(.success(with: taskLists[index])), otherwise you will still execute the rest of the function, which includes a recursive call.

In general I'd advise to modify your function like so:

public func completeResolveTaskList(listName: INSpeakableString, with completion: @escaping (INTaskListResolutionResult) -> Void) {  
    print("completeResolveTaskList")  
    let allLists = getAllLists()
    guard let matching = allLists.first(where: { $0.spokenPhrase.lowercased() == listName.spokenPhrase.lowercased() }) else {
        switch allLists.count {  
        case 0:  
            completion(.unsupported())  
        default:  
            completion(.disambiguation(with: taskLists))  
        }
        return
    }

    completion(.success(with: matching))  
}

This matches, imo, the flow a bit closer and in a more swifty way. Granted, the else for the guard statement is a little longer, but you could always refactor that into another method. In general it's more like "get me the first element that matches the input. If you don't find any, do some fallback, otherwise proceed normally". It also gets rid of iterating over the list with an index.

Gero
  • 4,394
  • 20
  • 36
  • The title is not changing even after I select an option. That is the reason why it is going into an infinite loop. matching is always nil. – rajeswari ratala Jul 09 '19 at 16:22
  • That just means that whatever `intent` your `resolveTargetTaskList` method gets is completely off from what you have defined in your `getAllLists` method. I gave this answer because your original code would have likely ended in an infinite loop anyways since you never prevented the execution of the completion block in the `switch` statement (and I assume `getAllLists` usually doesn't return an empty array). Anyways, to repeat my other comment: *What are your actual values?* Look at this, there's likely your problem. – Gero Jul 11 '19 at 06:29
  • As Pavel suggested in https://forums.developer.apple.com/message/369393#369393 when I say the option, the intent acquires the said list name. looks like a bug in sirikit. thanks for your reply – rajeswari ratala Jul 11 '19 at 10:38