Accessibilité pour les applications iOS reconnaissance vocale

Les développeurs cherchent constamment à rendre leurs applications plus avancées, mais sont-elles réellement utilisables par tout le monde? Pour la plupart des applications, la réponse est non. Afin de toucher le plus large public possible, découvrons des moyens de rendre nos applications plus accessibles.. 

Dans le prolongement de la Journée internationale des personnes handicapées des Nations Unies, voyons comment rendre nos applications iOS plus accessibles..

Dans ce didacticiel, nous utiliserons AVAudioEngine pour transcrire un discours et l’afficher sous forme de texte (comme le fait Siri sur votre iPhone)..

Ce tutoriel suppose que vous maîtrisiez bien Swift et que vous maîtrisiez l’utilisation du développement Xcode pour iOS.. 

Configuration du projet

Pour suivre, vous pouvez créer un nouveau projet dans Xcode ou télécharger l'exemple de projet pour cette application.. 

Si vous travaillez à partir d'un nouveau projet, ajoutez la ligne suivante en haut de votre ViewController.swift fichier afin que l'API Speech soit importée. 

importer le discours

Une autre étape à franchir avant de commencer consiste à faire le ViewController () classe conforme à la SFSpeechRecognizerDelegate

Une fois que c'est fait, vous êtes prêt à commencer le tutoriel.. 

1. Demander une autorisation

Étant donné qu'Apple prend la confidentialité au sérieux, il est logique de demander aux développeurs de demander l'autorisation des utilisateurs avant d'utiliser les microphones de l'appareil, d'autant plus que les données sont envoyées aux serveurs d'Apple pour analyse..

Dans le cas de la reconnaissance vocale, une autorisation est requise car les données sont transmises et stockées temporairement sur les serveurs Apple pour augmenter la précision de la reconnaissance.- Documentation Apple

Dans votre projet Xcode, vous devrez ouvrir votre Info.plist fichier et ajouter deux paires clé-valeur. Voici les clés que vous pouvez coller:

  • NSMicrophoneUsageDescription
  • NSSpeechRecognitionUsageDescription

Pour les valeurs, vous pouvez entrer n'importe quelle chaîne décrivant avec précision les autorisations souhaitées et la raison pour laquelle vous en aurez besoin. Voici à quoi cela devrait ressembler une fois qu'ils sont ajoutés:

Nous devrons maintenant demander l’autorisation de l’utilisateur avant de pouvoir continuer. Pour ce faire, nous pouvons simplement appeler une méthode, appelée commodément requestAuthorization ().

Mais avant cela, dans votre viewDidLoad () méthode, ajoutez la ligne de code suivante:

microphoneButton.isEnabled = false

Par défaut, le bouton sera désactivé, de sorte qu'il n'y ait aucune chance que l'utilisateur appuie sur le bouton avant que l'application n'ait la possibilité de vérifier auprès de l'utilisateur.. 

Ensuite, vous devrez ajouter l'appel de méthode suivant:

SFSpeechRecognizer.requestAuthorization (statut) dans OperationQueue.main.addOperation // Votre code va ici

Dans le gestionnaire d'achèvement de cette méthode, nous recevons le statut de l'autorisation, puis nous le configurons comme une constante appelée statut. Après cela, nous avons un appel asynchrone qui ajoute le code à l'intérieur du bloc au thread principal (puisque l'état du bouton doit être modifié dans le thread principal)..

À l'intérieur de la addOperation bloquer, vous devrez ajouter ce qui suit commutateur déclaration pour vérifier le statut de l'autorisation:

statut du commutateur case .authorized: dictationButton.isEnabled = true promptLabel.text = "Appuyez sur le bouton pour commencer la dictée ..." par défaut: dictationButton.isEnabled = false promptLabel.text = "Dictée non autorisée…"

