Search Unity

Newtonsoft Json with Magic Leap

Discussion in 'AR' started by FrozenKiwi, Mar 26, 2019.

  1. FrozenKiwi

    FrozenKiwi

    Joined:
    Mar 7, 2019
    Posts:
    13
    Hi All,

    I'm facing a very interesting issue and I'm wondering if this sounds familiar to anyone.

    I am integrating an external library that loads text files and parses them using Newtonsoft.Json. The integration was fairly smooth sailing - the functionality worked fine in a standard desktop viewer, inside the Magic Leap editor view, inside the simulator and even on the device with Zero Iteration enabled.

    However, when running the app purely on the device, things went a bit screwy, with what seems like random exceptions during load. After several days a bit of screaming digging, I traced the issue to a throw on the following line.

    Code (CSharp):
    1. JObject item = ...;
    2. item.ToObject<SceneNode>(); // Throws
    The variations on this (eg Populate etc) also threw.

    Interestingly, the exceptions thrown are all over the place, from "Invalid operation on relative Uri" to "Unable to find constructor to use for type". The stack traces showed the stack jumping from Newtonsoft.Json somehow into JsonUtility, and often ending in Unity texture creation (???).

    To workaround this for now, I'm using the slightly sub-optimal

    Code (CSharp):
    1. var asNode = JsonUtility.FromJson<SceneNode>(item.ToString());
    Ideally, we'd like to be able to use the same Json in Unity that we use in our library. Is there any reason why this doesn't work? Is it likely to change in the future?
     
    Last edited: Mar 26, 2019
  2. FrozenKiwi

    FrozenKiwi

    Joined:
    Mar 7, 2019
    Posts:
    13
  3. FrozenKiwi

    FrozenKiwi

    Joined:
    Mar 7, 2019
    Posts:
    13
    Turns out the last post was wrong on just about every count: Unity Json does not fix the issue, and we can use Newtonsoft.Json without modification.

    The real solution is to:
    Mark all serializable classes as [Serializable]
    Don't use accessors { get; set; }
    If you only use code in de/serialization, force AOT compilation ahead of time by explicitly calling the conversion function with all possible types

    https://docs.unity3d.com/Manual/ScriptingRestrictions.html

    (Also, make sure your using the NetStandard library, or compile Newtonsoft without the HAVE_REFLECTION_EMIT define)
     
    AlessioGrancini likes this.
  4. AlessioGrancini

    AlessioGrancini

    Joined:
    Aug 16, 2017
    Posts:
    8
    This is a little bit of a late reply, but I am running into the same problem and this is the only alternative solution I found. Would you mind explaining a little more? thanks
     
  5. FrozenKiwi

    FrozenKiwi

    Joined:
    Mar 7, 2019
    Posts:
    13
    So it's been quite a long time since I dealt with this, but we successfully used regular NetStandard Newtonsoft Json with IL2CPP (on Magic Leap).

    We compiled our base code into a NetStandard library, imported that as a Dll, then prevented code-stripping with some funny named file at the root of the project (one of the unity compiler directives - csp/rsc some odd name like that). I'm not sure that's all necessary - except for the no-stripping part, but just letting you know our setup in case it gives you any pointers.

    What is the actual issue you are having? Where have you gotten to in your investigations?