Reputation: 13
I am trying to detect if a user of my app entered an emoji into UITextView. I have found this code:
https://gist.github.com/cihancimen/4146056
However this code is not working for all emojis (for instance it is not working for the hearth symbol). Does anyone have a clue how to improve the code to catch all emojis? I am using Objective-C language. Any help is appreciated.
Upvotes: 0
Views: 1803
Reputation: 7031
If you need to be able to detect any emoji, you'll need to create a list containing all code points used for emoji (or a list of all emoji if you prefer). If you want to, you can look at how emoji are detected in this framework, which I created for the purpose of replacing standard emoji with custom images, or take a look at my answer to a related question.
Then, if you're working with Objective-C and the NSString
type, you'll first have to convert the string's unichar
s (which are UTF-16 encoded) into UTF-32 compatible format in order to use your list of code points. When you have the UTF-32 value, just compare it against your list and handle it however you need:
// Sample text.
NSString *text = @"a 😁";
// Get the UTF-16 representation of the text.
unsigned long length = text.length;
unichar buffer[length];
[text getCharacters:buffer];
// Initialize array to hold our UTF-32 values.
NSMutableArray *array = [[NSMutableArray alloc] init];
// Temporary stores for the UTF-32 and UTF-16 values.
UTF32Char utf32 = 0;
UTF16Char h16 = 0, l16 = 0;
for (int i = 0; i < length; i++) {
unichar surrogate = buffer[i];
// High surrogate.
if (0xd800 <= surrogate && surrogate <= 0xd83f) {
h16 = surrogate;
continue;
}
// Low surrogate.
else if (0xdc00 <= surrogate && surrogate <= 0xdfff) {
l16 = surrogate;
// Convert surrogate pair to UTF-32 encoding.
utf32 = ((h16 - 0xd800) << 10) + (l16 - 0xdc00) + 0x10000;
}
// Normal UTF-16.
else {
utf32 = surrogate;
}
// Compare the UTF-32 value against your list of code points, and handle.
// Just demonstrating with the code point for 😁.
if (utf32 == 0x1f601) {
NSLog(@"It's an emoji!");
}
}
Additionally, you'll need to handle Variation Selectors if you don't want false positives, and zero-width joiners if you need to be able to handle sequences, but just looking at the first character in a sequence will tell you whether the string contains an emoji, so I won't go further into this.
Upvotes: 1
Reputation: 1542
This is how I do it in my app :
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if textView.textInputMode?.primaryLanguage == "emoji" || textView.textInputMode?.primaryLanguage == nil {
// An emoji was typed by the user
// Do anything you need to do (or return false to disallow emojis)
}
return true
}
Upvotes: 1