Search Unity

LitJSON issue on iOS

Discussion in 'iOS and tvOS' started by francksitbon, Nov 25, 2011.

  1. francksitbon

    francksitbon

    Joined:
    Jan 22, 2010
    Posts:
    268
    Hi I'm experiencing a bug on iOS, not present on the editor using LitJSON:

    Code (csharp):
    1. var data : JsonData = JsonMapper.ToObject (text);      
    2. var resultCount = data["resultCount"].ToString();   // Second use ERROR here   
    3.    
    First time works perfectly, second use, it crashes:

    System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.

    Help needed I'm really stuck on it
     
  2. francksitbon

    francksitbon

    Joined:
    Jan 22, 2010
    Posts:
    268
    Hi,
    I searched and found that JsonMapper is not compatible with IOS.
    I created my own functions to find the needed Values.
    first of all copy the LitJson.dll file from Paul Tondeur web site, (see links below) to your asset folder

    Code (csharp):
    1.  
    2.  
    3. import LitJson;
    4.  
    5. function GetVal (jsonString:String,property:String):String
    6. {
    7.     var reader : JsonReader = new JsonReader(jsonString);
    8.     while (reader.Read())
    9.     {
    10.    
    11.      if (reader.Token.ToString() == "PropertyName"  reader.Value.ToString() == property )
    12.      {
    13.         reader.Read();
    14.         if (reader.Token.ToString() == "Double" || reader.Token.ToString() == "Int" || reader.Token.ToString() == "String")
    15.             return reader.Value.ToString();
    16.      }
    17.     }
    18.  
    19. }
    20. function GetArray(jsonString:String,property:String):Array
    21. {
    22.     var array = new Array ();
    23.     array.Clear();
    24.     var reader : JsonReader = new JsonReader(jsonString);
    25.     while (reader.Read())
    26.     {
    27.      
    28.      if (reader.Token.ToString() == "PropertyName"  reader.Value.ToString() == property )
    29.      {
    30.         reader.Read();
    31.         if (reader.Token.ToString() == "ArrayStart")
    32.         {
    33.             while (reader.Token.ToString() != "ArrayEnd")
    34.             {
    35.                 reader.Read();
    36.                 if (reader.Token.ToString() == "Double" || reader.Token.ToString() == "Int" || reader.Token.ToString() == "String")
    37.                 {
    38.                     array.Push (reader.Value.ToString());
    39.                 }
    40.             }
    41.         }
    42.         return array;
    43.      }
    44.     }
    45. }
    46.  
    47.  
    48.  
    49.  


    And these could be used to find the needed values.

    Code (csharp):
    1.  
    2. var text : String;
    3. var resultCount = GetVal (text, "resultCount");
    4. Debug.Log (resultCount);
    5.  
    6. //and with an array or value :
    7.  
    8. var Screenshots = new Array ()
    9. Screenshots.Clear();
    10. Screenshots = GetArray (text, "screenshotUrls");
    11. for (var i =0; i< Screenshot.length; i++)
    12.     Debug.Log (Screenshot[i]);
    13.  
    14.  
    Hope it would help people stuck with this JsonMapper issue

    Thanks to people who shared, found the solution in this thread :

    http://answers.unity3d.com/questions/52199/how-to-implement-litjson.html

    and thanks to Paul Tondeur for sharing his LitJson.dll file and his tutorial :

    http://www.paultondeur.com/2010/03/...al-xml-and-json-files-with-unity-part-2-json/
     
    Last edited: Nov 27, 2011
  3. rushdi500

    rushdi500

    Joined:
    Jul 8, 2010
    Posts:
    10
    Hi francksitbon

    Thank you , you give me great help.
     
  4. francksitbon

    francksitbon

    Joined:
    Jan 22, 2010
    Posts:
    268
    You are welcome ! ;))))
     
  5. samurai413x

    samurai413x

    Joined:
    Apr 19, 2012
    Posts:
    5
    Hey,

    This thread has been really helpful so far, thank you!

    My only question: Am I correct in saying that the code you provided won't handle nested arrays in the JSON very well?

    Thanks again!
     
  6. StephanK

    StephanK

    Joined:
    Jul 10, 2012
    Posts:
    47
    Did you ever figure out why it doesn't work on ios? I am having the exact same problem, but I'd really like to use the JsonMapper and I can't find why it shouldn't work on ios as it doesn't do anything that would be forbidden on ios.
     
  7. StephanK

    StephanK

    Joined:
    Jul 10, 2012
    Posts:
    47
    Just as update. If using the ToObject<T> method in C# and providing a Type for the mapper to map the data to it seems to work also on ios.
     
  8. Deleted User

    Deleted User

    Guest

  9. SSL90

    SSL90

    Joined:
    Mar 19, 2013
    Posts:
    3
    response to : if using toObject<T> and naming a Type

    could you elaborate on this with an example please:)
     
    Last edited: Jul 1, 2013
  10. StephanK

    StephanK

    Joined:
    Jul 10, 2012
    Posts:
    47
    There seem to be two ways to use this library. The first one uses the ToObject() method and will create a hierachy of JsonData objects that represent the original json using untyped Dictionaries Lists and arrays. The second approach allows you to use the generic ToObject<T> method. To use this you would do something like the following:

    public class MyDataObject {
    public string name;
    public int number;
    }

    with that class you could then do the following:

    MyData myData = new MyData();
    string json = JsonMapper.ToJson(myData);
    MyData anotherMyData = JsonMapper.ToObject<MyData>(json);

    This would serialize the object to a json string and then deserialize it to a new object. This works with any kind of data, so if you get some data as a respnse from a server you would just create a class containing the respective fields and then you can use the ToObject<T> method to create an object of that type from a json string.
     
  11. SSL90

    SSL90

    Joined:
    Mar 19, 2013
    Posts:
    3
    thank you for the reply.. unfortunately I'm still stuck:(
    Do i still need to implement the francksitbon code if I only want to write the file to an array and just display the text. (json contains all text).


    public string[] jsonTeamsSelected = new string[];
    public string[] jsonDefSelected = new string[];

    void ExtractTeams(string json)
    {

    JsonData jsonTeams = JsonMapper.ToObject(json);

    Debug.Log(jsonTeams["teams"].Count);
    jsonSetcount = jsonTeams["teams"].Count;

    for (int j = 0; j < jsonSetcount; j++){

    jsonTeamsSelected[j] = jsonTerms["teams"][j]["team"].ToString();
    jsonDefSelected[j] = jsonTerms["teams"][j]["defend"].ToString();

    }
     
  12. hirenkacha

    hirenkacha

    Joined:
    Apr 4, 2012
    Posts:
    10
    I am also trying to parse json on iOS, but cant find it working

    Code (csharp):
    1. JsonData jd = JsonMapper.ToObject(www.data.ToString());
    2. net_amt=jd["totals"][0]["net_amt"].ToString();
    3.                 net_gr=jd["totals"][0]["net_gr"].ToString();
    4.                 net_amt_gr=jd["totals"][0]["net_amt_gr"].ToString();
    5.                 net_vatav=jd["totals"][0]["net_vatav"].ToString();
    6.                 net_total=jd["totals"][0]["net_total"].ToString();
     
  13. StephanK

    StephanK

    Joined:
    Jul 10, 2012
    Posts:
    47
    You are trying to use the non-generic version of ToObject which also doesn't work for me. If you use the generic one it works.
     
  14. hirenkacha

    hirenkacha

    Joined:
    Apr 4, 2012
    Posts:
    10
    I Got it working with same code. There was an issue of multiple callbacks.. Solved.
     
  15. Takafumi

    Takafumi

    Joined:
    Aug 8, 2013
    Posts:
    2
    Hello, could you elaborate on this?
    I'm having a similar problem. Not the exception, but the result of non-generic ToObject() is corrupt :(
    Thank you!
     
  16. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    I think what he meant was calling ToObject<T>() instead of just ToObject. What is it you're trying to serialize / deserialize?
     
  17. Takafumi

    Takafumi

    Joined:
    Aug 8, 2013
    Posts:
    2
    Oh, I misunderstood.
    But I debugged the problem and now LitJson works fine on my iOS, with non-generic ToObject(). The problem was in line 532 of JsonMapper.cs.

    Code (csharp):
    1.                     ((IDictionary) instance)[property] = ReadValue (
    2.                         factory, reader);
    This makes ReadValue() called again and again before assignment and consume all the members of currently parsing object. I suppose this is an AOT compiler bug or something, but don't know exactly. Anyway separating call to ReadValue() and assignment and prevent optimizer from merging them again fixed the problem.

    In my case the problem was not an exception, but corrupt resulting data, so I don't know if this workaround will save everyone having similar issues.
     
  18. poolts

    poolts

    Joined:
    Aug 9, 2012
    Posts:
    113
    Could you include the code snippet you used to fix this?
     
  19. cecker

    cecker

    Joined:
    Feb 10, 2014
    Posts:
    2
    As a UnityScript user I couldn't figure out, what to change in JsonMapper.cs. Could you include the code snippet you used to fix this, Takafumi?

    Thank you a lot StephanK! Your solution saved me.
    According to StephanK LitJson should be used like this in UnityScript:

    JSONData = LitJson.JsonMapper.ToObject.<LitJson.JsonData>(JSONText);

    instead of

    JSONData = LitJson.JsonMapper.ToObject(JSONText);