Swift 5 – How to use base emoji in case statement that may have skin-tone emoji as input?

Viewed 87

The input to my switch may or may not be an emoji with skin tone.

Do I have to test for all six variations for each emoji that can have a skin tone or is there a simple one-liner way to strip out the base emoji from the emoji modifier?

Here is my failing code:

switch blah {
    case "✅":
        daIcon = self.iconComplete!
    case "":
        daIcon = self.iconConfirmed!
    case "":
        daIcon = self.iconMessageLeft!
    case "":
        daIcon = self.iconLookingForDocs!
    case "☎️":
        daIcon = self.iconVoiceMailLeft!
    case "❌":
        daIcon = self.iconPostponed!
    default:
         daIcon = self.iconRedQuestion!
}

Edit:

I am new to all of this from a programming perspective. I knew that emoji took more than "a" byte and that zero-width whatchamacallits existed, but it was not unit the above switch statement failed that I needed to learn more. LOL

In this particular use case, I am just using a series of emojis to indicate various status states. Therefore, I do not anticipate needing any of the more complicated combinations (e.g. ‍‍).

The full list is: ✅, ⭕, , , , ☎️, ❓, ‼️, ⁉️, , , , ⭕️, ❌, ⚠️, , , , , and of course, .

1 Answers

One way you can do this is to first check if the string is a single Character, then get the first unicode scalar. That will be the unmodified base emoji.

You can write your own ~= operator for String, s

// or if...else if you are doing other stuff after the switch
guard blah.count == 1 else {
    daIcon = self.iconRedQuestion!
    return
}
switch blah.unicodeScalars.first {
case "✅":
    daIcon = self.iconComplete!
case "":
    daIcon = self.iconConfirmed!
case "":
    daIcon = self.iconMessageLeft!
case "":
    daIcon = self.iconLookingForDocs!
case "☎":
    daIcon = self.iconVoiceMailLeft!
case "❌":
    daIcon = self.iconPostponed!
default:
    daIcon = self.iconRedQuestion!
}

Note that the ☎️ emoji is actually ☎ (U+260E BLACK TELEPHONE) plus a variation selector. You should use only U+260E in the cases.

You can also use Smile, specifically the unmodify(emoji:) and isSingleEmoji functions, which are implemented similarly as above.

Note that this approach picks out the first emoji in a ZWJ sequence, which may or may not be expected.

Related