Velkommen til den syvende avbetalingen i serien vår om hvordan å utforme og bygge en 1980-versjon av IOS? Telefon? app. I denne veiledningen vil jeg demonstrere hvordan du spiller den riktige lydtonen for hvert nummer på telefonens tastatur.
Dette er et øyeblikksbilde av hva vi skal bygge i løpet av denne serien:
Dette er en flerdelerserie designet for å undervise iOS SDK-emner. Innholdet vil bli stadig mer komplisert etter hvert som serien går videre. Hvis du til enhver tid har mistet deg i å følge denne serien, må du kanskje gå et skritt tilbake og jobbe deg gjennom vår Læringsmål-C-serie eller vår begynnende iOS SDK Development-serie.
I den siste opplæringen i denne serien demonstrerte jeg hvordan jeg faktisk starter en iPhone-samtale etter at du har tastet et nummer på tastaturet, og hvordan du formaterer nummervisningen når en bruker tapper et siffer. I denne veiledningen legger vi til de lovede berøringstonene til hver av knappene 0 - 9.
IOS SDK leveres med flere rammer som gir ulike metoder for å spille lydklipp og til og med generere lyd på fly. Apples Multimedia Programmering Guide beskriver formålet med hvert tilgjengelig lydramme som følger:
En hel serie opplæringsprogrammer kan være dedikert til hvert av rammene i listen ovenfor, men det er nok å si at i denne veiledningen vil vi bruke Audio Toolbox-rammeverket på grunn av ett unikt tilbud: System Sound Services. System Sound Services er et C-nivå grensesnitt beregnet for å spille korte brukergrensesnitt lydeffekter og andre små lydklipp med 30 sekunder eller mindre.
Prosessen for å spille et lydklipp med System Sound Services spenner over tre trinn:
Resten av denne opplæringen vil implementere denne prosessen for å spille innspilte DTMF-toner for tastaturstallene 0-9.
Hvorfor bruker vi forhåndsinnspilte toner i stedet for å generere riktig frekvens på flyet? For det meste å spare tid og å holde denne opplæringen mer tilgjengelig ved å unngå matematikken involvert i sinusformede funksjoner og frekvensgenerering. Hvis du vil gå den ruten i stedet, vil du sannsynligvis finne følgende artikler hendig:
Vil du virkelig vite hvordan du genererer lyd på flyet? Hvis dette innlegget mottar minst 10 kommentarer som ber om en opplæring om hvordan du lager lyd fra grunnen innen 1. mai 2011, lager jeg en avansert iOS SDK-serie på det aktuelle emnet. Ingen løfter om at det vil innebære DTMF-toner spesielt, men det vil definitivt være noe gøy.
Med teoretisk kunnskap ut av veien, la oss dykke inn i koden og få denne funksjonen ferdig!
Vi må begynne med å importere Audio Toolbox-rammen i vårt program for å gjøre System Sound Services tilgjengelig for vår kode. For å gjøre dette, velg "PhoneAppSkin" -prosjektet i Prosjektnavigator-panelet i Xcode, velg deretter "PhoneAppSkin" under "TARGETS", og til slutt velg "Build Phases" -fanen. Etter dette skal skjermen se slik ut:
Deretter klikker du på "Link binære med biblioteker", og klikker på "+" -symbolet for å legge til et nytt rammeverk for prosjektets koblingsfase.
Til slutt finner du "AudioToolbox" -rammen i popup-vinduet, og deretter klikker du "Legg til".
Deretter åpner du PhoneViewController.h fil og legg til linjen som er nødvendig for å faktisk importere Audio Toolbox-rammen i klassen din:
#importere#importere
Lydverktøy-funksjonene skal nå være tilgjengelige for klassen din!
Last ned og åpne kildekoden knyttet til denne Mobiletuts + posten og finn mappen med tittelen "Audio". Dra hele denne mappen til "Ressurser" -mappen i Xcode Project Navigator, pass på at du merker "Kopier" -alternativet når du blir bedt om det. Du bør ende opp med en skjerm noe som dette:
I PhoneViewController.h, legg til følgende C-style array-erklæring:
@interface PhoneViewController: UIViewController SystemSoundID toneSSIDs [10];
Linje 13 erklærer en type C-stil av typen SystemSoundID
med en maksimal kapasitet på 10.
Lagring av systemlyd-ID-er i denne gruppen gjør at vi raskt kan referere til riktig lydklipp i numberButtonPressed:
metode senere.
Åpen PhoneViewController.m og hopp til initWithCoder
metode på linje 17. Når PhoneViewController
er først initialisert og initWithCoder
Metoden kalles, vi vil registrere systemlyder for hver tone som skal brukes på tastaturet med iOS system lyd server. Etter at et lydklipp er registrert hos lydserveren, kan vi instruere serveren til å avspille lydfilen senere når tastaturet trykkes inn.
For å registrere 0-9 berøringstoner, legg til følgende kode:
-(id) initWithCoder: (NSCoder *) aDecoder self = [super initWithCoder: aDecoder]; hvis (selv) phoneNumberString = [[NSString alloc] init]; for (int count = 0; count < 10; count++) NSString *toneFilename = [NSString stringWithFormat:@"DTMF_%02d", count]; NSURL *toneURLRef = [[NSBundle mainBundle] URLForResource:toneFilename withExtension:@"wav"]; SystemSoundID toneSSID = 0; AudioServicesCreateSystemSoundID( (CFURLRef) toneURLRef, &toneSSID ); toneSSIDs[count] = toneSSID; return self;
På linje 24, en til
loop som vil iterere 10 ganger begynner. Hensikten med dette til
loop er å legge til en ny system lyd ID til toneSSIDs
array for hver av berøringstonene knyttet til tastene 0-9.
På linje 25, en forekomst av NSString
er instantiated som vil holde filnavnet til den relevante DTMF berøringssignalen. Et interessant notat på denne linjen er stringWithFormat:
metallsamtale og % 02d
format spesifiserer. Dette formatet spesifiserer konverterer et hvilket som helst tall til et nullpolstret siffer på 2 tegn. Så for eksempel blir 0 00 ', blir 1' 01 ', 2 blir' 02 ', osv.
På linje 27, de NSBundle
klassen brukes til å generere en filsystembane til filnavnet generert på linje 25 med en utvidelse av "wav" vedlagt. NSLog
denne verdien hvis du vil se hele banen for deg selv.
Linje 29 lager en variabel for å holde SystemSoundID
som vil bli generert av iOS system lyd server neste.
Som en side notat,
SystemSoundID
er bare en typedef for Mac Typeuint32
, som selv er en typedef forusignert lenge
. Derfor kunne vi ha erklært variabelen på denne typen linjeusignert lenge
, men det ville være dårlig praksis fordi fremtidige iOS-utgivelser kan endreSystemSoundID
skriv, forårsaker koden å bryte. Ikke desto mindre er det godt å huske på dette når du jobber medSystemSoundID
s fordi kompilatoren noen ganger vil advare om inkompatibelusignert lenge
typer.
Linjer 31 - 34 er en c-stil-funksjonskall til AudioServicesCreateSystemSoundID
, som tar a CFURL
(Core Foundation URL) av lydfilbanen for å generere en System Sound ID for og en SystemSoundID-referanse som vil bli brukt til å lagre SSID-en etter at den er opprettet. Legg merke til hvordan ampersand karakteren (dvs. '&') vises før toneSSID
variabel på linje 33? Dette er en unary prefiks operatør som konverterer toneSSID
parameter i minnesadressen til variabelen i stedet for verdien lagret i minnet for den variabelen. Dette er gjort slik at AudioServicesCreateSystemSoundID
funksjonen kan lagre det genererte SSID nummeret direkte i toneSSID
minnesadresse, slik at funksjonalderen (det vil si vår metode) tilgang til det genererte SSID uten at SSID'en egentlig sendes tilbake fra funksjonen.
Lyder litt forvirrende? Det vil nok med mindre du allerede har erfaring med programmering på et språk som C, C ++ eller Go. Fordi Objective-C er en streng erstatning for C-språket, er iOS SDK noen ganger avhengig av biblioteker skrevet i prosedyre C. Hvis C-setningen ikke gir mening for deg, ikke bekymre deg for det for mye akkurat nå, men ta det som en utfordring for å utfylle din iOS SDK kunnskap med grunnleggende av C-språket i fremtiden!
På linje 35, indeksen av toneSSIDs
c-style array utpekt av gjeldende telle
verdien tilordnes verdien som er opprettet av AudioServicesCreateSystemSoundID
funksjon. Denne SSID-verdien vil bli referert senere for å spille den riktige tonen når brukeren tapper på tastaturnumrene.
De numberButtonPressed:
Metoden kalles hver gang touchUpInside
hendelsesbrann for knappene 0 - 9. Fordi indeksene 0-9 av toneSSIDs
array inneholder nå den tilsvarende tonen for hver knapp, de følgende tre kodelinjene er nok til å spille den riktige tonen:
-(IBAction) numberButtonPressed: (UIButton *) pressedButton int toneIndex = [pressedButton.titleLabel.text intValue]; SystemSoundID toneSSID = toneSSIDs [toneIndex]; AudioServicesPlaySystemSound (toneSSID); self.phoneNumberString = [self.phoneNumberString stringByAppendingString: pressedButton.titleLabel.text]; [self displayPhoneNumber];
Linje 96 konverterer tekstverdien til den trykte UIButton
tittel til et heltall fra en streng.
Med det numeriske nummeret som er oppnådd, linje 97 henter a SystemSoundID
fra toneSSIDs
matrise.
På linje 98, de AudioServicesPlaySystemSound
funksjonen kalles med SSID nettopp hentet for å starte avspilling av berøringstonen.
Det er det! Gå videre og lagre og bygge prosjektet nå, og du burde oppdage at tastaturnumrene har lydeffekter!
Det er et lite problem med den nåværende løsningen. Legg merke til forsinkelsen mellom å trykke på knappen og den genererte tonen? I del 6 av denne serien ble tastaturknappene konfigurert for å utløse touchUpInside
handling. Denne handlingen brenner etter at brukeren fjerner fingeren fra knappen. Tonen skal imidlertid spilles så snart brukeren tapper på knappen, ikke etter å ha fjernet fingeren. For å fikse dette, åpne PhoneView.xib
, fjern touchUpInside
IBAction
referanser for alle knapper, og bind deretter hver knapp Touchdown
handling til numberButtonPressed:
metode.
Hvis du trenger hjelp å finne ut hvordan du gjør dette trinnet, referer du bare til del 6, trinn 1 i denne serien.
Denne opplæringen har vært en hvirvelvindstur i Audio Toolbox-rammeverket og System Sound Services. Hvis du har spørsmål, vær så snill å legge dem i kommentarene nedenfor, og jeg vil gjøre mitt beste for å svare. Selvfølgelig er det ikke nok timer på dagen for meg å sjekke alle mine tidligere innlegg for nye kommentarer hver dag, så som månedene har på deg, kan du ha lykke til å kontakte meg via Twitter: @markhammonds.