Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Commit

Permalink
Fix hasPermission() always returning success on iOS
Browse files Browse the repository at this point in the history
- Use `[AVAudioSession sharedInstance] recordPermission` to check mic permissions

Closes #89
  • Loading branch information
leshik committed Oct 19, 2018
1 parent f998b16 commit 2dd231e
Showing 1 changed file with 98 additions and 74 deletions.
172 changes: 98 additions & 74 deletions src/ios/SpeechRecognition.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define MESSAGE_RESTRICTED @"Speech recognition restricted on this device"
#define MESSAGE_NOT_DETERMINED @"Speech recognition not determined on this device"
#define MESSAGE_ACCESS_DENIED_MICROPHONE @"User denied access to microphone"
#define MESSAGE_NOT_DETERMINED_MICROPHONE @"Microphone access not determined on this device"
#define MESSAGE_ONGOING @"Ongoing speech recognition"

@interface SpeechRecognition()
Expand Down Expand Up @@ -58,100 +59,97 @@ - (void)startListening:(CDVInvokedUrlCommand*)command {
return;
}

[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted){
if (!granted) {
NSLog(@"startListening() microphone access not authorized");
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:MESSAGE_ACCESS_DENIED_MICROPHONE];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
return;
}
AVAudioSessionRecordPermission micStatus = [[AVAudioSession sharedInstance] recordPermission];
if (micStatus != AVAudioSessionRecordPermissionGranted) {
NSLog(@"startListening() microphone access not authorized");
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:MESSAGE_MISSING_PERMISSION];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
return;
}

NSString* language = [command argumentAtIndex:0 withDefault:DEFAULT_LANGUAGE];
int matches = [[command argumentAtIndex:1 withDefault:@(DEFAULT_MATCHES)] intValue];
BOOL showPartial = [[command argumentAtIndex:3 withDefault:@(NO)] boolValue];
NSString* language = [command argumentAtIndex:0 withDefault:DEFAULT_LANGUAGE];
int matches = [[command argumentAtIndex:1 withDefault:@(DEFAULT_MATCHES)] intValue];
BOOL showPartial = [[command argumentAtIndex:3 withDefault:@(NO)] boolValue];

NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:language];
self.speechRecognizer = [[SFSpeechRecognizer alloc] initWithLocale:locale];
self.audioEngine = [[AVAudioEngine alloc] init];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:language];
self.speechRecognizer = [[SFSpeechRecognizer alloc] initWithLocale:locale];
self.audioEngine = [[AVAudioEngine alloc] init];

// Cancel the previous task if it's running.
if ( self.recognitionTask ) {
[self.recognitionTask cancel];
self.recognitionTask = nil;
}
// Cancel the previous task if it's running.
if ( self.recognitionTask ) {
[self.recognitionTask cancel];
self.recognitionTask = nil;
}

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
[audioSession setMode:AVAudioSessionModeDefault error:nil];
[audioSession setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
[audioSession setMode:AVAudioSessionModeDefault error:nil];
[audioSession setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];

self.recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init];
self.recognitionRequest.shouldReportPartialResults = showPartial;
self.recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init];
self.recognitionRequest.shouldReportPartialResults = showPartial;

AVAudioInputNode *inputNode = self.audioEngine.inputNode;
AVAudioFormat *format = [inputNode outputFormatForBus:0];
AVAudioInputNode *inputNode = self.audioEngine.inputNode;
AVAudioFormat *format = [inputNode outputFormatForBus:0];

