CCDictionary - bug? reading value always returns NULL

Hi,
Hoping someone on here can help as I’ve been beating my head against this for a long time. At this point, it looks like a potential bug (as code from numerous other tutorials and posts doesn’t seem to work as well), but I’m still hopeful it’s something bone-headed I’m doing. I’ve seen some other recommendations for some xml packages to use to read plists, but I’d prefer to use the functionality of the Cocos2dx engine if I can get it to work.

I’m loading a plist file and trying to read some values from a dictionary from that file (and I’ve tried with combinations of arrays and dictionaries but always hit some flavor of the same issue). Reading values always returns NULL. The plist seems to load fine, as I can read all the keys in the file, but anytime I try to retrieve a value I get NULL.

The first two lines seem to work, but the third line, obj returns NULL.

CCArray* _levels =  CCArray::createWithContentsOfFileThreadSafe("levels.plist");
CCDictionary* _chosenLevel = (CCDictionary*)_levels->objectAtIndex(0);

CCString* obj = (CCString*)_chosenLevel->objectForKey("start");

But, I can do this and see all the keys printed to the output window:

CCArray* keys = _chosenLevel->allKeys();
for (int i = 0; i < keys->count(); i++)
{
  CCString* key = (CCString*)keys->objectAtIndex(i);
  CCLog(key->getCString());
}

And, all of these return NULL:

string myString = _chosenLevel->valueForKey("start")->getCString();
CCObject* myObject = _chosenLevel->objectForKey("start");
CCDictElement* dictElement = (CCDictElement*)_chosenLevel->objectForKey(key->getCString());
_chosenLevel->valueForKey("end")->intValue();

I’ve also tried with CCFloat* and CCInteger* but still always get NULL back
Pretty much anything I’ve tried that tries to get either an objectForKey or a valueForKey always returns NULL.

The plist file is:

        start
        1
        end
        5
        right
        2
        left
        2
        middle
        13.5

Any ideas?
I’m using Cocos2dx 2.2, using C++, in Visual Studio, developing for an app for the Windows 8.1 environment. Everything else I’m doing is working fine.

Thanks in advance

hi
i test the following code:

    CCArray* _levels = CCArray::createWithContentsOfFileThreadSafe("levels.plist");
    CCDictionary* _chosenLevel = (CCDictionary*)_levels->objectAtIndex(0);

    CCString* obj = (CCString*)_chosenLevel->objectForKey("start");
    CCLog("obj: %x, %s", obj, obj->getCString());

    CCArray* keys = _chosenLevel->allKeys();
    for (int i = 0; i < keys->count(); i++)
    {

        CCString* key = (CCString*)keys->objectAtIndex(i);
        CCLog("key: %s", key->getCString());
        CCDictElement* dictElement = (CCDictElement*)_chosenLevel->objectForKey(key->getCString());
        CCLog("dictElement: %x.", dictElement);
    }

    std::string myString = _chosenLevel->valueForKey("start")->getCString();
    CCLog("myString: %s.", myString.c_str());
    CCObject* myObject = _chosenLevel->objectForKey("start");
    CCLog("myObject: %x.", myObject);
    //CCDictElement* dictElement = (CCDictElement*)_chosenLevel->objectForKey(key->getCString());
    int v1 = _chosenLevel->valueForKey("end")->intValue();
    CCLog("v1: %d.", v1);

just as you said.
and i got result like xcode.png and win32.png.
i think the result is right.


Thanks for the quick reply. So I copied your code above and pasted it into visual studio and ran it. In the 3rd line, it fails:
@@CCString* obj = (CCString*)_chosenLevel->objectForKey(“start”);

obj is NULL. So it’s getting the same behavior as described in my post. Is there something else I can take a look at?

I’m not sure whether it could be a problem, but maybe you have wrong line endings in your plist-file (CRLF vs LF)?

Good suggestion. I tried that - I resaved the plist files and tried a few different options LF, CRLF, and CR. I got the same result in each case. For full transparency, the _level variable is a member of a class, but I can’t see why that would matter.

I looked at a few other things, but no luck. I suspect it has something to do with targeting an app to windows 8.1 (as apparently the code above works on other environments.) I’m not sure how well tested projects targeting windows 8.1 are as it seems most folks use cocos2dx for iPhone/android. One last thing I’ll look at is digging out the template project and running it there to see if I can step into the debugger in the cocos2dx code (I found the template project hard to use and huge, so I copied the headers, built the necessary dlls and then put together a nice streamlined project targeting just Windows to get started).

I’ve heard there are some other good free xml parsing/saving packages out there and I was thinking of using one of those (sounds easier than rolling my own). If I don’t get anywhere soon, I’ll look at one of those.

It seems you have to dive into amazing world of step by step debugging.