Unity, JsonFX does not deserialize

1.4k views Asked by At

I just want to serialize some data and deserialize it back, and it must work on iOS platform. Json.NET does not works on iOS. The JsonFX can serialize data and string looks like string serialized by Json.Net, but JsonFX can't deserialize data back. Here is simple code which gives me next error

InvalidCastException: Cannot cast from source type to destination type.

using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using Pathfinding.Serialization.JsonFx;

public class jsonTest : MonoBehaviour {

    public Text text;
    public List<ChapterModel> chapters;

    // Use this for initialization
    void Start () {
         chapters = new List<ChapterModel>();

         for(int i=0; i<2; i++)
         {
             var cm = new ChapterModel();
             cm.pages = new List<PageModel>();
             cm.id = i;

             for(int j =0; j<2; j++)
             {
                 var pm = new PageModel();
                 pm.BackgroundArt = j.ToString();
                 cm.pages.Add(pm);
             }

             chapters.Add(cm);
         }

        Debug.Log(JsonReader.Deserialize<List<ChapterModel>>(JsonWriter.Serialize(chapters)).Count);
    }
}

Is anyone knows how to fix it?

1

There are 1 answers

2
mwilczynski On BEST ANSWER

After playing around a little bit with JsonFX I found out that it's quite tricky to use:

using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using System.Linq;
using Pathfinding.Serialization.JsonFx;
using UnityEditor;

public class jsonTest : MonoBehaviour
{

public Text text;
public List<ChapterModel> chapters;

// Use this for initialization
void Start()
{
    chapters = new List<ChapterModel>();

    for (int i = 0; i < 2; i++)
    {
        var cm = new ChapterModel();
        cm.pages = new List<PageModel>();
        cm.id = i;

        for (int j = 0; j < 2; j++)
        {
            var pm = new PageModel();
            pm.BackgroundArt = j.ToString();
            cm.pages.Add(pm);
        }

        chapters.Add(cm);
    }

    string json = JsonWriter.Serialize(chapters);

    //Will end up in in invalid cast:
    //var deserialized = JsonReader.Deserialize<List<ChapterModel>(json);

    //Will be casted to object[] on deserialization:
    //var deserialized = JsonReader.Deserialize(json, typeof (List<ChapterModel>));

    //Will evaluate just fine:
    var deserialized = JsonReader.Deserialize(json, typeof(List<ChapterModel>)) as object[];
    List<ChapterModel> list = deserialized.Select(item => item as ChapterModel).ToList();
    Debug.Log(list.Count);
    }
}

[System.Serializable]
public class ChapterModel
{
   public int id = -1;
   public List<PageModel> pages;
}


[System.Serializable]
public class PageModel
{
   public string BackgroundArt,
    ForeAddedArt,
    VFXloop, VFXappeared, VFXnextSlide,
    BGAmbientLoop, BGMusicLoop, BGVoiceLoop,
    VFXSound, MusicSound, VoiceSound;
}

However, if we let our JSON know a typehint, it should be fine. What's funny, it's not:

    //(...)
    StringBuilder output = new StringBuilder();

    JsonWriterSettings writerSettings = new JsonWriterSettings { TypeHintName = "__type" };

    JsonWriter writer = new JsonWriter(output, writerSettings);
    writer.Write(chapters);
    JsonReaderSettings readerSettings = new JsonReaderSettings { TypeHintName = "__type" };
    JsonReader reader = new JsonReader(output, readerSettings);

    //Will now see objects inside array as ChapterModel but still will fail to cast properly to list/array of ChapterModels
    List<ChapterModel> deserialized = reader.Deserialize() as List<ChapterModel>;
    Debug.Log(deserialized.Count);

You might want to play a little more with it or stick with ugly version I provided above.