Nous activons la valeur de retour du autorisationStatus () une fonction. Si l'action est autorisée (statut est .autorisé), le bouton de dictée est activé et Appuyez sur le bouton pour commencer la dictée…  est affiché. Sinon, le bouton de dictée est désactivé et Dictée non autorisée…  est affiché.

2. Conception de l'interface utilisateur

Ensuite, nous devrons concevoir une interface utilisateur pour pouvoir faire deux choses: démarrer ou arrêter la dictée et afficher le texte interprété. Pour ce faire, dirigez-vous vers le Tableau principal fichier.

Voici les trois éléments de construction d'interface dont vous aurez besoin pour continuer avec ce tutoriel:

  • UILabel
  • UITextView
  • UIButton

Étant donné que le placement n'est pas déterminant dans cette application, je ne couvrirai pas exactement où et comment tout placer. Il vous suffit donc de suivre cette structure filaire de base lors du placement des éléments de votre interface utilisateur:

En guise de référence, voici à quoi ressemble mon story-board:

Encore une fois, si votre mise en page est différente, vous pouvez vous assurer que les trois mêmes éléments de base sont identiques. Maintenant, collez les lignes de code suivantes en haut de votre ViewController () classe:

@IBOutlet var promptLabel: UILabel! @IBOutlet var transcribeTextView: UITextView! @IBOutlet var dictationButton: UIButton!

Vers le bas de la ViewController () classe, ajoutez simplement la fonction suivante à déclencher lorsque vous appuyez sur le bouton de dictée:

@IBAction func dictationButtonTapped () // Votre code va ici

La dernière chose à faire est d'ouvrir le Assistant rédacteur et connectez les connexions du constructeur d'interface à votre Tableau principal fichier. Les points qui apparaissent à côté d’eux devraient maintenant apparaître remplis, et vous pourrez maintenant accéder à tous ces éléments en tant que variables et méthodes, respectivement..

3. Ajouter des variables

Nous sommes enfin prêts à commencer la reconnaissance vocale. La première étape consiste à créer les variables et constantes appropriées que nous utiliserons tout au long du processus. Sous les sorties de votre générateur d'interface, ajoutez les lignes de code suivantes:

let audioEngine = AVAudioEngine () let speechRecognizer = SFSpeechRecognizer (paramètre régional: paramètre régional (identificateur: "en-US"))! demande var: SFSpeechAudioBufferRecognitionRequest? tâche var: SFSpeechRecognitionTask?

Voici une description de ce que font les variables et les constantes:

  • audioEngine est un exemple de AVAudioEngine () classe. Cette classe est, en termes simples, une série de nœuds audio. Les nœuds audio servent à différentes tâches audio, telles que la génération et le traitement de celle-ci..
  • reconnaissance vocale est un exemple de SFSpeechRecognizer () classe. Cette classe ne reconnaît rien d’autre que la langue spécifiée - dans ce cas, l’anglais américain.
  • demande est une variable optionnelle de type SFSpeechAudioBufferRecognitionRequest, et il est en cours d'initialisation à néant. Plus loin dans ce didacticiel, nous en créerons un et définirons sa valeur lorsque nous en aurons besoin. Ceci sera utilisé pour reconnaître les données d'entrée du microphone de l'appareil.
  • tâche est une autre variable optionnelle, cette fois de type SFSpeechReconnaissance. Plus tard, nous utiliserons cette variable pour surveiller les progrès de notre reconnaissance vocale.

Après avoir ajouté les variables, vous avez tout ce dont vous avez besoin pour plonger dans le processus de reconnaissance vocale.

4. Déclarer la méthode de dictée

Nous allons maintenant créer la méthode principale de notre algorithme de reconnaissance vocale. Sous le viewDidLoad () méthode, déclarez la fonction suivante:

func startDictation () // Votre code va ici

Puisque nous ne connaissons pas l’état actuel de la tâche, nous devons annuler la tâche en cours, puis nous devons la redéfinir sur néant (au cas où ce ne soit pas déjà fait). Cela peut être fait en ajoutant les deux lignes de code suivantes à votre méthode:

