I am trying to set dynamic json collection data using JsonUtilit,and not having a lot of luck, at first I tried getting the raw string (but why would that ever work) so I could iterate over it then cast them to their types, once I had the string types.
[Serializable]
public class JsonHeader
{
public string title;
public string description;
public string id;
public JsonData[] data;
}
[Serializable]
public class JsonData
{
//Use this type to use as a switch to deseralize to the correct object?
public string type;
public Dictionary<string, object> data;
//I just need a way to get the data in some form in json utility so I can desacralize it properly.
}
[Serializable]
public class SingleData...
[Serializable]
public class DateData...
public void Start()
{
string jsonString = @"
{
""title"": ""Tester"",
""description"": ""foobar"",
""id"": ""1"",
""data"": [
{
""type"": ""single"",
""data"": {
""title"": ""Multiple choice"",
""description"": """",
""id"": ""2"",
""options"": [
""test1"",
""test2""
],
""default"": 0,
""required"": false
}
},
{
""type"": ""date"",
""data"": {
""title"": ""Date picker"",
""description"": """",
""id"": ""3"",
""default"": ""2011/11/11"",
""required"": false
}
}
]
}";
//Not setting the data
var data = JsonUtility.FromJson<JsonHeader>(jsonString);
//Setting the data
var data2 = JsonConvert.DeserializeObject<JsonHeader>(jsonString);
Anyone see a way to do this using JsonUtlity, even if it’s a hack?
You can copy the dictionary data to parallel arrays instead, it’ll serialize those.
Better yet, use Newtonsoft Json.Net instead of JsonUtility and be done with it. As soon as you start needing to “hack” JsonUtility, it’s easier to just use the better JSON package to start with.
There has to be a serialisation library you can use on IOS. JsonUtility is pretty damn useless. It can’t serialise anything that Unity can’t draw in the inspector, which is a lot of things honestly.
Hence why when someone says “I’m using JsonUtility”, everyone else says, “Use an actual proper serialisation lib”. There has to be others. Have you looked at the Odin serialiser?
It’s more complex in the case of JsonUtility as it’s kept around largely for backwards compatibility reasons. Around five years ago (Unity 2019.1) Unity released the following package with a more competent JSON implementation that isn’t dependent on third party libraries like Newtonsoft (though I’d likely still use that over an official one).
Note that Unity’s JsonUtility is actually one of the fastest json parsers in most comparisons because it’s actually written o the C++ side with tons of optimisations as it ties into the internal serialization system. That’s why it has the same limitations. Those strict limitations actually made it that fast.
Apart from that, what’s your actual goal? If you just want to handle arbireary json data, you could use my SimpleJSON library. It’s just a single source file (well there are extension files, one for Unity) and it doesn’t actually map the data to your own classes but simply provides access to the json data in an easy to use manner.
Whatever object mapper you would use, your approach by using a Dictionary<string,object> would require tons of type checking and casting in order to use the data. I’ve originally written the parser outside of Unity specifically to handle webservice requests and answers.
The usage is as simple as
JSONNode n = JSON.Parse(jsonString);
string opt = n["data"][0]["data"]["options"][1];
Debug.Log(opt); // prints test2
The library will rarely cause any error as missing keys just means it will dynamically create a “LazyCreator” which will retroactively create the structure once you assign a value to a nested but missing object. Though be warned that you can not lazily create an array entry with a specific index. When you provide an invalid index, it will simply add an element at the end. So this
JSONNode n = new JSONObject();
n["test"][0]["foobar"] = 5;
n["test"][-42]["foobar"] = 42;
Debug.Log(n.ToString(4))
will create this json
{
"test":[
{
"foobar": 5
},
{
"foobar": 42
}
]
}
The library is simple but has a lot of flexibility. All classes are declared as partial so you can augment whatever data or methods you want into the concept. Have a look at the Unity extension file which adds conversion methods / properties and conversion operators to the JSONNode class so you can transparently read Vector3 or Color values. Adding custom conversion operators is quite easy for other custom classes if that’s necessary. Each JSONNode also has casting properties so you can easily attempt to convert say a string to a float or int.