Reputation:
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
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
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