tâche? .cancel () tâche = nil

Génial! Nous savons maintenant qu’il n’ya pas de tâche en cours. Il s'agit d'une étape importante lorsque vous utilisez des variables déclarées en dehors de la portée de la méthode. Une chose à noter est que nous utilisons un chaînage optionnel pour appeler Annuler() sur tâche. C’est une façon d’écrire concise que nous voulons seulement appeler Annuler() si tâche n'est pas nul.

5. Initialisation des variables

Maintenant, nous devons initialiser les variables que nous avons créées précédemment dans ce tutoriel. Pour continuer, ajoutez ces lignes de code à votre startDictation () méthode de l'étape précédente:

request = SFSpeechAudioBufferRecognitionRequest () let audioSession = AVAudioSession.sharedInstance () let inputNode = audioEngine.inputNode guard let request = request else retour request.shouldReportPartialResults = true try? audioSession.setCategory (AVAudioSessionCategoryRecord) essayer? audioSession.setMode (AVAudioSessionModeMeasurement) essayer? audioSession.setActive (true, avec: .notifyOthersOnDeactivation)

Faisons le décomposer. Se souvenir du demande variable que nous avons créée plus tôt? La première ligne de code initialise cette variable avec une instance de SFSpeechAudioBufferRecognitionRequest classe. 

Ensuite, nous affectons l’instance de session audio partagée à une constante appelée audioSession. La session audio se comporte comme un intermédiaire entre l'application et l'appareil lui-même (et les composants audio).

Après cela, nous définissons le noeud d’entrée sur un singleton appelé inputNode. Pour commencer l’enregistrement, nous créerons plus tard un robinet sur ce noeud.

Ensuite, nous utilisons un garde pour déballer le demande variable que nous avons initialisée plus tôt. Ceci est simplement pour éviter d'avoir à décompresser cela plus tard dans l'application. Ensuite, nous activerons l'affichage des résultats incomplets. Cela fonctionne de la même façon que la dictée sur iPhone: si vous avez déjà utilisé la dictée, le système saisit ce qu'il pense, puis, à l'aide d'indices de contexte, ajuste les choses si nécessaire.. 

Enfin, les trois dernières lignes de code tentent de définir divers attributs de la session audio. Ces opérations peuvent générer des erreurs, elles doivent donc être marquées du essayer? mot-clé. Pour gagner du temps, nous ignorons simplement les erreurs éventuelles.. 

Nous avons maintenant initialisé la plupart des variables précédemment à l'état nul. Une dernière variable à initialiser est la tâche variable. Nous ferons cela dans la prochaine étape.

6. Initialisation de la variable de tâche

L'initialisation de cette variable nécessitera un gestionnaire d'achèvement. Collez le code suivant dans le bas de votre startDictation () méthode:

task = speechRecognizer.recognitionTask (avec: request, resultHandler: (résultat, erreur) dans la garde let result = result else return self.transcribTextView.text = result.bestTranscription.formattedString si error! = nil || result.isFinal  self.audioEngine.stop () self.request = nil self.task = nil inputNode.removeTap (onBus: 0))

Tout d'abord, nous créons un tâche de reconnaissance avec le demande en paramètre. Le deuxième paramètre est une fermeture définissant le gestionnaire de résultats. le résultat paramètre est une instance de SFSpeechRecognitionResult. À l'intérieur de ce gestionnaire d'achèvement, nous devons à nouveau dérouler la variable de résultat. 

Ensuite, nous définissons le texte de notre vue comme la meilleure transcription fournie par l’algorithme. Ce n'est pas nécessairement parfait, mais c'est ce que l'algorithme pense le mieux correspondre à ce qu'il a entendu.

Enfin, à l'intérieur de cette si déclaration, nous vérifions d’abord s'il y a une erreur ou si le résultat est finalisé. Si l’un d’entre eux est vrai, le moteur audio et d’autres processus connexes s’arrêteront, et nous supprimerons le robinet. Ne vous inquiétez pas, vous en apprendrez plus sur les robinets à l'étape suivante.!

