web-dev-qa-db-fra.com

le bouton de raccourci siri (INUIAddVoiceShortcutButton) affiche un titre incorrect lorsque plusieurs raccourcis sont utilisés (NSUserActivity)

J'ai 2 raccourcis siri dans mon application. J'utilise NSUserActivity pour faire don de ces raccourcis. J'ai également créé 2 NSUserActivityTypes dans mon info.plist. 

Deux contrôleurs de vue gèrent ces raccourcis (1 contrôleur de vue pour 1 raccourci).

Si j'ajoute 1 raccourci siri à partir d'un contrôleur de vue puis passe au contrôleur de vue 2e, le bouton de raccourci siri natif (INUIAddVoiceShortcutButton) sur le contrôleur de vue 2e sélectionne automatiquement le premier raccourci (créé à partir du premier contrôleur de vue) et affiche le message "Ajouté à Siri" phrase au lieu d’afficher le bouton "Ajouter à Siri". J'ai vérifié deux fois que chaque NSUserActivity a un identifiant différent mais qu'il choisit toujours le mauvais raccourci.

Contrôleur de vue 1:

let userActivity = NSUserActivity(activityType: "com.activity.type1")
userActivity.isEligibleForSearch = true
userActivity.isEligibleForPrediction = true
userActivity.title = shortcut.title
userActivity.suggestedInvocationPhrase = suggestedPhrase

let attributes = CSSearchableItemAttributeSet(itemContentType: kUTTypeItem as String)
attributes.contentDescription = description
userActivity.contentAttributeSet = attributes
let shortcut = INShortcut(userActivity: userActivity)
let siriButton = INUIAddVoiceShortcutButton(style: .whiteOutline)
siriButton.translatesAutoresizingMaskIntoConstraints = false
siriButton.shortcut = shortcut
self.view.addSubview(siriButton)

Contrôleur de vue 2:

let userActivity2 = NSUserActivity(activityType: "com.activity.type2")
userActivity2.isEligibleForSearch = true
userActivity2.isEligibleForPrediction = true
userActivity2.title = shortcut.title
userActivity2.suggestedInvocationPhrase = suggestedPhrase

let attributes = CSSearchableItemAttributeSet(itemContentType: kUTTypeItem as String)
attributes.contentDescription = description
userActivity2.contentAttributeSet = attributes

let shortcut = INShortcut(userActivity: userActivity2)
let siriButton = INUIAddVoiceShortcutButton(style: .whiteOutline)
siriButton.translatesAutoresizingMaskIntoConstraints = false
siriButton.shortcut = shortcut
self.view.addSubview(siriButton)

Une chose semblable se produit lorsque je supprime l'application et que je réinstalle sans supprimer les raccourcis de l'application Paramètres du téléphone.

6
Bilal

On dirait que c'est un bogue IOS. J'ai trouvé une solution de contournement pour ce problème. Vous devez créer un nouveau bouton siri chaque fois que l'utilisateur ajoute/modifie le raccourci siri. Avant de créer le bouton siri faites les choses suivantes

1- Obtenez tous les raccourcis vocaux de INVoiceShortcutCenter en appelant la fonction. Notez que cela se produit de manière asynchrone. Vous devez donc le faire un certain temps avant d’avoir besoin des données (par exemple, dans votre AppDelegate). Vous devrez également le recharger chaque fois que l'utilisateur ajoutera un raccourci Siri (probablement dans la méthode INUIAddVoiceShortcutViewControllerDelegate.addVoiceShortcutViewController(_:didFinishWith:error)).

INVoiceShortcutCenter.shared.getAllVoiceShortcuts  { (voiceShortcutsFromCenter, error) in
    guard let voiceShortcutsFromCenter = voiceShortcutsFromCenter else {
            if let error = error as NSError? {
                os_log("Failed to fetch voice shortcuts with error: %@", log: OSLog.default, type: .error, error)
            }
            return
        }
        self.voiceShortcuts = voiceShortcutsFromCenter
}

2- Dans View Controller-1, vérifiez si le raccourci est déjà ajouté ou non en itérant tous les raccourcis vocaux.

let voiceShorcut = voiceShortcuts.first { (voiceShortcut) -> Bool in
    if let activity = voiceShortcut.shortcut.userActivity, activity.activityType == "com.activity.type1" {
        return true
    }
    return false
}

3- Si votre raccourci vocal est enregistré, passez le bouton INShortcut à siri, sinon ne le configurez pas.

if voiceShorcut != nil {
    let shortcut = INShortcut(userActivity: userActivity1)
    siriButton.shortcut = shortcut
} 

Faites la même chose dans Second View Controller.

2
Bilal

C'est iOS 12.0 bug . Vous pouvez le corriger en mettant à jour INUIAddVoiceShortcutButton.voiceShortcut avec la valeur correcte . Utilisez KVO pour observer la propriété "voiceShortcut" et, le cas échéant, lui attribuer la valeur correcte.

