Accesibilitate pentru aplicațiile iOS Recunoaștere vorbire

Dezvoltatorii încearcă în mod constant să facă aplicațiile lor mai avansate, dar sunt efectiv utilizabile de toată lumea? Pentru majoritatea aplicațiilor, răspunsul este nu. Pentru a ajunge la cel mai mare public, să învățăm despre modalități prin care să facem aplicațiile mai accesibile. 

Urmărind Ziua Internațională a Persoanelor cu Dizabilități al Organizației Națiunilor Unite, să aruncăm o privire la modul în care putem face accesibilitatea aplicațiilor noastre pentru iOS.

În acest tutorial, vom folosi AVAudioEngine pentru a transcrie vorbirea și a le afișa utilizatorului ca text (la fel ca Siri pe iPhone).

Acest tutorial presupune că sunteți expert în Swift și că sunteți familiarizat cu utilizarea Xcode pentru dezvoltarea iOS. 

Setarea proiectului

Pentru a continua, puteți crea un nou proiect în Xcode sau puteți descărca proba de proiect pentru această aplicație. 

Dacă lucrați dintr-un proiect nou, adăugați următoarea linie în partea de sus a paginii ViewController.swift astfel încât API-ul de vorbire să fie importat. 

importă vorbire

Un alt pas pe care trebuie să-l faceți înainte de a începe este să faceți ViewController () clasa este conformă cu SFSpeechRecognizerDelegate

Odată ce ați terminat, sunteți gata să începeți tutorialul. 

1. Solicitarea permisiunii

Din moment ce Apple ia in serios intimitatea, are sens ca ei au nevoie de dezvoltatori pentru a cere utilizatorilor permisiunea inainte de a folosi microfoanele dispozitivului, mai ales ca datele sunt trimise la serverele Apple pentru analize.

În cazul recunoașterii vorbirii, este necesară permisiunea deoarece datele sunt transmise și stocate temporar pe serverele Apple pentru a spori acuratețea recunoașterii. - Documentația Apple

În proiectul dvs. Xcode, va trebui să vă deschideți Info.plist fișier și adăugați două perechi cheie-valoare. Iată cheile pe care le poți lipi:

  • NSMicrophoneUsageDescription
  • NSSpeechRecognitionUsageDescription

Pentru valori, puteți introduce orice șir care descrie cu exactitate permisiunile dorite și de ce veți avea nevoie de ele. Asa ar trebui sa arate dupa ce au fost adaugate:

Acum, va trebui să cerem permisiunea utilizatorului înainte de a putea continua. Pentru a face acest lucru, putem numi o metodă convenabilă requestAuthorization ().

Dar înainte de a face asta, înăuntrul tău viewDidLoad () adăugați următoarea linie de cod:

microphoneButton.isEnabled = false

Implicit, acest lucru va face ca butonul să fie dezactivat, astfel încât să nu existe nicio șansă ca utilizatorul să apese butonul înainte ca aplicația să aibă posibilitatea de a verifica cu utilizatorul. 

Apoi, va trebui să adăugați următorul apel de metodă:

SFSpeechRecognizer.requestAutorizare (status) în OperationQueue.main.addOperation // Codul dvs. merge aici

În cadrul manualului de completare a acestei metode, primim starea autorizației și apoi o setăm la o constantă numită stare. Apoi, avem un apel asincron care adaugă codul în interiorul blocului la firul principal (deoarece starea butonului trebuie schimbată în firul principal).

În interiorul addOperation bloc, va trebui să adăugați următoarele intrerupator pentru a verifica ce este starea de autorizare:

starea comutării caz .autorizat: dictationButton.isEnabled = adevărat promptLabel.text = "Apăsați butonul pentru a începe dictarea ..." implicit: dictationButton.isEnabled = false promptLabel.text = "Dicționarea nu este autorizată ..."

