JsonFx seems to be well recommended for Unity iOS, from a search of forum posts. I just grabbed JsonFx v2.0 and noticed that just using JsonReader and JsonWriter adds System.Xml dependency
ExecutionEngineException: Attempting to JIT compile method ‘JsonFx.Serialization.DataReader1<JsonFx.Model.ModelTokenType>:Read<System.Collections.Generic.Dictionary2<string, object>> (string)’ while running with --aot-only.
I wrote a reply to this a week ago but it apparently didn’t post.
The need for System.Xml is only to support the XML Serialization attributes. If you don’t need these, a build would be easy to produce which didn’t have that dependency.
Also there is probably a subset of the JsonFx v2 source that could be built which would be betters suited to this environment. I’m not familiar with Unity enough but there is certainly a lot of flexibility written into JsonFx v2 which is not critical to JSON serialization.
The XML dependency is a minor issue, and as you mention is is possible to strip out classes and dependencies.
The real problem is that for Unity on iOS, it runs in Mono’s AOT mode, which is extremely unfriendly toward serialization with Generics, particularly Generics of non-string types. After trying pretty much every serialization method available for C# on iOS, and having all of them throw JIT errors at runtime, I eventually settled on GitHub - ServiceStack/ServiceStack.Text: .NET's fastest JSON, JSV and CSV Text Serializers
This has the advantage of being extremely fast, working over RPC methods as well as serializing data to PlayerPrefs. But on iOS one must use string types such as Dictionary<string,string> and List for example.
I should mention that I’m the developer of JsonFx.
If I knew the constraints of Mono’s AOT mode, I’d be able to produce a build that was more suitable for Unity on iOS. I’ve seen a lot of people using JsonFx on here but I’ve never actually made a build specifically for Unity.
If anyone has any better direction for what needs to change to make it work better on Unity, I’d be happy to try to produce a build for it.
mckamey, OK thanks for the info and for JsonFx too! Just to clarify, I think the AOT JIT Errors would arise only running under iOS player. Targeting other Unity platforms such as Win, Mac, webplayer, etc. should not have this issue.
Don’t use reflection for data parsing (ie json ↔ object), parse the Json manually, thats working.
On AOT, these automagic reflection are severely limited
as for System.XML: thats standard, most Json / tree parsers you will find in .NET rely on system xml for one or more aspects
No reflection is needed for deserialization. That is simply reading the JSON text. Reflection is typically used when serializing POCO to JSON.
JsonFx doesn’t rely on System.Xml for anything but the serialization attributes that are pretty commonly used. If you don’t use those attributes on your model objects, then you have no need for System.Xml.dll.
Sry for waking up this old thread, but this is still a problem for me
Has someone a working version of JsonFx, I get it working in editor and Webplayer but not on iOS.
Beside a lot of Warnings that testing against null does’t work and other small stuff, whats not really nice to have so much warning spamm, it’s running in Editor, as said above.
But on iOS i have 2 Problems, stripping with mscorelib is not working. And as dreamora said Object ↔ Json parsing is not working.
But what is working? What is needed to get a Json representation of an Object Array?
I need to get some Objects with string and number propperties to Json for Device ↔ Server communication, something similar to the example here:
I get loads of these when trying: System.MissingMethodException: Method not found: ‘Default constructor not found…ctor() of System.ComponentModel.Int32Converter’.
If you have an updated/(iOS)working version, it would be…AWESOME.
While the link.xml tip was working for me i ran into another problem.
I have Build in Array of a small class. This way i can fill the array within unity. custom class is
[System.Serializable]
public class Level {
public bool locked = true;
public bool played = false;
public int lastPlayerPoints{get;set;}
public int achievedStars{get;set;}
public string sceneName;
}
Now the weird thing. This is iOS only and only happens on the device. I serialize the Array onApplicationPause like this:
void OnApplicationPause (bool pause) {
Debug.Log("*** OnApplicationPause ***************************");
if(pause) {
Debug.Log("*** we got to pause and want to save ***********************");
// we are in background
saveLevelProgressToTextFile(1);
} else {
Debug.Log("*** we resume the game ***********************");
// we are in foreground again.
}
}
void saveLevelProgressToTextFile (int world) {
Debug.Log("******** saveLevelProgressToTextFile ********");
string fileName = "w"+world+"progress.txt";
// this turns a C# object into a JSON string.
Debug.Log("******** fileName = " + fileName);
Debug.Log("******** Checking directory to save to");
if(!Directory.Exists(Application.persistentDataPath+"/LevelProgress")){
Debug.Log("Creating LevelProgress Folder");
Directory.CreateDirectory(Application.persistentDataPath+"/LevelProgress");
} else {
Debug.Log("LevelProgress Folder Exists");
}
//wir öffnen einen neuen StreamWriter
string fullPath = Application.persistentDataPath +"/LevelProgress/" + fileName;
Debug.Log("try to save " + fullPath);
Debug.Log("trying to serialize world1Levels = " + world1Levels);
string levelDataJSON = JsonWriter.Serialize(world1Levels);
Debug.Log("******** levelDataJSON = " + levelDataJSON);
StreamWriter sw = new StreamWriter(fullPath);
sw.WriteLine(levelDataJSON);
sw.Flush();
sw.Close();
//damit schliessen wir den StreamWriter
if(File.Exists(fullPath)){
print("File " + fileName + " written!");
} else{
Debug.LogWarning("Error writing file " + fileName);
}
}
I am testing this with Xcode. I run the app, and hit the home Button. OnApplicationPause gets fired, serialzes, saves and all is well.
I hit the app icon again, app resumes, file gets read in and desiriales. All is well.
But…
if i hit the home button a second time now it crashes on save. Always.
XCode gives me this:
try to save /var/mobile/Applications/4D3BBA14-06FC-40CC-9B92-054399455623/Documents/LevelProgress/w1progress.txt
(Filename: /Applications/buildAgent/work/d9c061b1c154f5ae/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 43)
trying to serialize world1Levels = Level[]
(Filename: /Applications/buildAgent/work/d9c061b1c154f5ae/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 43)
System.String doesn't implement interface System.Collections.IEnumerator
* Assertion: should not be reached at mini-trampolines.c:183
(lldb)
I have no idea why. Only reason could be that on the first desiralisation either the class instances get messed up somehow, or their values have internal type issues.
I am currently lost in the dark
I am also having this problem on iOS. Everything works fine on OSX in the editor but the application crashes when running on the device. The issue comes when I serialize. Did you happen to find any fix for it? Thanks! - Josh
I had the exact same error as well. mini-trampoline.c…
I finally got fed up and started using LitJson. Added all the functionality missing from it… and using that instead.
When this project is done, I do plan on uploading my changes to the project. (When I have time to clean it up.)
The main thing it is lacking is it doesn’t support ignore properties. No rename property. And if I remember correctly, it serializes statics as well…
I did find this a while back: https://bitbucket.org/TowerOfBricks/jsonfx-for-unity3d/src/ They seem to have continued to work on JsonFX… too late for me to see if they have fixed that mini-trampoline, but if any of you try it out, please report on you success/failure with this!
By the way, I have used LitJson in the past and the reason I switched to JsonFx was because I remember having stack problems when deserializing not-so-deeply-nested structures (like 3 or 4 levels or so). There would be an exception telling me stack stack is insufficient or something like that.
This would probably be cause LitJson serializes statics as well… so serializing singletons ==> recursive loop.
I will check with the above finding; thank you!
(We still use JsonFX for reading JSON… and: very late in this project, JsonFX refused to parse a List of int:s all of a sudden… changing to uint worked. (ints > 0 and < 35…), so anything more stable would be…welcome. I do hope they have something better/more stable for Unity4)
System.String doesn't implement interface System.Collections.IEnumerator
* Assertion: should not be reached at mini-trampolines.c:183
This is a problem for us too. We’re using LitJson.
The problem goes away on test devices when we remove some of our log statements. Some of these statements have JsonData.ToJson() in them ( object → string ), but we are not satisfied at all that this is the culprit because it is used throughout the project and does not appear to use reflection. Other possible culprits include the use of JsonMapper.ToObject(), however this is used fairly often and is not used in any log statements (which would make no sense). I also cannot find any use of Reflection in the class.
We are continuing to test, and hoping to discover more precisely what the issues are. In the meantime, if anyone has any concrete information, that would be extremely helpful. Properly debugging this issue is nightmarish at the moment, because of the way trampolines work and the lack of solid information on the web concerning precisely what causes trampolines to be required in an AOT build.
In fact, we are even confused about how trampolines are relevant at all here: since iOS requires AOT, doesn’t that mean that the JIT doesn’t run? And if so, how are trampolines used? Sure, they are pre-allocated at compile-time, but surely to be used at runtime the JIT must in some sense be running?
Furthermore, upping the number of each type of trampoline in the AOT settings appears to have no effect whatsoever upon the issue.