Is there a way to know if an Emoji is supported in iOS?
Asked Answered
B

2

25

I'm building an iOS App, and Emojis play a big part in it.

In iOS 10.2, new emojis were released.

I'm pretty sure that if someone has iOS 8, for example, they wouldn't actually be able to see these emojis. Is there a way to detect this? I'm trying to dynamically build a list of all the Emojis that are supported on the user's iOS version, but I'm having a bit of trouble.

Bombazine answered 25/12, 2016 at 5:54 Comment(8)
Are you trying to determine if an emjoi is available for the user in your app or the person you're sending a message to? I wonder if there's a string representation for emojisJurat
Well, it is sort of two-fold. One the one hand, I want to generate a list of all emojis a user can use on their own iOS version, but if they send it to someone, that person might not be able to see the emoji. In which case, I want a fallback.Bombazine
Why you don't use @available(iOS 10.2, *) before generating available emojis to the user ?Losse
@wajeeh I could do something like that for generating emojis for iOS 10.2, but that doesn't tell me anything about if an Emoji is supported in iOS 9, for example. In fact, that would be great if I got a list of Emojis for iOS 9, 9.1, etc. - iOS 10.2. I'm looking for lists like that currently.Bombazine
Ah ok, check this link en.stack.aiseen.org/questions/35687407/… , Also after I made some tests I found that unsupported emoji will always fall back to a specific character (black question mark), So maybe you can benefit from this. this answer use same method: https://mcmap.net/q/539484/-how-can-i-determine-if-a-specific-emoji-character-can-be-rendered-by-an-ios-deviceLosse
Here's a link with added emojis on iOS 10.2: emojipedia.org/apple/ios-10.2/new You can scroll to the bottom and pick another iOS version changelog. Not sure how correct that website is. This is not what you asked for, but it might help.Coleville
@SomeHelpingDude that looks really cool. If I could consolidate some of the versions into like an array of unicodes in the order Apple shows them in the Emoji Keyboard, this could work out. I'd need to work out the kinks of different skin tone emojis, but that shouldn't be too difficult.Bombazine
The update is an entirely different question. Please post a new request.Upraise
U
28

Clarification: an Emoji is merely a character in the Unicode Character space, so the present solution works for all characters, not just Emoji.

Synopsis

To know if a Unicode character (including an Emoji) is available on a given device or OS, run the unicodeAvailable() method below.

It works by comparing a given character image against a known undefined Unicode character U+1FFF.

unicodeAvailable(), a Character extension

private static let refUnicodeSize: CGFloat = 8
private static let refUnicodePng =
    Character("\u{1fff}").png(ofSize: Character.refUnicodeSize)

func unicodeAvailable() -> Bool {
    if let refUnicodePng = Character.refUnicodePng,
        let myPng = self.png(ofSize: Character.refUnicodeSize) {
        return refUnicodePng != myPng
    }
    return false
}

Discussion

  1. All characters will be rendered as a png at the same size (8) as defined once in

    static let refUnicodeSize: CGFloat = 8

  2. The undefined character U+1FFF image is calculated once in

    static let refUnicodePng = Character("\u{1fff}").png(ofSize: Character.refUnicodeSize)

  3. A helper method optionally creates a png from a Character

    func png(ofSize fontSize: CGFloat) -> Data?

1. Example: Test against 3 emoji

let codes:[Character] = ["\u{2764}","\u{1f600}","\u{1F544}"] // ❤️, 😀, undefined
for unicode in codes {
    print("\(unicode) : \(unicode.unicodeAvailable())")
}

3 characters

2. Example: Test a range of Unicode characters

func unicodeRange(from: Int, to: Int) {
    for unicodeNumeric in from...to {
        if let scalar = UnicodeScalar(unicodeNumeric) {
            let unicode = Character(scalar)
            let avail = unicode.unicodeAvailable()
            let hex = String(format: "0x%x", unicodeNumeric)
            print("\(unicode) \(hex) is \(avail ? "" : "not ")available")
        }
    }
}

a few hundred characters


Helper function: Character to png

func png(ofSize fontSize: CGFloat) -> Data? {
    let attributes = [NSAttributedStringKey.font:
                          UIFont.systemFont(ofSize: fontSize)]
    let charStr = "\(self)" as NSString
    let size = charStr.size(withAttributes: attributes)

    UIGraphicsBeginImageContext(size)
    charStr.draw(at: CGPoint(x: 0,y :0), withAttributes: attributes)

    var png:Data? = nil
    if let charImage = UIGraphicsGetImageFromCurrentImageContext() {
        png = UIImagePNGRepresentation(charImage)
    }

    UIGraphicsEndImageContext()
    return png
}

► Find this solution on GitHub and a detailed article on Swift Recipes.

Upraise answered 30/12, 2016 at 8:58 Comment(6)
It is merely one of the many characters not yet implemented (or defined). It thus prints a [?] question mark, as do all the invalid characters. All invalid unicode characters share the same bitmap.Upraise
FYI, this fails for 🤸‍♂️ (man doing cartwheel, U+1F938 U+200D U+2642 U+FE0F) because the PNG will render as [?]♂ rather than [?]. I worked around this by only rendering the first codepoint (obtained using enumerateSubstringsInRange:options:usingBlock:)Kaiserdom
@Ford, find generalized solution on GitHub. As per Unit Test, no need to render individual CodepointsUpraise
@SwiftArchitect, This approach doesnt work with Country flags. e.g. "NZ" encoded as a unicode countrycode is fine but "EU" (some software insists the European Union is a country) returns the letters E and U each surrounded by a box. I can filter the country codes that I know will cause problems but I still don't know if macOS has actually created a flag glyph for the remainder.Bibliopole
This approach works for EU. Build a unicode Character with codes U+1F1EA U+1F1EA as in \u{1F1EA}\u{1F1EA}, you will get 🇪🇺, and the Unit Test See GitHub project will pass.Upraise
This is a great solution @SwiftArchitect, thanks for sharing! I have tried to convert it to AppKit for a macOS application but wasn’t able to find a proper equivalent for UIGraphicsBeginImageContext. Would you mind sharing a macOS solution as well?Dyann
U
0

Just for future reference, after discovering my app had 13.2 emojis not supported in 12.x versions, I used the answer from here: How can I determine if a specific emoji character can be rendered by an iOS device? which worked really well for me.

Undertrump answered 6/6, 2020 at 14:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.