7. Démarrer le moteur audio

Enfin, le moment que vous avez attendu! Nous pouvons enfin démarrer le moteur que nous avons passé tant de temps à créer. Nous ferons cela en installant un "tap". Ajoutez le code suivant sous votre tâche initialisation:

let recordingFormat = inputNode.outputFormat (forBus: 0) inputNode.installTap (onBus: 0, bufferSize: 1024, format: recordingFormat) (tampon, quand) dans self.request? .append (tampon)

Dans ce code, nous définissons le format de sortie du nœud d'entrée sur une constante appelée enregistrementFormat. Ceci est utilisé dans la prochaine étape pour installer un fichier audio robinet sur le nœud d'entrée pour enregistrer et surveiller l'audio. À l'intérieur du gestionnaire d'achèvement, nous ajoutons le tampon dans un format PCM jusqu'à la fin de la demande de reconnaissance. Pour démarrer le moteur, ajoutez simplement les deux lignes de code suivantes:

audioEngine.prepare () try? audioEngine.start ()

Cela prépare simplement et tente ensuite de démarrer le moteur audio. Maintenant, nous devons appeler cette méthode depuis notre bouton, faisons-le à l'étape suivante.

8. Désactivation et activation du bouton

Nous ne voulons pas que l'utilisateur puisse activer la reconnaissance vocale, sauf si elle est disponible, sinon l'application pourrait se bloquer. Nous pouvons le faire via une méthode déléguée, ajoutez donc les quelques lignes de code suivantes sous le startDictation () déclaration de méthode:

func speechRecognizer (_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) si disponible dictationButton.isEnabled = true else dictationButton.isEnabled = false

Ceci sera appelé lorsque la reconnaissance vocale devient disponible après avoir été indisponible ou indisponible après avoir été disponible. À l'intérieur, nous utiliserons simplement une instruction if pour activer ou désactiver le bouton en fonction de l'état de disponibilité..

Lorsque le bouton est désactivé, l'utilisateur ne voit rien, mais le bouton ne répond pas aux tapotements. Ceci est une sorte de filet de sécurité pour empêcher l'utilisateur d'appuyer sur le bouton trop rapidement.

9. Répondre aux taps de bouton

La dernière chose à faire est de répondre lorsque l'utilisateur appuie sur le bouton. Ici, nous pouvons également modifier le contenu du bouton et indiquer à l'utilisateur ce qu'il doit faire. Pour vous rafraîchir la mémoire, voici la @IBAction nous avons fait plus tôt:

@IBAction func dictationButtonTapped () // Votre code va ici

À l'intérieur de cette fonction, ajoutez l'instruction if suivante:

if audioEngine.isRunning dictationButton.setTitle ("Démarrer l'enregistrement", pour: .normal) promptLabel.text = "Appuyez sur le bouton pour dicter…" demander? .endAudio () audioEngine.stop () else dictationButton.setTitle (" Arrêter l'enregistrement ", pour: .normal) promptLabel.text =" Allez-y. Je vous écoute… "startDictation ()

Si le moteur audio est déjà en cours d'exécution, nous souhaitons arrêter la reconnaissance vocale et afficher l'invite appropriée à l'intention de l'utilisateur. S'il n'est pas en cours d'exécution, nous devons lancer la reconnaissance et afficher les options permettant à l'utilisateur d'arrêter la dictée..

Conclusion

C'est tout! Vous avez créé une application qui peut reconnaître votre voix et la retranscrire. Cela peut être utilisé pour diverses applications afin d'aider les utilisateurs qui ne peuvent pas interagir avec vos applications de différentes manières. Si vous avez aimé ce tutoriel, assurez-vous de consulter les autres de cette série.!

Et pendant que vous êtes ici, consultez certains de nos autres articles sur le développement d'applications Swift et iOS.!