Schimbăm valoarea returnată a authorizationStatus () funcţie. Dacă acțiunea este autorizată (stare este .autorizat), butonul de dictare este activat și Atingeți butonul pentru a începe dictarea ...  este afisat. În caz contrar, butonul de dictare este dezactivat și Dicționarea nu este autorizată ...  este afisat.

2. Proiectarea interfeței utilizator

Apoi, va trebui să proiectăm o interfață de utilizator pentru a putea face două lucruri: începerea sau oprirea dictării și afișarea textului interpretat. Pentru a face acest lucru, mergeți la Main.storyboard fişier.

Iată cele trei elemente de construcție a interfeței de care veți avea nevoie pentru a continua cu acest tutorial:

  • UILabel
  • UITextView
  • UIButton

Deoarece plasarea nu este esențială în această aplicație, nu voi mai acoperi exact unde și cum să plasați totul, deci pur și simplu urmați această schemă de bază atunci când plasați elementele interfeței utilizator:

Ca un punct de referință, iată cum arată scenariul meu în acest moment:

Din nou, este bine dacă aspectul dvs. arată diferit, dar asigurați-vă că aveți aceleași trei elemente de bază în cadrul wireframe. Acum, lipiți următoarele linii de cod în partea de sus a dvs. ViewController () clasă:

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

Spre sfârșitul paginii ViewController () , adăugați pur și simplu următoarea funcție care va fi declanșată la apăsarea butonului de dictare:

@IBAction function dictationButtonTapped () // Codul dvs. merge aici

Ultimul lucru pe care trebuie să-l faceți este să-l deschideți Editor asistent și conectați conexiunile constructorului interfeței la dvs. Main.storyboard fişier. Punctele care apar lângă ele ar trebui să apară acum completate și acum veți putea accesa toate aceste elemente ca variabile și metode.

3. Adăugarea de variabile

Acum suntem gata să începem recunoașterea vorbirii. Primul pas este de a crea variabilele și constantele corespunzătoare pe care le vom folosi pe parcursul întregului proces. Sub punctele de desfacere ale constructorului de interfețe, adăugați următoarele linii de cod:

permiteți audioEngine = AVAudioEngine () let speechRecognizer = SFSpeechRecognizer (locale: Locale (identificator: "en-US"))! var cerere: SFSpeechAudioBufferRecognitionRequest? var task: SFSpeechRecognitionTask?

Iată o descriere a ceea ce fac variabilele și constantele:

  • audioEngine este o instanță a AVAudioEngine () clasă. Această clasă este, în termeni simpli, o serie de noduri audio. Nodurile audio sunt folosite pentru a face diferite lucruri cu audio, cum ar fi generarea și prelucrarea acestora.
  • speechRecognizer este o instanță a SFSpeechRecognizer () clasă. Această clasă nu recunoaște altceva decât limba specificată - în acest caz, engleza americană.
  • cerere este o variabilă opțională de tip SFSpeechAudioBufferRecognitionRequest, și se inițiază în prezent la zero. Mai târziu, în acest tutorial, vom crea unul dintre acestea și vom stabili valoarea când trebuie să îl folosim. Aceasta va fi utilizată pentru a recunoaște datele de intrare de la microfonul dispozitivului.
  • sarcină este o altă variabilă opțională, în acest moment de tip SFSpeechRecognition. Mai târziu, vom folosi această variabilă pentru a monitoriza progresul recunoașterii vocale.

După ce ați adăugat variabilele, aveți tot ce aveți nevoie pentru a vă scufunda chiar în procesul de recunoaștere a vorbirii.

4. Declararea metodei de dictare

Acum, vom fi principala metodă pentru algoritmul nostru de recunoaștere vocală. Sub viewDidLoad () , declarați următoarea funcție:

func startDictation () // Codul dvs. merge aici

Din moment ce nu știm starea actuală a sarcină, va trebui să anulam sarcina curentă și apoi trebuie să o readusăm înapoi zero (în cazul în care nu este deja). Acest lucru se poate face adăugând următoarele două linii de cod în metoda dvs.:

