user1620350
user1620350

Reputation:

AVSpeechSynthesizer Special characters

I'm using AVSpeechSynthesizer to read a string, but it gives an error if the string has any special characters like a emoji smile.

How toclean the string for special characters but leave support for japanese, chinese ?

Upvotes: 1

Views: 647

Answers (2)

patgdut
patgdut

Reputation: 103

Try this.Replace emoji strings with white space.

Note:If you need to highlight the text like UITextView,don't only remove the emoji strings,because - (void)speechSynthesizer:willSpeakRangeOfSpeechString:utterance: delegate method will get wrong range.

NSMutableString *string = [NSMutableString string];
NSString *text = @"Text with emoji.";    

[text enumerateSubstringsInRange:NSMakeRange(0, text.length)
                             options:NSStringEnumerationByComposedCharacterSequences
                          usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                              if ([substring isEmojiString]) {
                                  // If you need highlight text,replace the emoji with white space
                                  for (int i=0; i<substring.length; i++) {
                                      [string appendString:@" "];
                                  }
                              } else {
                                  [string appendString:substring];
                              }
                          }];

NSString Category

- (BOOL)isEmojiString {

BOOL returnValue = NO;
const unichar hs = [self characterAtIndex:0];
// surrogate pair
if (0xd800 <= hs && hs <= 0xdbff) {
    if (self.length > 1) {
        const unichar ls = [self characterAtIndex:1];
        const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
        if (0x1d000 <= uc && uc <= 0x1f77f) {
            returnValue = YES;
        }
    }
} else if (self.length > 1) {
    const unichar ls = [self characterAtIndex:1];
    if (ls == 0x20e3) {
        returnValue = YES;
    }

} else {
    // non surrogate
    if (0x2100 <= hs && hs <= 0x27ff) {
        returnValue = YES;
    } else if (0x2B05 <= hs && hs <= 0x2b07) {
        returnValue = YES;
    } else if (0x2934 <= hs && hs <= 0x2935) {
        returnValue = YES;
    } else if (0x3297 <= hs && hs <= 0x3299) {
        returnValue = YES;
    } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
        returnValue = YES;
    }
}

return returnValue;

}

Upvotes: 1

SPA
SPA

Reputation: 1289

Use the NSString method stringByTrimmingCharactersInSet with the inverted set of the NSCharacterSet alphanumeric, which will filter out the emoji

So if your string that contains emoji and Chinese characters is called 'textWithEmoji' then

NSString *textToSpeak = [textWithEmoji stringByTrimmingCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]];

'textToSpeak' will be the same text but without emoji, and other no alphanumeric characters

Upvotes: 1

Related Questions