SaladLab / Json.Net.Unity3D

Forked Newtonsoft.Json to support Unity3D
MIT License
918 stars 169 forks source link

JObject -> HashSet Exception on IOS #8

Open zpavlov opened 8 years ago

zpavlov commented 8 years ago

As a side note, serializing to string and back works fine on iOS, it just appears to be ToObject.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class JFail : MonoBehaviour {

    public class JsonFailure {
        public HashSet<string> foo;
        public JsonFailure() {
            foo = new HashSet<string>();
            foo.Add("HI THERE");
        }
    }
    void Start() {
        JsonFailure original = new JsonFailure();
        JObject jobject = JObject.FromObject(original);
        Debug.Log("JObject: " + jobject.ToString());
        Debug.Log (jobject["foo"].Type.ToString ());

        //Argument Non Null exception on IOS
        JsonFailure backFromJObject = jobject.ToObject<JsonFailure>();
        Debug.Log("---------------------DONE");
    }

}

In editor, this works as expected, but on IOS, the ToObject call exceptions with the following error (apologies for lack of line number due to il2cpp)

ArgumentNullException: Argument cannot be null. Parameter name: method at Newtonsoft.Json.Utilities.ValidationUtils.ArgumentNotNull (System.Object value, System.String parameterName) [0x00000] in :0 at Newtonsoft.Json.Utilities.LateBoundReflectionDelegateFactory.CreateParameterizedConstructor (System.Reflection.MethodBase method) [0x00000] in :0 at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x00000] in :0 at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue (Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.JsonConverter propertyConverter, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty, Newtonsoft.Json.JsonReader reader, System.Object target) [0x00000] in :0 at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject (System.Object newObject, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, System.String id) [0x00000] in :0 at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x00000] in :0 at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, Boolean checkAdditionalContent) [0x00000] in :0 at Newtonsoft.Json.JsonSerializer.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in :0 at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in :0 at Newtonsoft.Json.Linq.JToken.ToObject (System.Type objectType, Newtonsoft.Json.JsonSerializer jsonSerializer) [0x00000] in :0 at Newtonsoft.Json.Linq.JToken.ToObject (System.Type objectType) [0x00000] in :0 at JFail.Start () [0x00000] in :0

veblush commented 8 years ago

Oh I confirmed that it happened on my machine, too. I'll take a look at it :+1:

zpavlov commented 8 years ago

thanks! We're currently working around this and another issue related to bools using jsonproperty attributes and onDeserialized/onSerialized properties to convert the data

veblush commented 8 years ago

Ok. I fixed this problem. Please install the latest release. (previous one is replaced) and put following code on anywhere in your executable code path.

Newtonsoft.Json.Utilities.AotHelper.EnsureList<string>();

This makes Unity3D take necessary classes for deserializing HashSet<string> in iOS executable.