How could I get Apple emoji name instead of Unicode name?
Asked Answered
S

2

6

I see that the Unicode name of an emoji and its Apple name as displayed in Character Viewer are different. How could I get an emoji's Apple name using Swift?

Example:

Emoji: 😄

Unicode Name (got via .applyingTransform(.toUnicodeName, reverse: false)):

smiling face with open mouth and smiling eyes

Apple Name (got from macOS Character Viewer):

grinning face with squinting eyes

Symon answered 21/4, 2020 at 16:23 Comment(0)
S
8

The first one is the Unicode name, though the correct name is:

SMILING FACE WITH OPEN MOUTH AND SMILING EYES

The fact that it's uppercase matters. It's a Unicode identifier. It's permanent and it's unique. (It's really permanent, even if they misspell a word like "BRAKCET" in "PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET", that name is forever).

The second name is the "Apple Name." These are localized names. On Mac, the English version is stored in:

/System/Library/PrivateFrameworks/CoreEmoji.framework/Versions/A/Resources/en.lproj/AppleName.strings

You can dump this file with plutil, or read it using PropertyListDecoder.

$ plutil -p AppleName.strings
{
  "〰" => "wavy dash"
  "‼️" => "red double exclamation mark"
  "⁉️" => "red exclamation mark and question mark"
  "*️⃣" => "keycap asterisk"
  "#️⃣" => "number sign"
  "〽️" => "part alternation mark"
  "©" => "copyright sign"
  ...

That said, unless you absolutely need to match Apple, I'd recommend the CLDR (Common Locale Data Repository) annotation short name. That's the Unicode source for localized names. They're not promised to be unique, though. Their biggest purpose is for supporting text-to-speech.

For the current list in XML, it's most convenient on GitHub. Or you can browse the v37 table or download the raw data.

Salver answered 24/9, 2020 at 0:49 Comment(0)
P
2

Looking at the Character Viewer app with Hoppper, it seems that there is no API for this, but you could get it using a XCP service.

Pseudocode for +[CPKDefaultDataSource localizedCharacterName:]

/* @class CPKDefaultDataSource */
+(void *)localizedCharacterName:(void *)arg2 {
    r14 = arg2;
    rax = [CPKDefaultDataSource preferredEmojiLocale];
    if (rax != 0x0) {
            rax = CEMEmojiTokenCreateWithString(r14, rax);
            if (rax != 0x0) {
                    r15 = CEMEmojiTokenCopyName(rax, 0x2);
                    CFRelease(rax);
                    if (r15 != 0x0) {
                            rax = [r15 autorelease];
                    }
                    else {
                            rax = [[CPSearchManager sharedSearchManager] infoForCharcater:r14 infoTag:@"unam"];
                    }
            }
            else {
                    rax = [[CPSearchManager sharedSearchManager] infoForCharcater:r14 infoTag:@"unam"];
            }
    }
    else {
            rax = 0x0;
    }
    return rax;
}

Presudocode of -[CPSearchManager infoForCharcater:infoTag:]

/* @class CPSearchManager */
-(void *)infoForCharcater:(void *)arg2 infoTag:(void *)arg3 {
...
    rax = [CPCharacterDatabase sharedDatabase];
    rax = [rax createXPCDictionaryForCharacterInfo:r14];
...
    rax = [r12 cStringUsingEncoding:0x4];
    rax = xpc_dictionary_get_value(r15, rax);
...
    rax = xpc_dictionary_create(0x0, 0x0, 0x0);
    r12 = rax;
    xpc_dictionary_set_string(rax, "command", "search_character_info");
    xpc_dictionary_set_string(r12, "string", [r14 cStringUsingEncoding:0x4]);
    rdx = *(r15 + 0x10);
    *(r15 + 0x10) = rdx + 0x1;
    xpc_dictionary_set_uint64(r12, "transactionID", rdx + 0x1);
    rax = _CPXPCConnection();
    rax = xpc_connection_send_message_with_reply_sync(rax, r12);
    rax = xpc_dictionary_get_value(rax, "result");
...
}

I found all this inside this framework: /System/Library/PrivateFrameworks/CharacterPicker.framework, if you are building this for macOS, you can link against this library for private distribution

Ptah answered 24/9, 2020 at 0:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.