Create a gist now

Instantly share code, notes, and snippets.

Detect ISO 681 Language Code from String and Convert to BCP 47 Language Code
static NSString * BCP47LanguageCodeFromISO681LanguageCode(NSString *ISO681LanguageCode) {
if ([ISO681LanguageCode isEqualToString:@"ar"]) {
return @"ar-SA";
} else if ([ISO681LanguageCode hasPrefix:@"cs"]) {
return @"cs-CZ";
} else if ([ISO681LanguageCode hasPrefix:@"da"]) {
return @"da-DK";
} else if ([ISO681LanguageCode hasPrefix:@"de"]) {
return @"de-DE";
} else if ([ISO681LanguageCode hasPrefix:@"el"]) {
return @"el-GR";
} else if ([ISO681LanguageCode hasPrefix:@"en"]) {
return @"en-US"; // en-AU, en-GB, en-IE, en-ZA
} else if ([ISO681LanguageCode hasPrefix:@"es"]) {
return @"es-ES"; // es-MX
} else if ([ISO681LanguageCode hasPrefix:@"fi"]) {
return @"fi-FI";
} else if ([ISO681LanguageCode hasPrefix:@"fr"]) {
return @"fr-FR"; // fr-CA
} else if ([ISO681LanguageCode hasPrefix:@"hi"]) {
return @"hi-IN";
} else if ([ISO681LanguageCode hasPrefix:@"hu"]) {
return @"hu-HU";
} else if ([ISO681LanguageCode hasPrefix:@"id"]) {
return @"id-ID";
} else if ([ISO681LanguageCode hasPrefix:@"it"]) {
return @"it-IT";
} else if ([ISO681LanguageCode hasPrefix:@"ja"]) {
return @"ja-JP";
} else if ([ISO681LanguageCode hasPrefix:@"ko"]) {
return @"ko-KR";
} else if ([ISO681LanguageCode hasPrefix:@"nl"]) {
return @"nl-NL"; // nl-BE
} else if ([ISO681LanguageCode hasPrefix:@"no"]) {
return @"no-NO";
} else if ([ISO681LanguageCode hasPrefix:@"pl"]) {
return @"pl-PL";
} else if ([ISO681LanguageCode hasPrefix:@"pt"]) {
return @"pt-BR"; // pt-PT
} else if ([ISO681LanguageCode hasPrefix:@"ro"]) {
return @"ro-RO";
} else if ([ISO681LanguageCode hasPrefix:@"ru"]) {
return @"ru-RU";
} else if ([ISO681LanguageCode hasPrefix:@"sk"]) {
return @"sk-SK";
} else if ([ISO681LanguageCode hasPrefix:@"sv"]) {
return @"sv-SE";
} else if ([ISO681LanguageCode hasPrefix:@"th"]) {
return @"th-TH";
} else if ([ISO681LanguageCode hasPrefix:@"tr"]) {
return @"tr-TR";
} else if ([ISO681LanguageCode hasPrefix:@"zh"]) {
return @"zh-CN"; // zh-HK, zh-TW
} else {
return nil;
static NSString * BCP47LanguageCodeForString(NSString *string) {
NSString *ISO681LanguageCode = (__bridge NSString *)CFStringTokenizerCopyBestStringLanguage((__bridge CFStringRef)string, CFRangeMake(0, [string length]));
return BCP47LanguageCodeFromISO681LanguageCode(ISO681LanguageCode);

First, thanks for this piece of code. That's great.
It seems that in iOS9.1 can cause the issue

2015-11-12 00:04:32.701 Speech Synthesizer[72300:1113005] BCP-47 Language Code: ja-JP Speech rate:[0.000000, 1.000000]
2015-11-12 00:04:32.707 Speech Synthesizer[72300:1113005] |AXSpeechAssetDownloader|error| ASAssetQuery error fetching results (for Error Domain=ASError Code=21 "Unable to copy asset information" UserInfo={NSDescription=Unable to copy asset information}

when getting the voice from a language that is not the device language. See here:

This seems to be addressed in the Apple's Forums as well:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment