Search code examples
c#unity-game-enginelong-integersimplejsonint64

Int64 changes value when passed into a function with SimpleJSON


I'm getting User IDs (int64) from JSON and then passing them into a function to populate user data. However the JSON ID value I get changes once I pass it through a iEnumerator function. Any idea why this happens?

I have printed the values and know for sure they are the expected JSON values before i pass them.

I am getting the IDs with GetTeachersStudentList and passing them into PopulateStudentGamesAndTutorial. The dictionaries I am using to store the IDs and data are initialized right before GetTeachersStudentList is called.

IEnumerator GetTeachersStudentList()
{
    //get user information from server call 
    Dictionary<string, string> headers = new Dictionary<string,string>();
    headers.Add("Access-Token", PlayerData.accessToken);
    string url = studentURL += "?staffId=" + PlayerData.currentUser.staffId;

    WWW www = new WWW(url, null, headers);

    yield return www;

    StudentListWebResponse = www.text;
    PlayerData.studentList = StudentListWebResponse; 

    //parse json
    JSONArray students = (JSONArray) JSON.Parse(StudentListWebResponse);
    expectedStudentsToPopulate = students.Count;

    //populate each users data 
    for (int i = 0; i < students.Count; i++)
    {
        string userInformation = students[i].ToString();
        JSONObject studentJsonObject = (JSONObject) JSON.Parse(userInformation);
        foreach (var item in studentJsonObject)
        {
            //look for id, then use that id to populate user data
            if (item.Key == "id")
            {
                StartCoroutine(PopulateStudentGamesAndTutorial(item.Value));
            }
        }
    }

    PlayerData.control.Save();
}

IEnumerator PopulateStudentGamesAndTutorial(Int64 id)
{
    //get games with id 
    Dictionary<string, string> headers = new Dictionary<string,string>();
    headers.Add("Access-Token", PlayerData.accessToken);

    string studentGameURL = serverManager.GamesURL(id);
    WWW gamesWWW = new WWW(studentGameURL, null, headers);
    yield return gamesWWW;  
    PlayerData.StudentListWithGames.Add(id, gamesWWW.text);

    //get tutorials with id 
    string tutorialURL = serverManager.TutorialURL(id);
    WWW wwwGetTutorialsCompleted = new WWW(tutorialURL, null, headers);
    yield return wwwGetTutorialsCompleted;
    JSONArray tutorialArray = (JSONArray) JSON.Parse(wwwGetTutorialsCompleted.text);
    List<int> tutorialIDList = new List<int>();
    for (int i = 0; i < tutorialArray.Count; i++)
    {
        tutorialIDList.Add(tutorialArray[i]["id"]); 
    }
    PlayerData.StudentListWithTutorials.Add(id, tutorialIDList);
    PlayerData.control.Save();

Solution

  • SimpleJSON stores all simple scalar values (such as Booleans, numbers and strings) as string. It provides accessor properties and operators to allow you to extract the value as a number of different types.

    So for example:

    bool b1 = node.AsBool; 
    bool b1 = node; // Calls operator bool which in turn calls AsBool
    

    This means that in most cases you can simply use the node as if it was already the correct type.

    However there is no automatic conversion to Int64. If you try to use a node where an int64 is expected, the best match will be operator int which will not do what you want.

    The solution is to pass it as a string, and use Int64.Parse or Int64.TryParse to convert it to the correct type.