Swift turn a country code into a emoji flag via unicode

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 ...


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)
}

Tags:

Unicode

Swift