dil33pm dil33pm - 4 months ago 166
JSON Question

Deserialization of JSON using MiniJSON in Unity C#

I have a list of items send from a PHP file to unity using WWW. The WWW.text looks like

[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
where I trim the extra
[]
from the string. When I try to parse it using Boomlagoon.JSON, only the first object is retrieved. I found out that I have to
deserialize()
the list and have imported MiniJSON.

But I am confused how to deserialize() this list. I want to loop through every JSON object and retrieve data. How can I do this in Unity using C#?

The class I am using is

public class player {

public string playerId { get; set; }
public string playerLoc { get; set; }
public string playerNick { get; set; }
}


After trimming the
[]
I am able to parse the json using MiniJSON. But it is returning only the first
KeyValuePair
.

IDictionary<string,object> s = Json.Deserialize(serviceData) as IDictionary<string,object>;
foreach (KeyValuePair<string, object> kvp in s)
{
Debug.Log(string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value));
}


Thanks!

Answer

Unity added JsonUtility to their API after 5.3.3 Update. Forget about all the 3rd party libraries. JsonUtility is more than 10x faster than other Json libraries. Update to Unity 5.3.3version or above then try the code below.

To convert your player class to Json then serialize it back to class without using third-party libraries:

1. ONE DATA(NON ARRAY JSON)

public class player
{

    public string playerId;
    public string playerLoc;
    public string playerNick;
}

public class APP : MonoBehaviour
{
    player playerInstance;

    void Start()
    {
        playerInstance = new player();
        playerInstance.playerId = "8484239823";
        playerInstance.playerLoc = "Powai";
        playerInstance.playerNick = "Random Nick";

        //Convert to Jason
        string playerToJason = JsonUtility.ToJson(playerInstance);
        Debug.Log("Jason is " + playerToJason);

        //Convert Json Back to Class(Serialize) METHOD 1 
        player serializedPlayer = new player();
        serializedPlayer = JsonUtility.FromJson<player>(playerToJason);
        //serializedPlayer now conatains data from playerToJason/playerInstance

        //Convert Json Back to Class(Serialize) METHOD 2 (Creates new instance of player. No new keyword required)
        player AnotherSerializedPlayer = (player)JsonUtility.FromJson(playerToJason, typeof(player));
        //AnotherSerializedPlayer now conatains data from playerToJason/playerInstance

        //Convert Json Back to Class(Serialize) METHOD 3(Overwrite the existing   class  instance "playerInstance". Less memory Allocation)
        JsonUtility.FromJsonOverwrite(playerToJason, playerInstance);
    }
}

EDIT:

2. MULTIPLE DATA(ARRAY JSON) Your Json contains multiple data. For example playerId appeared more than once. Unity's JsonUtility does not support array as it is still new but you can use a helper class from this person to get array working with JsonUtility.

Create a class called JsonHelper. Copy the JsonHelper directly from below.

using System;
using UnityEngine;
using System.Collections;

public static class JsonHelper
{
    public static T[] FromJson<T>(string json)
    {
        Wrapper<T> wrapper = UnityEngine.JsonUtility.FromJson<Wrapper<T>>(json);
        return wrapper.Items;
    }

    public static string ToJson<T>(T[] array)
    {
        Wrapper<T> wrapper = new Wrapper<T>();
        wrapper.Items = array;
        return UnityEngine.JsonUtility.ToJson(wrapper);
    }

    [Serializable]
    private class Wrapper<T>
    {
        public T[] Items;
    }
}

Your original data is

 [{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]

Add {"Items": in front of it then add } at the end of it.

Code to do this:

serviceData = "{\"Items\":" + serviceData + "}";

Now you have:

 {"Items":[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]}

To serialize the multiple data from php as arrays, you can now do

public player[] playerInstance;
playerInstance = JsonHelper.FromJson<player>(serviceData);

playerInstance[0] is your first data

playerInstance[1] is your second data

playerInstance[2] is your third data

or data inside the class with playerInstance[0].playerLoc, playerInstance[1].playerLoc, playerInstance[2].playerLoc ......

You can use playerInstance.Length to check the length before accessing it.

NOTE: Remove { get; set; } from the player class. If you have { get; set; }, it wont work. Unity's JsonUtility does NOT work with class members that are defined as properties.