self.recognitionTask = [self.speechRecognizer recognitionTaskWithRequest:self.recognitionRequest resultHandler:^(SFSpeechRecognitionResult *result, NSError *error) {
self.recognitionTask = [self.speechRecognizer recognitionTaskWithRequest:self.recognitionRequest resultHandler:^(SFSpeechRecognitionResult *result, NSError *error) {

if ( result ) {
if ( result ) {

NSMutableArray *resultArray = [[NSMutableArray alloc] init];
NSMutableArray *resultArray = [[NSMutableArray alloc] init];

int counter = 0;
for ( SFTranscription *transcription in result.transcriptions ) {
if (matches > 0 && counter < matches) {
[resultArray addObject:transcription.formattedString];
}
counter++;
int counter = 0;
for ( SFTranscription *transcription in result.transcriptions ) {
if (matches > 0 && counter < matches) {
[resultArray addObject:transcription.formattedString];
}
counter++;
}

NSArray *transcriptions = [NSArray arrayWithArray:resultArray];
NSArray *transcriptions = [NSArray arrayWithArray:resultArray];

NSLog(@"startListening() recognitionTask result array: %@", transcriptions.description);
NSLog(@"startListening() recognitionTask result array: %@", transcriptions.description);

CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:transcriptions];
if (showPartial){
[pluginResult setKeepCallbackAsBool:YES];
}
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:transcriptions];
if (showPartial){
[pluginResult setKeepCallbackAsBool:YES];
}
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

if ( error ) {
NSLog(@"startListening() recognitionTask error: %@", error.description);
if ( error ) {
NSLog(@"startListening() recognitionTask error: %@", error.description);

[self.audioEngine stop];
[self.audioEngine.inputNode removeTapOnBus:0];
[self.audioEngine stop];
[self.audioEngine.inputNode removeTapOnBus:0];

self.recognitionRequest = nil;
self.recognitionTask = nil;
self.recognitionRequest = nil;
self.recognitionTask = nil;

CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.description];
if (showPartial){
[pluginResult setKeepCallbackAsBool:YES];
}
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.description];
if (showPartial){
[pluginResult setKeepCallbackAsBool:YES];
}
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

if ( result.isFinal ) {
NSLog(@"startListening() recognitionTask isFinal");

[self.audioEngine stop];
[self.audioEngine.inputNode removeTapOnBus:0];
if ( result.isFinal ) {
NSLog(@"startListening() recognitionTask isFinal");

self.recognitionRequest = nil;
self.recognitionTask = nil;
}
}];

[inputNode installTapOnBus:0 bufferSize:1024 format:format block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) {
[self.recognitionRequest appendAudioPCMBuffer:buffer];
}];
[self.audioEngine stop];
[self.audioEngine.inputNode removeTapOnBus:0];

[self.audioEngine prepare];
[self.audioEngine startAndReturnError:nil];
self.recognitionRequest = nil;
self.recognitionTask = nil;
}
}];

[inputNode installTapOnBus:0 bufferSize:1024 format:format block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) {
[self.recognitionRequest appendAudioPCMBuffer:buffer];
}];

[self.audioEngine prepare];
[self.audioEngine startAndReturnError:nil];
}

- (void)stopListening:(CDVInvokedUrlCommand*)command {
Expand Down Expand Up @@ -183,18 +181,44 @@ - (void)getSupportedLanguages:(CDVInvokedUrlCommand*)command {

- (void)hasPermission:(CDVInvokedUrlCommand*)command {
SFSpeechRecognizerAuthorizationStatus status = [SFSpeechRecognizer authorizationStatus];
BOOL speechAuthGranted = (status == SFSpeechRecognizerAuthorizationStatusAuthorized);
CDVPluginResult *pluginResult = nil;
BOOL speechAuthGranted = NO;

switch (status) {
case SFSpeechRecognizerAuthorizationStatusAuthorized:
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
speechAuthGranted = YES;
break;
case SFSpeechRecognizerAuthorizationStatusDenied:
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:MESSAGE_ACCESS_DENIED];
break;
case SFSpeechRecognizerAuthorizationStatusRestricted:
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:MESSAGE_RESTRICTED];
break;
case SFSpeechRecognizerAuthorizationStatusNotDetermined:
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:MESSAGE_NOT_DETERMINED];
break;
}

if (!speechAuthGranted) {
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:NO];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
return;
}

[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted){
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:granted];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}];
AVAudioSessionRecordPermission micStatus = [[AVAudioSession sharedInstance] recordPermission];

switch (micStatus) {
case AVAudioSessionRecordPermissionGranted:
break;
case AVAudioSessionRecordPermissionDenied:
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:MESSAGE_ACCESS_DENIED_MICROPHONE];
break;
case AVAudioSessionRecordPermissionUndetermined:
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:MESSAGE_NOT_DETERMINED_MICROPHONE];
break;
}

[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

- (void)requestPermission:(CDVInvokedUrlCommand*)command {
Expand Down

0 comments on commit 2dd231e

Please sign in to comment.