Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

MiniJSON script for parsing JSON data

Discussion in 'iOS and tvOS' started by Dark-Table, Nov 25, 2009.

  1. Dark-Table

    Dark-Table

    Joined:
    Nov 25, 2008
    Posts:
    315
    (Updated 12/1/11) It's the season for sharing.

    Attached is a handy script for encoding and decoding JSON data. This could be used as a way to pack arrays and dictionaries into PlayerPrefs, or a way to interact with web services.

    It's a small modification of a script I found online:
    http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html

    I modified it so that it would run in Unity iPhone without complaining or throwing exceptions.

    It can encode any basic type (int, string, float, etc.) and arrays, ArrayLists, and hashtables. Note: When you decode an array you always get an ArrayList back.

    There are a couple areas that I haven't tested throughly:
    * I haven't tried encoding and decoding Unicode text (above the normal ASCII range)
    * I haven't tried encoding and decoding numbers in a locale that uses . as the thousands seperator (1.234,56). I also haven't tried encoding numbers in one locale and decoding in another.

    Here's an example that gets tweets mentioning Unity3d:
    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6. using MiniJSON;
    7.  
    8. public class MiniJsonDemo : MonoBehaviour {
    9.   void Start () {
    10.     StartCoroutine("GetTwitterUpdate");    
    11.   }
    12.  
    13.   IEnumerator GetTwitterUpdate() {
    14.     WWW www = new WWW("http://search.twitter.com/search.json?q=Unity3d");
    15.    
    16.     float elapsedTime = 0.0f;
    17.    
    18.     while (!www.isDone) {
    19.       elapsedTime += Time.deltaTime;
    20.      
    21.       if (elapsedTime >= 10.0f) break;
    22.      
    23.       yield return null;  
    24.     }
    25.    
    26.     if (!www.isDone || !string.IsNullOrEmpty(www.error)) {
    27.       Debug.LogError(string.Format("Fail Whale!\n{0}", www.error));
    28.       yield break;
    29.     }
    30.    
    31.     string response = www.text;
    32.    
    33.     Debug.Log(elapsedTime + " : " + response);    
    34.    
    35.     IDictionary search = (IDictionary) Json.Deserialize(response);
    36.    
    37.     IList tweets = (IList) search["results"];
    38.    
    39.     foreach (IDictionary tweet in tweets) {
    40.       Debug.Log(string.Format("tweet: {0} : {1}", tweet["from_user"], tweet["text"]));
    41.     }
    42.   }  
    43. }
    44.  
    GitHub Gist: MiniJSON.cs

    For more complicated JSON serializing and deserializing, I highly recommend using JsonFX.
    JsonFX for Unity

    Edit: Updated and optimized this script to use generics and StringBuilders throughout. I've tested it with a ~32k JSON file, and it was able to serialize and deserialize it without issue. Added an MIT license header.
     
    Last edited: Dec 1, 2011
  2. kenlem

    kenlem

    Joined:
    Oct 16, 2008
    Posts:
    1,630
    Thanks! This should come in handy.
     
  3. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    Just a head's up on this MiniJSON; the class worked fine for minor things, but the moment i threw some modest-sized data at it on iOS, it caused the Garbage Collector to go nuts the app to hang during the delay.

    Sometimes up to over a 1.5min, and that's not even with a big data set (40k or so).

    Your sharing this is still very much appreciated; just as a heads up, if you need to do heavy lifting with JSON, recommend instead JsonFx's Serialization library (http://jsonfx.net/download/).

    iOS friendly and MUCH faster w/out any major GC overhead.

    Thanks again!
     
  4. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Will second the recommendation on JsonFX, definitely the most solid, iOS usable library (if you use Unity iOS 1.x, its actually the only one that works at all).
    It pushed through over 200 students each with about 2 dozen keys for a virtual master project expo guide earlier this year which were streamed from WWW upon request without any delay or GC spiking
     
  5. fyrlandt

    fyrlandt

    Joined:
    Aug 20, 2009
    Posts:
    80
    So JsonFX is more recommended over Litjson?
     
  6. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    With Unity iPhone 1.x Litjson just didn't work (but used it on a desktop project where its fine). It depends a bit on your requirements if its better or not
     
  7. fyrlandt

    fyrlandt

    Joined:
    Aug 20, 2009
    Posts:
    80
    Ahh, I guess I'll just try both then XD
     
  8. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    Adding, had tried LitJSON prior to switching to JsonFX and found JsonFX more compatible for my purposes.
     
  9. Rustam-Ganeyev

    Rustam-Ganeyev

    Joined:
    Jul 18, 2011
    Posts:
    29
    Thank you, silentchujo! You saved my day
     
  10. defjr

    defjr

    Joined:
    Apr 27, 2009
    Posts:
    436
    That's cool, you're cool. I like JSON. :)
     
  11. andymads

    andymads

    Joined:
    Jun 16, 2011
    Posts:
    1,614
    Thanks for sharing :)
     
  12. Andrei_Nubee

    Andrei_Nubee

    Joined:
    Jan 18, 2012
    Posts:
    1
    Can someone help me? I'm new to Json and I'm having trouble making the Json parsers work with this json string from the server I'm working on:

    [{"code":"200","message":"OK"},{"user_id":"1","facebook_id":null,"user_name":"fendy","avatar_type":"14","level":"3","map_size":"1","credibility":"70"}]

    I've tried DarkTable's JsonFx for Unity and MiniJson. My problem is always I get Invalid Cast Exception whenever I deserialize (in MiniJson's case, I do an explicit cast).

    I suspect that I might just be using these parsers wrong, unless the parsers themselves don't support the json string above.

    Can anyone show me how to deserialize the json string shown above? Whether it be MiniJson or JsonFx. I would appreciate it.
     
  13. elhispano

    elhispano

    Joined:
    Jan 23, 2012
    Posts:
    52
    You have there two strings in request results.
    String 1: {"code":"200","message":"OK"}
    String 2 : {"user_id":"1","face book_id":null,"user_name":"fendy","avatar_type":"1 4","level":"3","map_size":"1","credibility":"70 "}

    So, you first need to iterate over an array of strings, and then, you must parse String2 (second element in string array) with the class that you have defined to represent it in your project.

    Take note that:
    All classes must have a simple constructor, without parameters.
    You can´t use Properties in C#, they throw an error in iOS
     
  14. J_P_

    J_P_

    Joined:
    Jan 9, 2010
    Posts:
    1,027
    This MiniJSON stuff works great for me. Someone might find this useful:
    Code (csharp):
    1.     public float GetAsFloat(object theObject, float defaultValue = 0.0f){
    2.         if(theObject == null){
    3.             return defaultValue;
    4.         }
    5.        
    6.         var newNumber = theObject.GetType().ToString() == "System.Double"?(double)theObject:(long)theObject;
    7.         return (float)newNumber;
    8.        
    9.     }
    If our db had float value of 1.0, I'd get a json object telling me the value is 1 (I think because php doesn't do types? I didn't code the backend part so I don't really know) -- this meant that when asking for a double, I'd sometimes get a long and it spit out an error. So the above code checks if it is null (if so, return default value) - if not null, it checks whether it's long or double before returning float.
     
    Last edited: Mar 6, 2012
  15. Saulotti

    Saulotti

    Joined:
    Oct 20, 2009
    Posts:
    19
    Hey! How should I cast when nesting dictionaries? like:

    { "int" : 1, "array" : { "int" : 2, "numbers": { "number1" : 1 }}}​

    i'm trying to do this, but i'm getting casting errors. after parsing:

    (double)parsedData["int"] // returns 1
    IDictionary dic = (IDictionary) parsedData["array"]);
    IDictionary dic2 = (IDictionary) dic["numbers"] // CASTING ERROR​

    What should I do? Thanks!
     
  16. thinkfuture

    thinkfuture

    Joined:
    Jul 23, 2012
    Posts:
    3
    Hi all: I'm attempting to parse some JSON using MiniJSON but I can't seem to find any examples at all of how to do it using Unity JS

    Here is what I've done so far:
    1. Created a plugins directory under Assets
    2. Placed the latest MiniJSON.cs into that directory
    3. Attempted a number of various ways of accessing it - such as:

    var f = MiniJSON.Decode(request.data); - gives me "'Decode' is not a member of 'MiniJSON'"
    var f = Json.Deserialize(request.data); (as per M)- gives me Unknown identifier: 'Json'
    var f = MiniJSON.Deserialize(request.data); - gives me "'Deserialize' is not a member of 'MiniJSON'"
    var f = MiniJSON.Json.Deserialize(request.data); does not give me and error, but when I try to print f it shows up as blank.

    In case its important, here is what the JSON looks like coming from the server:

    {"fighters":[{"species":"Mega","sex":"F","image":"https://s3.amazonaws.com/image/fighter.png","xp":100,"level":1,"strength":90,"stamina":110,"health":58,"hunger":19.0,"speed":0.4,"color":"brown","size":"L"},{"species":"Mega","sex":"M","image":"https://s3.amazonaws.com/image/fighter.png","xp":100,"level":1,"strength":110,"stamina":90,"health":44,"hunger":45.0,"speed":0.96,"color":"brown","size":"L"}]}

    I've searched high and low over the last two days but I can't find any JS examples of how to parse using MiniJSON. Are there any examples out there? If I can't find any my next steps will be pretty steep, write my own parser or learn C#, neither of which this project is giving me the time to do. If someone has an example out there, please let me know....

    Thanks!
     
    Last edited: Aug 23, 2012
  17. mastermax001

    mastermax001

    Joined:
    Aug 9, 2012
    Posts:
    9
    Thank you for sharing your work, extremely useful :)
     
  18. Bovine

    Bovine

    Joined:
    Oct 13, 2010
    Posts:
    177
    I've been struggling to find a working parser - take the example below:

    public class Bob
    {
    public Vector3 Tmp = new Vector3(1, 2, 3);
    }


    This explodes with jasonFX - anyone have a serializer that can cope with this?
     
  19. rstehwien

    rstehwien

    Joined:
    Dec 30, 2007
    Posts:
    101
    I wrote a POCO (plain old C# object) serialize that takes any class and preserves polymorphism. It leverages MiniJSON in that it creates a dictionary that is written/read by the rest of the lib.

    I need to test it on iOS but I'm pretty sure I didn't use any unsupported functions. My plan was to package it up and put it on the asset store for a nominal fee. Wrote it because I found JsonFX and others insufficient for my needs.
     
  20. rsaenz

    rsaenz

    Joined:
    Sep 8, 2010
    Posts:
    5
    Thanks! perfect for parsing localization strings with nested levels.
     
  21. rsaenz

    rsaenz

    Joined:
    Sep 8, 2010
    Posts:
    5

    Hi,

    I've just used the MiniJSON for parsing information with multiple nested levels. The best way is to use a recursive function. Hope this helps!

    Code (csharp):
    1.  
    2.     public static void DoTest()
    3.     {
    4.         string jsonString = "{ \"int\" : 1, \"array\" : { \"int\" : 2, \"numbers\": { \"number1\" : 1 }}}";
    5.         int count = 0;
    6.         ParseJSON( 0, MiniJSON.Json.Deserialize( jsonString ) as Dictionary<string, object>, ref count );
    7.         Debug.Log( "Number of keys: " + count );
    8.     }
    9.  
    10.  
    11.     private static void ParseJSON( int level, Dictionary<string, object> dictToParse, ref int count )
    12.     {
    13.         if( dictToParse != null )
    14.         {
    15.             foreach( KeyValuePair< string, object > pair in dictToParse )
    16.             {
    17.                 if( pair.Value is Dictionary< string, object > ) {
    18.                     // Nested node
    19.                     ParseJSON( level + 1, pair.Value as Dictionary< string, object >, ref count );
    20.                 } else {
    21.                     // Item node
    22.                     count++;
    23.                     Debug.Log( "Level: " + level + ", Key: " + pair.Key + ", Value: " + pair.Value.ToString() );
    24.                 }
    25.             }
    26.         }
    27.     }
    28.  
    Regards
     
    TechDevTom likes this.
  22. Grhyll

    Grhyll

    Joined:
    Oct 15, 2012
    Posts:
    119
    Hello everybody,

    We have encountered some serious problems with MiniJSON (seems to be on iOS only) during last week with our released game, many users having their progress deleted randomly. After having spent too much time trying to find the repro, it appears that the problem comes from MiniJSON, apparently when the Unity setting "stripping level" is activated (any value except disabled) ; we have a perfectly good dictionary like:
    {"version":1,
    "1":{"en":"Welcome to our Game!",
    "fr":"Bienvenue !",}}
    Which usually gets well saved, but in some case when we serialize it (putting all the elements inside "1" in a dict, dict then put in a list) we obtain:
    [{"S":null,"y":null,"s":null,"t":null,"e":null,"m":null,".":null,"C":null,"o":null,"l":null,"l":null,"e":null,"c":null,"t":null,"i":null,"o":null,"n":null,"s":null,".":null,"G":null,"e":null,"n":null,"e":null,"r":null,"i":null,"c":null,".":null,"D":null,"i":null,"c":null,"t":null,"i":null,"o":null,"n":null,"a":null,"r":null,"y":null,"`":null,"2":null,"[":null,"S":null,"y":null,"s":null,"t":null,"e":null,"m":null,".":null,"S":null,"t":null,"r":null,"i":null,"n":null,"g":null,",":null,"S":null,"y":null,"s":null,"t":null,"e":null,"m":null,".":null,"O":null,"b":null,"j":null,"e":null,"c":null,"t":null,"]":null}]

    And for our player settings, which are serialized and then saved in PlayerPrefs, we have:
    {"S":null,"y":null,"s":null,"t":null,"e":null,"m":null,".":null,"C":null,"o":null,"l":null,"l":null,"e":null,"c":null,"t":null,"i":null,"o":null,"n":null,"s":null,".":null,"G":null,"e":null,"n":null,"e":null,"r":null,"i":null,"c":null,".":null,"D":null,"i":null,"c":null,"t":null,"i":null,"o":null,"n":null,"a":null,"r":null,"y":null,"`":null,"2":null,"[":null,"S":null,"y":null,"s":null,"t":null,"e":null,"m":null,".":null,"S":null,"t":null,"r":null,"i":null,"n":null,"g":null,",":null,"S":null,"y":null,"s":null,"t":null,"e":null,"m":null,".":null,"O":null,"b":null,"j":null,"e":null,"c":null,"t":null,"]":null}

    (For those who would wonder, it writes System.Collections.Generic.Dictionary`2[SYstem.String,System.Object].)

    Note: It could also come from the fact that "serialize" is sometimes used from a coroutine, we are not totally sure about the cause of the problem...

    Any idea how to fix it from MiniJSON code? We would like to keep "stripping level" enabled, and if possible it would be best to keep MiniJSON, as the version is already live, but we absolutely cannot keep that bug...



    EDIT: Well, it appears that the bug finally came from a log in which I tried to display the dict inside a Debug.Log (like Debug.Log("Dict: " + dictObject); )..... Nevermind my intervention...
     
    Last edited: May 31, 2013
  23. AShim-3D

    AShim-3D

    Joined:
    Jul 13, 2012
    Posts:
    34
  24. jptsetung

    jptsetung

    Joined:
    Jan 12, 2013
    Posts:
    51
    I needed to comment some of json files, I added the "#" comment support on minijson. Monodevelop seems to show everything after a # in orange as if it was comments. So with this fork, minijson ignored all what is shown in orange in monodevelop.

    [edit]All I had to do is to modify a little bit the EatWhiteSpace method.

    https://gist.github.com/jpsarda/7430545
     
  25. AbsoluteZero

    AbsoluteZero

    Joined:
    Sep 2, 2013
    Posts:
    19
    Hi,
    Any update if the above is still viable ?
    Thanks
     
  26. raj231

    raj231

    Joined:
    Nov 18, 2014
    Posts:
    46
  27. raj231

    raj231

    Joined:
    Nov 18, 2014
    Posts:
    46
    Can anyone tell me how can i get the url value from

    String modal3d=string.Format("modellinksArray: {0} ", modellinksArray["link"]);

    Debug.Log("modal Url load is "+ modal3d);

    I'm getting the log is modellinksArray: http://server.com/Unity/3dmodel/cat/cat.obj . I need to get only url without modellinksArray display.
     
    Last edited: Nov 18, 2014
  28. raj231

    raj231

    Joined:
    Nov 18, 2014
    Posts:
    46
    How to use where clause (Pass the parameter value) in MiniJSON?

    I have 2 array names called categories and products and i'm getting the values from products table but i want to pass the id value from categories to products using WHERE clause. But how can i use WHERE in MiniJSON?

    {"Categories":[{"id":"1","name":"Test1"},{"id":"2","name":"Test2"},}],
    "Products":
    [{"name":"Test2","category_id":"2","imageurl":"http://server.com/3DModel_images/Xpl.jpg"},
    {"name":"Test1","category_id":"1","imageurl":"http://server.com/3DModel_images/favicon.jpg"},]}


    IList linksObject = (IList) search["Products"]

    foreach (IDictionary ProductslinksArray in linksObject) {

    String modal3d=string.Format("{0} ", ProductslinksArray["imageurl"]);

    //Here i need to pass the id value from categories to products WHERE category_id=? (id value ) How can i use WHERE clause?

    }
     
  29. TechDevTom

    TechDevTom

    Joined:
    Oct 21, 2011
    Posts:
    33

    Just for other people's reference this works brilliantly, I was looking for a way to iterate through all of the returned results of a request sent back to me by using the FB.API call in Unity =D Thanks rsaenz!
     
  30. Dark-Table

    Dark-Table

    Joined:
    Nov 25, 2008
    Posts:
    315
    Hey Everybody,

    Today is the ten year anniversary of when I first posted the MiniJSON script to the Unity Forums!

    On this anniversary I have a special message:

    Stop using MiniJSON.

    SimpleJSON is faster (in initial parsing), more user friendly, and has been updated this year(!). Check it out: https://github.com/Bunny83/SimpleJSON

    For an even greater speed advantage (but adding substantial complexity), I'd check out Utf8JSON: https://github.com/neuecc/Utf8Json
     
    As_day likes this.