sarcina? .cancel () task = nil

Grozav! Acum știm că nu există deja o sarcină. Acesta este un pas important când utilizați variabilele declarate în afara scopului metodei. Un lucru de remarcat este că folosim lanțul opțional pentru a apela Anulare() pe sarcină. Acesta este un mod concis de scriere pe care nu dorim decât să-l sunăm Anulare() dacă sarcină nu este zero.

5. Inițializarea variabilelor

Acum, trebuie să inițializăm variabilele create mai devreme în acest tutorial. Pentru a continua, adăugați aceste linii de cod la dvs. startDictation () din etapa anterioară:

request = SFSpeechAudioBufferRecognitionRequest () permite audioSession = AVAudioSession.sharedInstance () permite inputNode = audioEngine.inputProtejeazăNodul lasă cererea = cere altceva return request.shouldReportPartialResults = adevărat încercați? audioSession.setCategory (AVAudioSessionCategoryRecord) încercați? audioSession.setMode (AVAudioSessionModeMeasurement) încercați? audioSession.setActive (true, with: .notifyOthersOnDeactivation)

Să-l rupem. Amintiți-vă cerere care am creat mai devreme? Prima linie de cod iniționează acea variabilă cu o instanță a SFSpeechAudioBufferRecognitionRequest clasă. 

Apoi, atribuim instanța de sesiune audio partajată unei constante numite audioSession. Sesiunea audio se comportă ca un om de mijloc între aplicație și dispozitivul însuși (și componentele audio).

După aceea, am setat nodul de intrare la un singur apel numit inputNode. Pentru a începe înregistrarea, vom crea mai târziu o Atingeți pe acest nod.

Apoi, vom folosi un gardian pentru a despacheta cerere variabilă pe care am inițializat-o mai devreme. Acest lucru este doar pentru a evita necesitatea de a dezveli acest lucru mai târziu în cerere. Apoi vom permite afișarea rezultatelor incomplete. Acest lucru funcționează în mod similar cu dictarea pe iPhone - dacă ați folosit vreodată dictare, veți ști că sistemul tipizează tot ce gândește și apoi, folosind indicii de context, ajustează lucrurile, dacă este necesar. 

În cele din urmă, ultimele trei linii de cod încearcă să seteze diferite atribute ale sesiunii audio. Aceste operațiuni pot arunca erori, deci trebuie să fie marcate cu încerca? cuvinte cheie. Pentru a economisi timp, vom ignora eventualele erori care apar. 

Acum am inițializat majoritatea variabilelor care au fost anterior în starea zero. O ultimă variabilă care trebuie inițializată este sarcină variabil. Vom face asta în pasul următor.

6. Inițializarea variabilei Task

Initializarea acestei variabile va necesita un handler de completare. Inserați următorul cod în partea de jos a ferestrei startDictation () metodă:

task = speechRecognizer.recognitionTask (cu: request, resultHandler: (rezultatul, eroarea) in paza let result = rezultat else return self.transcribedTextView.text = result.bestTranscription.formattedString daca eroare! = nil || result.isFinal  self.audioEngine.stop () self.request = nulă self.task = null inputNode.removeTap (onBus: 0))

În primul rând, creăm un recognitionTask cu cerere ca parametru. Al doilea parametru este o închidere care definește dispozitivul de preluare a rezultatelor. rezultat parametru este o instanță de SFSpeechRecognitionResult. În acest handler de completare, trebuie să reluăm din nou variabila rezultată. 

Apoi, setăm textul vizualizării noastre text pentru a fi cea mai bună transcriere pe care algoritmul o poate oferi. Acest lucru nu este neapărat perfect, dar este ceea ce algoritmul crede că se potrivește cel mai bine cu ceea ce a auzit.

În cele din urmă, înăuntru dacă , verificăm mai întâi dacă există o eroare sau dacă rezultatul este finalizat. Dacă oricare dintre acestea este adevărat, motorul audio și alte procese conexe se vor opri și vom elimina Atingeți. Nu vă faceți griji, veți învăța despre robinete în pasul următor!

