At my workplace, we are in a situation where following standalone code below,
#include <CoreFoundation/CoreFoundation.h>
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <boost/cast.hpp>
// Reference release
struct reference_close
{
void operator()(const void *ref) const
{
CFRelease(static_cast<CFTypeRef>(ref));
}
}; // end of reference_close structure
typedef std::unique_ptr<const void, reference_close> reference_uptr;
std::string get_user_locale()
{
reference_uptr ref_ptr(CFLocaleCopyCurrent());
CFLocaleRef locale_ref(static_cast<CFLocaleRef>(ref_ptr.get()));
if (locale_ref == nullptr)
{
return std::string();
}
const size_t default_size(128);
std::vector<char> buff(default_size);
CFStringRef str_ref(CFLocaleGetIdentifier(locale_ref));
// CFStringRef str_ref((CFStringRef)CFLocaleGetValue(locale_ref,kCFLocaleLanguageCode));
if (str_ref != nullptr)
{
CFIndex len(CFStringGetLength(str_ref) + 1);
if (len > boost::numeric_cast<CFIndex>(default_size))
{
buff.resize(len);
}
buff[0] = 0;
if (!CFStringGetCString(str_ref, &buff[0], len, kCFStringEncodingISOLatin1))
{
return std::string();
}
}
return std::string(&buff[0]);
} // end of get_user_locale()
int main()
{
std::cout << "get_user_locale() : "<<get_user_locale() << std::endl;
return 0;
}
gives us a different output on OS X 10.12 and 10.13 beta.
This is what we do in a nutshell.
On 10.12 machine
1) Set the preference language as ru and region as RU
2) Restart the machine
3) Get the output of "defaults read -g AppleLocale" to make sure that output is { ru_RU }
4) Compile the code, run the exe. We get the output as { ru_RU }.
We then repeat the steps 1) to 3) on OS X 10.13 (beta) machine and then run the same exe (created on 10.12, you might ask why, its because of some our internal build system restrictions ) on 10.13 machine and the output we get is "en_RU" which is not correct.
Are we missing something here ? Or is this a known problem in OS X 10.13 (beta) ? If so, how do we fix this ?
UPDATE
We also wrote a following Objective-C code to use NSLocale interface and that too gave us same results i.e ru_RU on 10.12 and en_RU on 10.13 (beta)
#import <Foundation/Foundation.h>
int main()
{
@autoreleasepool
{
NSLog(@"localeIdentifier: %@", [[NSLocale currentLocale] localeIdentifier]);
}
}
The reason we were getting an incorrect value is because our app was not localized into the locale we expected e.g ru
.
We corrected this by adding an empty ru.lproj
directory into our app's Contents/Resources
directory and the API started giving us the correct answer.