Utviklere arbeider hele tiden for å gjøre appene mer avanserte, men er de faktisk brukbare av alle? For de fleste apper er svaret nei. For å nå det største publikum, la oss lære om måter å gjøre appene våre mer tilgjengelige.
Følg opp på FNs internasjonale dag for funksjonshemmede, la oss se på hvordan vi kan gjøre våre iOS-apper mer tilgjengelige.
I denne opplæringen bruker vi AVAudioEngine til å omskrive tale og vise den til brukeren som tekst (akkurat som Siri gjør på iPhone).
Denne opplæringen antar at du er dyktig i Swift, og at du er kjent med å bruke Xcode for iOS-utvikling.
For å følge med, kan du enten opprette et nytt prosjekt i Xcode eller laste ned prøveprosjektet for denne appen.
Hvis du jobber fra et nytt prosjekt, legger du til følgende linje øverst på din side ViewController.swift fil slik at talen API blir importert.
importere tale
Et annet skritt du må ta før du begynner, er å lage ViewController ()
klassen samsvarer med SFSpeechRecognizerDelegate
.
Når det er gjort, er du klar til å begynne opplæringen.
Siden Apple tar privatliv seriøst, er det fornuftig at de krever at utviklere spør brukerne om tillatelse før de bruker enhetsmikrofoner, særlig siden dataene sendes til Apples servere for analyse.
Ved taleinnkjenning kreves tillatelse fordi data overføres og midlertidig lagres på Apples servere for å øke nøyaktigheten av anerkjennelse. - Apple Documentation
I ditt Xcode-prosjekt må du åpne din Info.plist fil og legg til to nøkkelverdier par. Her er nøklene som du kan lime inn i:
NSMicrophoneUsageDescription
NSSpeechRecognitionUsageDescription
For verdiene kan du skrive inn en streng som nøyaktig beskriver de ønskede tillatelsene, og hvorfor du trenger dem. Slik ser det ut når de er lagt til:
Nå må vi faktisk spørre brukeren om tillatelse før vi kan fortsette. For å gjøre dette kan vi bare ringe en metode, beleilig kalt requestAuthorization ()
.
Men før vi gjør det, inne i din viewDidLoad ()
metode, legg til følgende linje av kode:
mikrofonButton.isEnabled = false
Som standard vil dette gjøre at knappen blir deaktivert, slik at det ikke er sjanse for at brukeren kan trykke på knappen før appen har mulighet til å sjekke med brukeren.
Deretter må du legge til følgende metodeanrop:
SFSpeechRecognizer.requestAuthorization (status) i OperationQueue.main.addOperation // Din kode går her
I ferdigstillingshåndteringen av denne metoden mottar vi statusen for autorisasjonen og setter den deretter til en konstant kalt status
. Etter det har vi et asynkront anrop som legger koden inne i blokken til hovedtråden (siden knappens tilstand må endres i hovedtråden).
Innsiden av addOperation
blokkere, må du legge til følgende bytte om
setning for å sjekke hva autorisasjonsstatusen egentlig er:
bytt status case .authorized: dictationButton.isEnabled = true promptLabel.text = "Trykk på knappen for å starte diktat ..." standard: dictationButton.isEnabled = false promptLabel.text = "Dictation ikke autorisert ..."
Vi slår på returverdien til authorizationStatus ()
funksjon. Hvis handlingen er autorisert (status
er .autorisert
), diktateknappen er aktivert og Trykk på knappen for å starte diktering ... er vist. Ellers er diktateknappen deaktivert og Diktat ikke autorisert ... er vist.
Deretter må vi designe et brukergrensesnitt for å kunne gjøre to ting: start eller stopp diktasjonen og vis den tolkte teksten. For å gjøre dette, gå til Main.storyboard fil.
Her er de tre grensesnittbyggerelementene du må fortsette med denne opplæringen:
UILabel
UITextView
UIButton
Siden plassering ikke er avgjørende i denne appen, vil jeg ikke dekke nøyaktig hvor og hvordan du plasserer alt, så følg bare denne grunnleggende wireframe når du plasserer brukergrensesnittelementene dine:
Som et referansepunkt, her er hva mitt storyboard ser ut på dette punktet:
Igjen er det greit hvis layoutet ditt ser annerledes ut, men bare sørg for at du har de samme tre grunnleggende elementene i wireframe. Lim inn følgende linjer med koden mot toppen av din ViewController ()
klasse:
@IBOutlet var promptLabel: UILabel! @IBOutlet var transkribertTextView: UITextView! @IBOutlet var dictationButton: UIButton!
Mot bunnen av ViewController ()
klasse, legger du til følgende funksjon som skal utløses når diktateknappen er tappet:
@IBAction func dictationButtonTapped () // Din kode går her
Det siste igjen å gjøre er å åpne Assistent Editor og koble til grensesnittbyggerens tilkoblinger til din Main.storyboard fil. Stikkene som vises ved siden av dem, skal nå vises fylt, og du vil nå kunne få tilgang til alle disse elementene som variabler og metoder, henholdsvis.
Nå er vi endelig klare til å starte talegjenkjenning. Det første trinnet er å skape de riktige variablene og konstantene som vi skal bruke gjennom hele prosessen. Under dine grensesnittbyggeruttak, legg til følgende linjer med kode:
la lydEngine = AVAudioEngine () la speechRecognizer = SFSpeechRecognizer (locale: Locale (ID: "en-US"))! var forespørsel: SFSpeechAudioBufferRecognitionRequest? var oppgave: SFSpeechRecognitionTask?
Her er en beskrivelse av hva variablene og konstantene gjør:
Audioengine
er en forekomst av AVAudioEngine ()
klasse. Denne klassen er, i enkle ord, en serie lyd noder. Lyd noder brukes til å gjøre forskjellige ting med lyd, for eksempel å generere og behandle det.speechRecognizer
er en forekomst av SFSpeechRecognizer ()
klasse. Denne klassen gjenkjenner ikke noe annet enn det angitte språket - i dette tilfellet, US English.be om
er en valgfri variabel av typen SFSpeechAudioBufferRecognitionRequest
, og det blir for øyeblikket initialisert til nil
. Senere i denne opplæringen, vil vi faktisk opprette en av disse og sette verdien når vi må bruke den. Dette brukes til å gjenkjenne inngangsdata fra enhetens mikrofon.oppgave
er en annen valgfri variabel, denne typen tid SFSpeechRecognition
. Senere bruker vi denne variabelen for å overvåke fremdriften av talegjenkjenningen.Etter at du har lagt til variablene, har du alt du trenger for å dykke rett inn i talegjenkjennelsesprosessen.
Nå skal vi gjøre hovedmetoden for talegjenkjenningsalgoritmen vår. Under viewDidLoad ()
metode, erklære følgende funksjon:
func startDictation () // Din kode går her
Siden vi ikke kjenner den nåværende statusen til oppgave
, Vi må avbryte den gjeldende oppgaven, og vi må derfor sette den tilbake til nil
(i tilfelle det ikke allerede er). Dette kan gjøres ved å legge til følgende to linjer med kode i metoden din:
oppgave? .cancel () oppgave = null
Flott! Nå vet vi at det ikke er en oppgave som allerede kjører. Dette er et viktig skritt når du bruker variabler som er deklarert utenfor metoden. En ting å merke seg er at vi bruker valgfri kjetting for å ringe Avbryt()
på oppgave
. Dette er en kortfattet måte å skrive på som vi bare vil ringe Avbryt()
hvis oppgave
er ikke null.
Nå må vi initialisere variablene vi opprettet tidligere i denne opplæringen. For å fortsette, legg til disse kodelinjene til din startDictation ()
metode fra forrige trinn:
request = SFSpeechAudioBufferRecognitionRequest () la lydSession = AVAudioSession.sharedInstance () la inputNode = audioEngine.inputNode vakt la request = request else return request.shouldReportPartialResults = true try? audioSession.setCategory (AVAudioSessionCategoryRecord) prøve? audioSession.setMode (AVAudioSessionModeMeasurement) prøve? audioSession.setActive (true, with: .notifyOthersOnDeactivation)
La oss slå det ned. Husk be om
variabel vi opprettet tidligere? Den første linjen med kode initialiserer den variabelen med en forekomst av SFSpeechAudioBufferRecognitionRequest
klasse.
Deretter tilordner vi den delte lydsesjonen til en konstant samtale audioSession
. Lydsesjonen oppfører seg som en mellommann mellom appen og selve enheten (og lydkomponentene).
Deretter setter vi inngangskoden til en singleton som heter inputNode
. For å starte opptak, vil vi senere opprette en springen
på denne noden.
Deretter bruker vi en vakt til å pakke ut be om
variabel som vi initialiserte tidligere. Dette er rett og slett for å unngå å måtte pakke ut dette senere i søknaden. Deretter aktiverer vi visning av ufullstendige resultater. Dette fungerer på samme måte som diktat på iPhone. Hvis du noen gang har brukt diktat, vet du at systemet teller ut hva det tenker, og deretter bruker du kontekstanvisninger, justerer ting om nødvendig.
Til slutt forsøker de tre siste kodelinjene å angi forskjellige attributter av lydsesjonen. Disse operasjonene kan kaste feil, så de må merkes med prøve?
søkeord. For å spare tid, ignorerer vi bare eventuelle feil som oppstår.
Nå har vi initialisert de fleste variablene som tidligere var i nulstaten. En siste variabel å initialisere er oppgave
variabel. Vi gjør det i neste trinn.
Initialiseringen av denne variabelen vil kreve en ferdigstillingsbehandler. Lim inn følgende kode i bunnen av din startDictation ()
metode:
oppgave = speechRecognizer.recognitionTask (med: request, resultHandler: (resultat, feil) i vakt la resultatet = resultat ellers return self.transcribedTextView.text = result.bestTranscription.formattedString hvis feil! = null || result.isFinal self.audioEngine.stop () self.request = null self.task = null inputNode.removeTap (onBus: 0))
Først oppretter vi en recognitionTask
med be om
som en parameter. Den andre parameteren er en lukking som definerer resultatbehandleren. De resultat
parameter er en forekomst av SFSpeechRecognitionResult
. I denne ferdigstillingsbehandleren må vi pakke ut resultatvariabelen igjen.
Deretter setter vi teksten i tekstvisningen til den beste transkripsjonen som algoritmen kan gi. Dette er ikke nødvendigvis perfekt, men det er det algoritmen mener passer best til det det hørte.
Til slutt, inne i dette hvis
erklæring, vi sjekker først om det er en feil, eller om resultatet er fullført. Hvis noen av disse er sanne, vil lydmotor og andre relaterte prosesser stoppe, og vi fjerner springen
. Ikke bekymre deg, du vil lære om kraner i neste trinn!
Til slutt, det øyeblikket du har ventet på! Vi kan endelig starte motoren vi har brukt så lenge på å skape. Vi gjør det ved å installere en "trykk". Legg til følgende kode under din oppgave
initialisering:
la recordingFormat = inputNode.outputFormat (forBus: 0) inputNode.installTap (onBus: 0, bufferSize: 1024, format: recordingFormat) (buffer, når) i self.request? .append (buffer)
I denne koden setter vi utdataformatet til inngangskoden til en konstant kalt recordingFormat
. Dette brukes i neste trinn for å installere en lyd springen
på inngangsknappen for å ta opp og overvåke lyd. Innsiden av ferdigstillingsbehandleren legger vi til buffer
i et PCM-format til slutten av godkjenningsforespørselen. For å starte motoren, legg bare til følgende to linjer med kode:
audioEngine.prepare () prøv? audioEngine.start ()
Dette forbereder seg og prøver å starte lydmaskinen. Nå må vi ringe denne metoden fra knappen vår, så la oss gjøre det i neste trinn.
Vi vil ikke at brukeren skal kunne aktivere talegjenkjenning, med mindre den er tilgjengelig for bruk, ellers kan appen krasje. Vi kan gjøre dette via en delegatemetode, så legg til følgende få linjer med kode under startDictation ()
metoden erklæring:
func speechRecognizer (_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange tilgjengelig: Bool) hvis tilgjengelig dictationButton.isEnabled = true else dictationButton.isEnabled = false
Dette vil bli kalt når talegjenkjenning blir tilgjengelig etter at den ikke er tilgjengelig eller utilgjengelig etter at den er tilgjengelig. Inne i det, vil vi ganske enkelt bruke en if-setning for å aktivere eller deaktivere knappen basert på tilgjengelighetsstatus.
Når knappen er deaktivert, vil brukeren ikke se noe, men knappen svarer ikke på kraner. Dette er et slags sikkerhetsnett for å forhindre at brukeren trykker på knappen for fort.
Det siste som er igjen å gjøre er å svare når brukeren tapper på knappen. Her kan vi også endre hva knappen sier, og fortelle brukeren hva de trenger å gjøre. For å oppdatere minnet ditt, her er det @IBAction
vi gjorde tidligere:
@IBAction func dictationButtonTapped () // Din kode går her
Innsiden av denne funksjonen, legg til følgende hvis setning:
hvis audioEngine.isRunning dictationButton.setTitle ("Start Recording", for:. normal) promptLabel.text = "Trykk på knappen for å diktere ..." forespørsel? .endAudio () audioEngine.stop () else dictationButton.setTitle (" Stop Recording ", for:. Normal) promptLabel.text =" Fortsett. Jeg lytter ... "startDictation ()
Hvis lydmotoren allerede kjører, vil vi stoppe talegjenkjenningen og vise den riktige spørringen til brukeren. Hvis den ikke kjører, må vi starte registrerings- og visningsalternativene for brukeren for å stoppe dikteringen.
Det er det! Du har opprettet en app som kan gjenkjenne stemmen din og transkribere den. Dette kan brukes til en rekke applikasjoner for å hjelpe brukere som ikke kan kommunisere med appene dine på andre måter. Hvis du likte denne opplæringen, må du sjekke ut de andre i denne serien!
Og mens du er her, sjekk ut noen av våre andre innlegg på Swift og iOS app utvikling!