'Number of emojis in a String?

With recently added iOS 9.1 emojis, and the availability of skin tones etc, how do you properly count the number of Emojis in a String, assuming the string is uniquely made out of emojis?

Keep in mind that the length of emojis can vary.

NSString.length or string.characters.count

"😀" returns 2
"✊🏿" returns 4
"🇧🇸" or "🇧🇸" or "🇧🇸🇧🇸🇧🇸🇧🇸🇧🇸🇧🇸" returns 1!
"👨‍👩‍👧‍👧" returns 4 (Should be normally displayed as 1 family emoji)
etc...



Solution 1:[1]

I make an extension of String to count number of emoji in a string:

extension String {
    func countEmojiCharacter() -> Int {

        func isEmoji(s:NSString) -> Bool {

            let high:Int = Int(s.characterAtIndex(0))
            if 0xD800 <= high && high <= 0xDBFF {
                let low:Int = Int(s.characterAtIndex(1))
                let codepoint: Int = ((high - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000
                return (0x1D000 <= codepoint && codepoint <= 0x1F9FF)
            }
            else {
                return (0x2100 <= high && high <= 0x27BF)
            }
        }

        let nsString = self as NSString
        var length = 0

        nsString.enumerateSubstringsInRange(NSMakeRange(0, nsString.length), options: NSStringEnumerationOptions.ByComposedCharacterSequences) { (subString, substringRange, enclosingRange, stop) -> Void in

            if isEmoji(subString!) {
                length++
            }
        }

        return length
    }
}

Test:

let y = "xxx?????zzz"

print(y.countEmojiCharacter())
// result is 3

Solution 2:[2]

try this code snippet

extension String {
    var composedCount : Int {
        var count = 0
        enumerateSubstringsInRange(startIndex..<endIndex, options: .ByComposedCharacterSequences) {_ in count++}
        return count
    }
}

: credit goes to ericasadun

Solution 3:[3]

You can use this code example or this pod.

To use it in Swift, import the category into the YourProject_Bridging_Header

#import "NSString+EMOEmoji.h"

Then you can check the range for every emoji in your String:

let example: NSString = "string???????with?emojis??" //string with emojis

let emojiCount: NSInteger = example.emo_emojiCount()  // count

print(emojiCount)

// Output: ["3"]

I created an small example project with the code above.

UPDATE

Running this code with >= iOS 8.3 will have an

// Output: ["3"]

Running this code with < iOS 8.3 will have an

// Output: ["7"]

This is because family emoji, skin tone and many others were introduced with iOS 8.3. So, a smaller iOS version are reading this emojis in a different way.

As a example, open this post in Safari, Firefox and Chrome to see the difference.

Solution 4:[4]

some situation(e.g. netty):

"???????".utf8.count

Solution 5:[5]

swift4 answer:

extension String {
    var composedCount : Int {
        var count = 0
        enumerateSubstrings(in: startIndex..<endIndex, options: .byComposedCharacterSequences) { (_, _, _, _) in
            count = count + 1
        }

        return count
    }
}

Solution 6:[6]

Emojis, much like the unicode standard, are deceptively complicated. Skin tones, genders, jobs, groups of people, zero-width joiner sequences, flags (2 character unicode) and other complications can make emoji parsing messy. A Christmas Tree, a Slice of Pizza, or a Pile of Poop can all be represented with a single Unicode code point. Not to mention that when new emojis are introduced, there is a delay between iOS support and emoji release. That and the fact that different versions of iOS support different versions of the unicode standard.

TL;DR. I have worked on these features and opened sourced a library I am the author for JKEmoji to help parse strings with emojis. It makes parsing as easy as:

print("I love these emojis ?????????????".emojiCount)

5

It does that by routinely refreshing a local database of all recognized emojis as of the latest unicode version (12.0 as of recently) and cross-referencing them with what is recognized as a valid emoji in the running OS version by looking at the bitmap representation of an unrecognized emoji character.

NOTE

A previous answer got deleted for advertising my library without clearly stating that I am the author. I am acknowledging this again.

Solution 7:[7]

Try this code (actual for Swift 5):

extension Character {
    var isSimpleEmoji: Bool {
        guard let firstScalar = unicodeScalars.first else { return false }
        return firstScalar.properties.isEmoji && firstScalar.value > 0x238C
    }

    var isEmoji: Bool {
        return isSimpleEmoji
    }
}

extension String {
    var emojis: [Character] { filter { $0.isEmoji } }
}

Use:

let emojisCount = yourString.emojis.count

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Meet Doshi
Solution 2
Solution 3
Solution 4 hstdt
Solution 5 Arjen M
Solution 6
Solution 7 VyacheslavBakinkskiy