Question

I'm using a unity plugin to handle Facebook called prime[31] Social Networking Plugin. It works fine for something like this:

void onGraph()
    {
        Facebook.instance.graphRequest( "me", HTTPVerb.GET, ( error, obj ) =>
        {
            // if we have an error we dont proceed any further
            if( error != null )
                return;             
            if( obj == null )
                return;             
            // grab the userId and persist it for later use
            var ht = obj as Dictionary<string,object>;
            _userId = ht["id"].ToString();      

            Debug.Log( "me Graph Request finished: " + _userId );
            Prime31.Utils.logObject( ht );
        } );
    }

It returns this:

 --------- IDictionary ---------
id: ########## 
name: Mike O'Connor 
first_name: Mike 
last_name: O'Connor 
link: https://www.facebook.com/########## 
username: ########## 
etc...

and I can seemingly grab any key and stuff it into a variable like this, right?:

_userId = ht["id"].ToString();

but when I request the scores of everyone playing my game:?

void onGetScore()

    {
        Facebook.instance.graphRequest( "AppID/scores", HTTPVerb.GET, ( error, obj ) =>
        {
            // if we have an error we dont proceed any further
            if( error != null )
                return;

            if( obj == null )
                return;
            // grab the userId and persist it for later use
            var ht = obj as Dictionary<string, object>;
            _score = ht["score"].ToString();
            Prime31.Utils.logObject( ht );
        } );
    }

It returns a nested dictionary/list like this:

 --------- IDictionary --------- 

 --------- IList --------- 
data: 
    --------- IDictionary ---------
    user:    --------- IDictionary ---------
        name:   Mike O'Connor
        id:     ##########
        score:  5677
        application:     --------- IDictionary ---------
            name:   ##########
            namespace:  ##########
            id:     ##########

now it's nested so I can't use this, right?

_score = ht["score"].ToString();

How do I get at the nested keys? Is it just a syntax problem or do I have to recast (or something else)?

Was it helpful?

Solution

So you want to access the value of a key-value pair inside a dictionary, inside a dictionary, inside a list, inside a dictionary?

It sounds like you want this:

_score = ht["data"][0]["score"].ToString();

Note, the 0 here represents the first item in the ht["data"] list.

Unfortunately it looks like your objects are probably weakly typed. In that case you'd have to do:

_score = 
    ((IDictionary<string, object>)
        ((IList<object>)ht["data"])[0])["score"].ToString();

Which looks terrible, but should work (assume the types returned are really what you describe).

To get an set of user name / score pairs, you can use something like this Linq query:

var scores = 
    from item in ((IList<object>)ht["data"]).Cast<IDictionary<string, object>>()
    let name = ((IDictionary<string, object>)item["user"])["name"].ToString()
    let score = item["score"].ToString()
    select new { username = name, score };

OTHER TIPS

You're going to need to change the property access logic. ht["score"] doesn't exist anymore (or at least isn't at the outer level, it's in a dictionary that's in a list that's in a dictionary). Instead it will be like ht["list1"].First()["score"].ToString() however I'm not sure what the exact path would be because your data format is not clear. Can you just update with the raw response? Then I can tell you for sure. Also, I think you'll likely have to do some iteration. Because the structure is nested more than once to get the inner values you have to iterate the outer dictionary, and then the list it contains, then access the values in the dictionaries that list contains.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top