Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift turn a country code into a emoji flag via unicode

Tags:

swift

unicode

People also ask

What is this country šŸ“?

šŸ“󠁧󠁢󠁄󠁮󠁧ó æ Flag: England.

How many country flag Emojis are there?

After all, Apple's iPhone only included 10 country flag emojis in 2008, and now there are 268.

What flag is not in the emoji?

This Taiwanese flag is hidden from the emoji keyboard on iOS devices when the region is set to China mainland or (as of iOS 13.1.


Here's a general formula for turning a two-letter country code into its emoji flag:

func flag(country:String) -> String {
    let base = 127397
    var usv = String.UnicodeScalarView()
    for i in country.utf16 {
        usv.append(UnicodeScalar(base + Int(i)))
    }
    return String(usv)
}

let s = flag("DE")

EDIT Ooops, no need to pass through the nested String.UnicodeScalarView struct. It turns out that String has an append method for precisely this purpose. So:

func flag(country:String) -> String { 
    let base : UInt32 = 127397
    var s = ""
    for v in country.unicodeScalars {
        s.append(UnicodeScalar(base + v.value))
    }
    return s
}

EDIT Oooops again, in Swift 3 they took away the ability to append a UnicodeScalar to a String, and they made the UnicodeScalar initializer failable (Xcode 8 seed 6), so now it looks like this:

func flag(country:String) -> String {
    let base : UInt32 = 127397
    var s = ""
    for v in country.unicodeScalars {
        s.unicodeScalars.append(UnicodeScalar(base + v.value)!)
    }
    return String(s)
}

If anyone looking for solution in ObjectiveC here is convenient category:

@interface NSLocale (RREmoji)

+ (NSString *)emojiFlagForISOCountryCode:(NSString *)countryCode;

@end


@implementation NSLocale (RREmoji)


+ (NSString *)emojiFlagForISOCountryCode:(NSString *)countryCode {
    NSAssert(countryCode.length == 2, @"Expecting ISO country code");

    int base = 127462 -65;

    wchar_t bytes[2] = {
        base +[countryCode characterAtIndex:0],
        base +[countryCode characterAtIndex:1]
    };

    return [[NSString alloc] initWithBytes:bytes
                                    length:countryCode.length *sizeof(wchar_t)
                                  encoding:NSUTF32LittleEndianStringEncoding];
}


@end

test:

for ( NSString *countryCode in [NSLocale ISOCountryCodes] ) {
    NSLog(@"%@ - %@", [NSLocale emojiFlagForISOCountryCode:countryCode], countryCode);
}

output: šŸ‡¦šŸ‡© - AD šŸ‡¦šŸ‡Ŗ - AE šŸ‡¦šŸ‡« - AF šŸ‡¦šŸ‡¬ - AG šŸ‡¦šŸ‡® - AI ...


Two optimizations of matt's answer.

  • No need to pass through the nested String in Swift 4
  • To avoid pass lower case string, I added uppercased()

Here is the code.

func flag(from country:String) -> String {
    let base : UInt32 = 127397
    var s = ""
    for v in country.uppercased().unicodeScalars {
        s.unicodeScalars.append(UnicodeScalar(base + v.value)!)
    }
    return s
}

I know this is not exactly what was asked, but maybe it will help someone:

let flags: [String: String] = [
  "AD": "šŸ‡¦šŸ‡©", "AE": "šŸ‡¦šŸ‡Ŗ", "AF": "šŸ‡¦šŸ‡«", "AG": "šŸ‡¦šŸ‡¬", "AI": "šŸ‡¦šŸ‡®", "AL": "šŸ‡¦šŸ‡±", "AM": "šŸ‡¦šŸ‡²", "AO": "šŸ‡¦šŸ‡“", "AQ": "šŸ‡¦šŸ‡¶", "AR": "šŸ‡¦šŸ‡·", "AS": "šŸ‡¦šŸ‡ø", "AT": "šŸ‡¦šŸ‡¹", "AU": "šŸ‡¦šŸ‡ŗ", "AW": "šŸ‡¦šŸ‡¼", "AX": "šŸ‡¦šŸ‡½", "AZ": "šŸ‡¦šŸ‡æ", "BA": "šŸ‡§šŸ‡¦", "BB": "šŸ‡§šŸ‡§", "BD": "šŸ‡§šŸ‡©", "BE": "šŸ‡§šŸ‡Ŗ", "BF": "šŸ‡§šŸ‡«", "BG": "šŸ‡§šŸ‡¬", "BH": "šŸ‡§šŸ‡­", "BI": "šŸ‡§šŸ‡®", "BJ": "šŸ‡§šŸ‡Æ", "BL": "šŸ‡§šŸ‡±", "BM": "šŸ‡§šŸ‡²", "BN": "šŸ‡§šŸ‡³", "BO": "šŸ‡§šŸ‡“", "BQ": "šŸ‡§šŸ‡¶", "BR": "šŸ‡§šŸ‡·", "BS": "šŸ‡§šŸ‡ø", "BT": "šŸ‡§šŸ‡¹", "BV": "šŸ‡§šŸ‡»", "BW": "šŸ‡§šŸ‡¼", "BY": "šŸ‡§šŸ‡¾", "BZ": "šŸ‡§šŸ‡æ", "CA": "šŸ‡ØšŸ‡¦", "CC": "šŸ‡ØšŸ‡Ø", "CD": "šŸ‡ØšŸ‡©", "CF": "šŸ‡ØšŸ‡«", "CG": "šŸ‡ØšŸ‡¬", "CH": "šŸ‡ØšŸ‡­", "CI": "šŸ‡ØšŸ‡®", "CK": "šŸ‡ØšŸ‡°", "CL": "šŸ‡ØšŸ‡±", "CM": "šŸ‡ØšŸ‡²", "CN": "šŸ‡ØšŸ‡³", "CO": "šŸ‡ØšŸ‡“", "CR": "šŸ‡ØšŸ‡·", "CU": "šŸ‡ØšŸ‡ŗ", "CV": "šŸ‡ØšŸ‡»", "CW": "šŸ‡ØšŸ‡¼", "CX": "šŸ‡ØšŸ‡½", "CY": "šŸ‡ØšŸ‡¾", "CZ": "šŸ‡ØšŸ‡æ", "DE": "šŸ‡©šŸ‡Ŗ", "DJ": "šŸ‡©šŸ‡Æ", "DK": "šŸ‡©šŸ‡°", "DM": "šŸ‡©šŸ‡²", "DO": "šŸ‡©šŸ‡“", "DZ": "šŸ‡©šŸ‡æ", "EC": "šŸ‡ŖšŸ‡Ø", "EE": "šŸ‡ŖšŸ‡Ŗ", "EG": "šŸ‡ŖšŸ‡¬", "EH": "šŸ‡ŖšŸ‡­", "ER": "šŸ‡ŖšŸ‡·", "ES": "šŸ‡ŖšŸ‡ø", "ET": "šŸ‡ŖšŸ‡¹", "FI": "šŸ‡«šŸ‡®", "FJ": "šŸ‡«šŸ‡Æ", "FK": "šŸ‡«šŸ‡°", "FM": "šŸ‡«šŸ‡²", "FO": "šŸ‡«šŸ‡“", "FR": "šŸ‡«šŸ‡·", "GA": "šŸ‡¬šŸ‡¦", "GB": "šŸ‡¬šŸ‡§", "GD": "šŸ‡¬šŸ‡©", "GE": "šŸ‡¬šŸ‡Ŗ", "GF": "šŸ‡¬šŸ‡«", "GG": "šŸ‡¬šŸ‡¬", "GH": "šŸ‡¬šŸ‡­", "GI": "šŸ‡¬šŸ‡®", "GL": "šŸ‡¬šŸ‡±", "GM": "šŸ‡¬šŸ‡²", "GN": "šŸ‡¬šŸ‡³", "GP": "šŸ‡¬šŸ‡µ", "GQ": "šŸ‡¬šŸ‡¶", "GR": "šŸ‡¬šŸ‡·", "GS": "šŸ‡¬šŸ‡ø", "GT": "šŸ‡¬šŸ‡¹", "GU": "šŸ‡¬šŸ‡ŗ", "GW": "šŸ‡¬šŸ‡¼", "GY": "šŸ‡¬šŸ‡¾", "HK": "šŸ‡­šŸ‡°", "HM": "šŸ‡­šŸ‡²", "HN": "šŸ‡­šŸ‡³", "HR": "šŸ‡­šŸ‡·", "HT": "šŸ‡­šŸ‡¹", "HU": "šŸ‡­šŸ‡ŗ", "ID": "šŸ‡®šŸ‡©", "IE": "šŸ‡®šŸ‡Ŗ", "IL": "šŸ‡®šŸ‡±", "IM": "šŸ‡®šŸ‡²", "IN": "šŸ‡®šŸ‡³", "IO": "šŸ‡®šŸ‡“", "IQ": "šŸ‡®šŸ‡¶", "IR": "šŸ‡®šŸ‡·", "IS": "šŸ‡®šŸ‡ø", "IT": "šŸ‡®šŸ‡¹", "JE": "šŸ‡ÆšŸ‡Ŗ", "JM": "šŸ‡ÆšŸ‡²", "JO": "šŸ‡ÆšŸ‡“", "JP": "šŸ‡ÆšŸ‡µ", "KE": "šŸ‡°šŸ‡Ŗ", "KG": "šŸ‡°šŸ‡¬", "KH": "šŸ‡°šŸ‡­", "KI": "šŸ‡°šŸ‡®", "KM": "šŸ‡°šŸ‡²", "KN": "šŸ‡°šŸ‡³", "KP": "šŸ‡°šŸ‡µ", "KR": "šŸ‡°šŸ‡·", "KW": "šŸ‡°šŸ‡¼", "KY": "šŸ‡°šŸ‡¾", "KZ": "šŸ‡°šŸ‡æ", "LA": "šŸ‡±šŸ‡¦", "LB": "šŸ‡±šŸ‡§", "LC": "šŸ‡±šŸ‡Ø", "LI": "šŸ‡±šŸ‡®", "LK": "šŸ‡±šŸ‡°", "LR": "šŸ‡±šŸ‡·", "LS": "šŸ‡±šŸ‡ø", "LT": "šŸ‡±šŸ‡¹", "LU": "šŸ‡±šŸ‡ŗ", "LV": "šŸ‡±šŸ‡»", "LY": "šŸ‡±šŸ‡¾", "MA": "šŸ‡²šŸ‡¦", "MC": "šŸ‡²šŸ‡Ø", "MD": "šŸ‡²šŸ‡©", "ME": "šŸ‡²šŸ‡Ŗ", "MF": "šŸ‡²šŸ‡«", "MG": "šŸ‡²šŸ‡¬", "MH": "šŸ‡²šŸ‡­", "MK": "šŸ‡²šŸ‡°", "ML": "šŸ‡²šŸ‡±", "MM": "šŸ‡²šŸ‡²", "MN": "šŸ‡²šŸ‡³", "MO": "šŸ‡²šŸ‡“", "MP": "šŸ‡²šŸ‡µ", "MQ": "šŸ‡²šŸ‡¶", "MR": "šŸ‡²šŸ‡·", "MS": "šŸ‡²šŸ‡ø", "MT": "šŸ‡²šŸ‡¹", "MU": "šŸ‡²šŸ‡ŗ", "MV": "šŸ‡²šŸ‡»", "MW": "šŸ‡²šŸ‡¼", "MX": "šŸ‡²šŸ‡½", "MY": "šŸ‡²šŸ‡¾", "MZ": "šŸ‡²šŸ‡æ", "NA": "šŸ‡³šŸ‡¦", "NC": "šŸ‡³šŸ‡Ø", "NE": "šŸ‡³šŸ‡Ŗ", "NF": "šŸ‡³šŸ‡«", "NG": "šŸ‡³šŸ‡¬", "NI": "šŸ‡³šŸ‡®", "NL": "šŸ‡³šŸ‡±", "NO": "šŸ‡³šŸ‡“", "NP": "šŸ‡³šŸ‡µ", "NR": "šŸ‡³šŸ‡·", "NU": "šŸ‡³šŸ‡ŗ", "NZ": "šŸ‡³šŸ‡æ", "OM": "šŸ‡“šŸ‡²", "PA": "šŸ‡µšŸ‡¦", "PE": "šŸ‡µšŸ‡Ŗ", "PF": "šŸ‡µšŸ‡«", "PG": "šŸ‡µšŸ‡¬", "PH": "šŸ‡µšŸ‡­", "PK": "šŸ‡µšŸ‡°", "PL": "šŸ‡µšŸ‡±", "PM": "šŸ‡µšŸ‡²", "PN": "šŸ‡µšŸ‡³", "PR": "šŸ‡µšŸ‡·", "PS": "šŸ‡µšŸ‡ø", "PT": "šŸ‡µšŸ‡¹", "PW": "šŸ‡µšŸ‡¼", "PY": "šŸ‡µšŸ‡¾", "QA": "šŸ‡¶šŸ‡¦", "RE": "šŸ‡·šŸ‡Ŗ", "RO": "šŸ‡·šŸ‡“", "RS": "šŸ‡·šŸ‡ø", "RU": "šŸ‡·šŸ‡ŗ", "RW": "šŸ‡·šŸ‡¼", "SA": "šŸ‡øšŸ‡¦", "SB": "šŸ‡øšŸ‡§", "SC": "šŸ‡øšŸ‡Ø", "SD": "šŸ‡øšŸ‡©", "SE": "šŸ‡øšŸ‡Ŗ", "SG": "šŸ‡øšŸ‡¬", "SH": "šŸ‡øšŸ‡­", "SI": "šŸ‡øšŸ‡®", "SJ": "šŸ‡øšŸ‡Æ", "SK": "šŸ‡øšŸ‡°", "SL": "šŸ‡øšŸ‡±", "SM": "šŸ‡øšŸ‡²", "SN": "šŸ‡øšŸ‡³", "SO": "šŸ‡øšŸ‡“", "SR": "šŸ‡øšŸ‡·", "SS": "šŸ‡øšŸ‡ø", "ST": "šŸ‡øšŸ‡¹", "SV": "šŸ‡øšŸ‡»", "SX": "šŸ‡øšŸ‡½", "SY": "šŸ‡øšŸ‡¾", "SZ": "šŸ‡øšŸ‡æ", "TC": "šŸ‡¹šŸ‡Ø", "TD": "šŸ‡¹šŸ‡©", "TF": "šŸ‡¹šŸ‡«", "TG": "šŸ‡¹šŸ‡¬", "TH": "šŸ‡¹šŸ‡­", "TJ": "šŸ‡¹šŸ‡Æ", "TK": "šŸ‡¹šŸ‡°", "TL": "šŸ‡¹šŸ‡±", "TM": "šŸ‡¹šŸ‡²", "TN": "šŸ‡¹šŸ‡³", "TO": "šŸ‡¹šŸ‡“", "TR": "šŸ‡¹šŸ‡·", "TT": "šŸ‡¹šŸ‡¹", "TV": "šŸ‡¹šŸ‡»", "TW": "šŸ‡¹šŸ‡¼", "TZ": "šŸ‡¹šŸ‡æ", "UA": "šŸ‡ŗšŸ‡¦", "UG": "šŸ‡ŗšŸ‡¬", "UM": "šŸ‡ŗšŸ‡²", "US": "šŸ‡ŗšŸ‡ø", "UY": "šŸ‡ŗšŸ‡¾", "UZ": "šŸ‡ŗšŸ‡æ", "VA": "šŸ‡»šŸ‡¦", "VC": "šŸ‡»šŸ‡Ø", "VE": "šŸ‡»šŸ‡Ŗ", "VG": "šŸ‡»šŸ‡¬", "VI": "šŸ‡»šŸ‡®", "VN": "šŸ‡»šŸ‡³", "VU": "šŸ‡»šŸ‡ŗ", "WF": "šŸ‡¼šŸ‡«", "WS": "šŸ‡¼šŸ‡ø", "YE": "šŸ‡¾šŸ‡Ŗ", "YT": "šŸ‡¾šŸ‡¹", "ZA": "šŸ‡æšŸ‡¦", "ZM": "šŸ‡æšŸ‡²", "ZW": "šŸ‡æšŸ‡¼"
]

Another function for turning a two-letter country code into its emoji flag using Swift 5.

internal func getFlag(from countryCode: String) -> String {
    countryCode
        .unicodeScalars
        .map({ 127397 + $0.value })
        .compactMap(UnicodeScalar.init)
        .map(String.init)
        .joined()
}

To give more insight into matt answer

Swift 2 version

public static func flag(countryCode: String) -> Character {
    let base = UnicodeScalar("šŸ‡¦").value - UnicodeScalar("A").value

    let string = countryCode.uppercaseString.unicodeScalars.reduce("") {
      var string = $0
      string.append(UnicodeScalar(base + $1.value))
      return string
    }

    return Character(string)
  }

Swift 3 version, taken from https://github.com/onmyway133/Smile/blob/master/Sources/Smile.swift#L52

public func emoji(countryCode: String) -> Character {
  let base = UnicodeScalar("šŸ‡¦").value - UnicodeScalar("A").value

  var string = ""
  countryCode.uppercased().unicodeScalars.forEach {
    if let scala = UnicodeScalar(base + $0.value) {
      string.append(String(describing: scala))
    }
  }

  return Character(string)
}