7. Pornirea motorului audio

În sfârșit, în momentul în care ați așteptat! În sfârșit, putem începe motorul pe care l-am petrecut atât de mult timp creând. O vom face prin instalarea unui "robinet". Adăugați următorul cod de mai jos sarcină initializare:

permiteți inputFormat = inputNode.outputFormat (forBus: 0) inputNode.installTap (onBus: 0, bufferSize: 1024, format: recordingFormat) (buffer, when) în self.request?

În acest cod, setăm formatul de ieșire al nodului de intrare la o constantă numită recordingFormat. Acest lucru este folosit în următorul pas pentru a instala un sunet Atingeți pe nodul de intrare pentru înregistrarea și monitorizarea sunetului. În interiorul handlerului de completare, adăugăm tampon într-un format PCM până la sfârșitul cererii de recunoaștere. Pentru a porni motorul, adăugați următoarele două linii de cod:

audioEngine.prepare () încercați? audioEngine.start ()

Aceasta pregătește pur și simplu și apoi încearcă să pornească motorul audio. Acum, trebuie să numim această metodă din butonul nostru, așa că hai să facem asta în pasul următor.

8. Dezactivarea și activarea butonului

Nu vrem ca utilizatorul să poată activa recunoașterea vocală dacă nu este disponibil pentru a fi utilizat - în caz contrar, aplicația se poate prăbuși. Putem face acest lucru printr-o metodă de delegat, deci adăugați următoarele câteva linii de cod de mai jos startDictation () declarație de metodă:

func speechRecognizer (_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange disponibil: Bool) dacă este disponibil dictationButton.isEnabled = true altceva dictationButton.isEnabled = false

Aceasta va fi apelată atunci când recunoașterea vocală devine disponibilă după ce nu este disponibilă sau nu este disponibilă după ce a fost disponibilă. În interiorul acestuia, vom folosi pur și simplu o declarație if pentru a activa sau a dezactiva butonul în funcție de starea de disponibilitate.

Când butonul este dezactivat, utilizatorul nu va vedea nimic, dar butonul nu va răspunde robinetelor. Acesta este un fel de plasă de siguranță pentru a împiedica apăsarea prea rapidă a butonului.

9. Răspundeți la butoanele de buton

Ultimul lucru pe care trebuie să îl faceți este să răspundeți atunci când utilizatorul pune pe buton butonul. Aici, putem schimba și ceea ce spune butonul și îi spun utilizatorului ce trebuie să facă. Pentru a vă reîmprospăta memoria, iată @IBAction am făcut mai devreme:

@IBAction function dictationButtonTapped () // Codul dvs. merge aici

În interiorul acestei funcții, adăugați următoarea declarație if:

dacă audioEngine.isRunning dictationButton.setTitle ("Începeți înregistrarea", pentru: .normal) promptLabel.text = "Atingeți butonul pentru a dicta ..." cererea ?.endAudio () audioEngine.stop () altceva dictationButton.setTitle (" Opriți înregistrarea ", pentru: .normal) promptLabel.text =" Continuați, ascult ... "startDictation ()

Dacă motorul audio funcționează deja, dorim să oprim recunoașterea vocală și să afișăm promptul corespunzător utilizatorului. Dacă nu rulează, trebuie să pornim opțiunile de recunoaștere și afișare pentru ca utilizatorul să oprească dictarea.

Concluzie

Asta e! Ați creat o aplicație care vă poate recunoaște vocea și o puteți transcrie. Acest lucru poate fi folosit pentru o varietate de aplicații pentru a ajuta utilizatorii care nu pot interacționa cu aplicațiile dvs. în alte moduri. Dacă v-ați plăcut acest tutorial, asigurați-vă că ați verificat celelalte din această serie!

Și în timp ce sunteți aici, verificați câteva dintre celelalte postări despre dezvoltarea aplicațiilor Swift și iOS!

Cod