Search code examples
macoscocoafoundationcore-foundationmacos-high-sierra

Regarding CFLocaleCopyCurrent API incorrect return value


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

Solution

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