3
Vitaliy Alekseev

Je suis passé maintenant à la configuration des intentions et je constate que même avec une seule configuration des intentions et en utilisant INUIAddVoiceShortcutButton , il est impossible de suivre mon raccourci. Une fois la phrase enregistrée, le message Ajouté à Siri s'affiche.

Mais chaque fois que l'application relance, le bouton Ajouter à Siri s'affiche au lieu du bouton Ajouté à Siri avec la phrase enregistrée.

J'ai essayé de suivre la suggestion de Bilal et bien que je puisse voir que INVoiceShortcutCenter me montre mon raccourci tel qu'il est présent, il ne l'a pas chargé dans le bouton Siri.

Mon code ressemble à ceci pour le bouton lui-même. 

 private func addSiriButton() {
    let addShortcutButton = INUIAddVoiceShortcutButton(style: .blackOutline)
    addShortcutButton.delegate = self

    addShortcutButton.shortcut = INShortcut(intent: engine.intent )
    addShortcutButton.translatesAutoresizingMaskIntoConstraints = false

    siriButtonSubView.addSubview(addShortcutButton)
    siriButtonSubView.centerXAnchor.constraint(equalTo: addShortcutButton.centerXAnchor).isActive = true
    siriButtonSubView.centerYAnchor.constraint(equalTo: addShortcutButton.centerYAnchor).isActive = true

}

Tous les protocoles sont implémentés et j’ai jeté un œil attentif sur l’application Soup mais je ne peux tout simplement pas comprendre ce qui motive cette inexactitude.

Assez drôle, même les développeurs d’applications de British Airways ont renoncé à cela car leur bouton a exactement le même comportement de défaut.

Mise à jour : J'ai construit un autre projet test avec une implémentation minimale pour l'intention et les options Ajouter à Siri et Ajouté à Siri fonctionne parfaitement. Je suppose à ce stade qu’il ya quelque chose dans mon propre codebase d’applications qui cause ce comportement indésirable.

update 2 Je voulais juste que tout le monde sache que j'ai résolu le problème. Utiliser les intentions fonctionne bien, mais le fichier de définition des intentions lui-même comporte un peu de sensibilité. Tout ce que j'avais à faire était de créer une nouvelle intention qui a ensuite été générée et qui a fonctionné. Il semble que mon intention initiale ait été corrompue, mais il n'y a pas eu d'erreur. Après avoir créé une autre intention et réaffecté la fonction de gestion de l'intention à celle-ci, tout s'est déroulé comme prévu. (jeu de mots intentionnel)

0
Dan Korkelia

Je viens de résoudre ce problème moi-même en modifiant mon implémentation (basée à l'origine sur l'application soupchef) sur cet exemple de code fourni par Apple ( https://developer.Apple.com/documentation/sirikit/inuiaddvoiceshortcutbutton ):

EDIT: j'ai ajouté du code indiquant comment créer et transmettre le raccourciObjet (INShortcut) pour les raccourcis UserActivity et les intentions personnalisées.

La classe Shortcut est une énumération qui contient une propriété calculée appelée intention qui renvoie une instanciation de l'intention personnalisée.

private func addShortcutButton(shortcut: Shortcut, parentViewController: UIViewController, shortcutViewControllerDelegate: INUIAddVoiceShortcutViewControllerDelegate) {
    guard let view = parentViewController.view else { return }

    if let intent = shortcut.intent {
        shortcutObject = INShortcut(intent: intent)
    } else if let userActivity = view.userActivity {
        shortcutObject = INShortcut(userActivity: userActivity)
    }

    self.shortcutViewControllerDelegate = shortcutViewControllerDelegate
    addSiriButton(to: shortcutButtonContainer)
}

func addSiriButton(to view: UIView) {
    let button = INUIAddVoiceShortcutButton(style: .whiteOutline)
    button.translatesAutoresizingMaskIntoConstraints = false

    view.addSubview(button)
    view.centerXAnchor.constraint(equalTo: button.centerXAnchor).isActive = true
    view.centerYAnchor.constraint(equalTo: button.centerYAnchor).isActive = true

    button.addTarget(self, action: #selector(addToSiri(_:)), for: .touchUpInside)
}

// Present the Add Shortcut view controller after the
// user taps the "Add to Siri" button.
@objc
func addToSiri(_ sender: Any) {
    guard let shortcutObject = shortcutObject else { return }
    let viewController = INUIAddVoiceShortcutViewController(shortcut: shortcutObject)
    viewController.modalPresentationStyle = .formSheet
    viewController.delegate = shortcutViewControllerDelegate
    parentViewController?.present(viewController, animated: true, completion: nil)
}
0
rmooney