Is there a method for backing up settings in CCUserDefault?


#1

Is there a method for backing up settings in CCUserDefault? I wanna do a second copy of my settings. :slight_smile: It’s more safer to store a copy of this setting in the second file :slight_smile: (for example I can do this copy before I write something in the first settings file).

What do you recommend me to do in this case?)


#2

Maybe someone knows a filename of the file in which Cocos2d-x stores user settings?


#3

From UserDefault.cpp

#define XML_FILE_NAME "UserDefault.xml"
// ..
if (! m_sbIsFilePathInitialized)
{
    m_sFilePath += CCFileUtils::sharedFileUtils()->getWritablePath() + XML_FILE_NAME;
    m_sbIsFilePathInitialized = true;
}

So it’s just the default writeable path from File Utils concatenated with “UserDefault.xml”


#4

Sami Peltomaa wrote:

From UserDefault.cpp
>
[…]
>
So it’s just the default writeable path from File Utils concatenated with “UserDefault.xml”

Hm… But I can’t find this file :frowning:
My attempt to read it:

std::string filename = cocos2d::CCFileUtils::sharedFileUtils()->getWritablePath() + "UserDefault.xml";

std::ifstream in;
in.open( filename.c_str() );
if ( !in.is_open() ) {
    cocos2d::CCLog( "ERROR. I can't find this file!" );
}

I get “ERROR. I can’t find this file!”. But:

std::string userName = cocos2d::CCUserDefault::sharedUserDefault()->getStringForKey( "user_name" );

works fine so the user settings store somewhere but where? :slight_smile: Why I can’t open it?

Where’s “UserDefault.cpp” file? I can’t find it…


#5

I’ve found you can find many files by searching for the classname in the cocos2dx reference, and scrolling to the bottom: http://www.cocos2d-x.org/reference/native-cpp/d0/d79/classcocos2d_1_1_c_c_user_default.html

The documentation for this class was generated from the following file:
/Users/minggo/SourceCode/cocos2dx-root/cocos2dx/support/user_default/CCUserDefault.h

So you can find it in cocos2dx/support/user_default folder.

I don’t know why you seem to be unable to find the file, your code works perfectly well for me :frowning: . If it helps, in windows, running in debug mode seems to create UserDefault.xml to the executable path, and in release mode it is created to C:username>project name>.xml


#6

Sami Peltomaa
Oh thanks! Now I’ve found CCUserDefault.cpp :slight_smile:
In the head of this file we see the line:

#if (CC_TARGET_PLATFORM != CC_PLATFORM_IOS && CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID)

but what does it mean?! It means that ALL following code (in this file) is not for iOS and Android? I test my code exactly on these systems :slight_smile: But where is CCUserDefault for these mobile platforms?

I see other strange thing:

if ( cocos2d::CCUserDefault::sharedUserDefault()->isXMLFileExist() ) {
    cocos2d::CCLog( "XMLExists!" );
} else {
    cocos2d::CCLog( "XML NOT Exists!" );    
}

it outputs to me: "XML NOT Exists And there’re not empty values! But where’s it stores settings on mobile devices? :slight_smile:
I use Android and iOS only (emulators and devices).


#7

Oh, sorry for not noticing that line that excludes ios and android platforms :frowning:

Anyway, I went looking for where might the iOS and android implementations hide, and after a while I came back and noticed they’re in the same directory ^^ There is CCUserDefault.mm and CCUserDefaultAndroid.cpp inside cocos2dx/support/user_default too.

From a quick glance at the iOS file, it looks like it’s making use of NSUserDefault to store the defaults. I have no idea how that works so you’ll have to take it from there. I also found this: http://www.cocos2d-x.org/news/103 And I think this is probably the reason why there still IS a function to check for XML file, CCUserDefault used to store stuff to XML on all platforms, then they changed it to use other (more efficient) form of storage on iOS/android but there is still support for XML for backwards compatibility.


#8

I don’t know what the problem but under Android (and iOS) I get false from isXMLFileExists() (meanwhile user settings values load fine and there’re not empty values) and this code also doesn’t work:

std::string getFileContent( std::string filename ) {

    std::string result = "";
    std::string lineStr = "";

    std::ifstream in;
    in.open( filename.c_str() );
    if ( in.is_open() ) {
        while ( !in.eof() ) {
            getline( in, lineStr );
            cocos2d::CCLog( "lineStr = %s", lineStr.c_str() );
            result += lineStr + "\n";   
        }
        in.close();
    } else {
        cocos2d::CCLog( "ERROR: file not open!" );  
    }

    return result;

}

std::string str5 = getFileContent( cocos2d::CCUserDefault::sharedUserDefault()->getXMLFilePath() );

#9

It doesn’t use XML anymore in iOS and android because (I presume) using there are other more efficient mechanisms.

I’m not sure if it would work or not to get rid of the CCUserDefault.mm and CCUserDefaultAndroid.cpp, and in CCUserDefault.cpp commenting out the line:

#if (CC_TARGET_PLATFORM = CC_PLATFORM_ANDROID)

Maybe it would make stuff work in XML again, if it wasn’t broken for iOS and android in the first place, I don’t know. I haven’t got any mac right now to test. It seems clear to me that iOS implementation is using NSUserDefault to store the values instead so you’d have to look into how that works. Android implementation is using something different again… Study the files CCUserDefault.mm [not the .mm] and CCUserDefaultAndroid.cpp, see what they do and work your way from there. Or try to hack it like I suggested to use the old way, which could be a bad idea as I don’t know why they’re being used in the first place.


#10

Thank you for the information! It was very helpful for me!