Jeavy
Jeavy

Reputation: 13

How to detect emoji iOS

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

Answers (2)

xoudini
xoudini

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 unichars (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

Dean
Dean

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

Related Questions