Search Unity

jsonUtility.FromJson<>(www.text) return null? my script problem?

Discussion in 'Scripting' started by ctchan7, Jan 13, 2019.

  1. ctchan7

    ctchan7

    Joined:
    Jan 13, 2019
    Posts:
    12
  2. ctchan7

    ctchan7

    Joined:
    Jan 13, 2019
    Posts:
    12
    Code here


    Code (CSharp):
    1. IEnumerator WaitForRequest(WWW www)
    2.     {
    3.         yield return www;
    4.  
    5.      
    6.         // check for errors
    7.         if (www.error== null)
    8.         {
    9.             Debug.Log("WWW ok!" + www.text);   // www.text replace www.data
    10.             Debug.Log("==END==");
    11.         } else
    12.         {
    13.             Debug.Log("WWW Error:" + www.error);
    14.         }
    15.  
    16.         ListCotainer container = JsonUtility.FromJson<ListCotainer>(www.text);
    17.  
    18.  
    19. public struct ListCotainer
    20. {
    21.  
    22.     public List<HospitalData> dataList;
    23.     public string lastupdateTime;
    24.  
    25.     public ListCotainer(List<HospitalData> _dataList, string _lastupdateTime)
    26.     {
    27.         dataList = _dataList;
    28.         lastupdateTime = _lastupdateTime;
    29.     }
    30. }
    31.  
    32.  
    33. [Serializable]
    34. public struct HospitalData
    35. {
    36.     public string Hname;
    37.     public string WaitTime;
    38.  
    39.     public HospitalData(string _Hname, string _WaitTime)
    40.     {
    41.         Hname = _Hname;
    42.         WaitTime = _WaitTime;
    43.     }
    44.  
    45. }
    46.  
    47.  
    48.         Debug.Log("container =" + container.dataList.Count);
    49.         Debug.Log("www.text length ="+www.text.Length);
    50. }
    51.  
     
    Last edited: Jan 13, 2019
  3. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Mark the ListContainer as [System.Serializable] and try outputting actual test from the www.text.

    Maybe that will shed some light on what's going on.

    Also, I think it's neccessary to provide exact key name to the class as in json file.
    E.g. Hname must be renamed to hospName.
     
  4. ctchan7

    ctchan7

    Joined:
    Jan 13, 2019
    Posts:
    12
    thank you for xVergilx reply... i change the code as follow ...but jsonutility.FromJson<> still return nul....www.text receive the correct string...but... only cannot read the data inside

    u may try to copy it and attached to a gameObject....i try many ways... for 3-4 days


    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using System;
    6.  
    7. public class Json_D : MonoBehaviour
    8. {
    9.     private string targetURL;
    10.     private string target2URL;
    11.  
    12.     void Start () {
    13.  
    14.    
    15.         targetURL = "http://www.ha.org.hk/opendata/aed/aedwtdata-tc.json";
    16.          WWW www = new WWW(targetURL);
    17.          StartCoroutine(WaitForRequest(www));
    18.       }
    19.  
    20.     IEnumerator WaitForRequest(WWW www)
    21.     {
    22.         yield return www;
    23.    
    24.         // check for errors
    25.         if (www.error== null)
    26.         {
    27.             Debug.Log("WWW ok!" + www.text);   // www.text replace www.data
    28.             Debug.Log("==END==");
    29.         } else
    30.         {
    31.             Debug.Log("WWW Error:" + www.error);
    32.         }
    33.  
    34.         ListCotainer container = JsonUtility.FromJson<ListCotainer>(www.text);
    35.         Debug.Log("container =" + container.dataList.Count);
    36.         Debug.Log("www.text length ="+www.text.Length);
    37.    
    38.     }
    39.  
    40.     // Update is called once per frame
    41.     void Update () {
    42.              
    43.     }
    44. }
    45.  
    46. [Serializable]
    47. public struct ListCotainer
    48. {
    49.  
    50.     public List<waitTime> dataList;
    51.     public string lastupdateTime;
    52.  
    53.     public ListCotainer(List<waitTime> _dataList, string _lastupdateTime)
    54.     {
    55.         dataList = _dataList;
    56.         lastupdateTime = _lastupdateTime;
    57.     }
    58. }
    59.  
    60. [Serializable]
    61. public struct waitTime
    62. {
    63.     public string hospName;
    64.     public string topWait;
    65.  
    66.     public waitTime(string _hospName, string _topWait)
    67.     {
    68.         hospName = _hospName;
    69.         topWait = _topWait;
    70.     }
    71.  
    72. }
    73.  
     
    Last edited: Jan 13, 2019
  5. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
  6. ctchan7

    ctchan7

    Joined:
    Jan 13, 2019
    Posts:
    12
    Thank SparrowsNest.. Just test your suggestion .. But cannot make it..

    Anyone want to take this challenge?
     
  7. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    You need to set variable names to be exact.

    Here's what seems to be working:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System;
    5.  
    6. public class Json_D : MonoBehaviour {
    7.    private string targetURL;
    8.    private string target2URL;
    9.  
    10.    private void Start() {
    11.       targetURL = "http://www.ha.org.hk/opendata/aed/aedwtdata-tc.json";
    12.       WWW www = new WWW(targetURL);
    13.       StartCoroutine(WaitForRequest(www));
    14.    }
    15.  
    16.    IEnumerator WaitForRequest(WWW www) {
    17.       yield return www;
    18.  
    19.       // check for errors
    20.       if (www.error == null) {
    21.          Debug.Log("WWW ok!" + www.text); // www.text replace www.data
    22.          Debug.Log("==END==");
    23.       } else {
    24.          Debug.Log("WWW Error:" + www.error);
    25.       }
    26.  
    27.       ListContainer container = JsonUtility.FromJson<ListContainer>(www.text);
    28.       Debug.Log(container.updateTime);
    29.       Debug.Log("container =" + container.waitTime.Count);
    30.       Debug.Log("www.text length =" + www.text.Length);
    31.    }
    32. }
    33.  
    34. [Serializable]
    35. public class ListContainer {
    36.    public List<WaitTime> waitTime = new List<WaitTime>();
    37.    public string updateTime;
    38. }
    39.  
    40. [Serializable]
    41. public struct WaitTime {
    42.    public string hospName;
    43.    public string topWait;
    44. }
    upload_2019-1-13_19-18-10.png
     
  8. ctchan7

    ctchan7

    Joined:
    Jan 13, 2019
    Posts:
    12
    Thanks xVergilx ... you're genius! And you save my life

    it also work on my project now.
    besides, you fix my confused concept on class / struct and the way of declaiming them...
    and my last question is...why the variable should be exact? is it the rule of dealing with Json data!
     
  9. doctorpangloss

    doctorpangloss

    Joined:
    Feb 20, 2013
    Posts:
    270
    Yes!
     
    ctchan7 likes this.
  10. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Serializer doesn't know what data is passed as text. Classes / struct's variables give serializer idea on how the data should be deserialized.

    So unless variables declared as is from the data, it won't be deserialized properly.
     
    ctchan7 likes this.
  11. ctchan7

    ctchan7

    Joined:
    Jan 13, 2019
    Posts:
    12
    Need help again!! xVergilx

    I accidentally update my Unity to 2018.3.1f1 Pesonal and it seem not allow me to use www to get URL file...
    then I rewrite the code as follow:

    The strange thing is... it work perfectly when I press play and show on the unity program, but when i output to Andriod... nothing help and no update.. it seem that the mobile cannot read the URL....before upgrade my unity... my mobile can read the URL...thus... can xVergilx or other people can help ..and



    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System;
    5. using UnityEngine.UI;
    6. using UnityEngine.Networking;
    7.  
    8. public class Json_D : MonoBehaviour
    9. {
    10.     public GameObject updateTime01Obj;
    11.     public GameObject Time01Obj;
    12.     public GameObject Time02Obj;
    13.     public GameObject Time03Obj;
    14.     public GameObject Time04Obj;
    15.  
    16.     private string targetURL;
    17.     private string target2URL;
    18.  
    19.     private void Start()
    20.     {
    21.         targetURL = "http://www.ha.org.hk/opendata/aed/aedwtdata-tc.json";
    22.          UnityWebRequest www = UnityWebRequest.Get(targetURL);
    23.         StartCoroutine(WaitForRequest(www));
    24.     }
    25.  
    26.     IEnumerator WaitForRequest(UnityWebRequest www)
    27.     {
    28.         yield return www.SendWebRequest();
    29.  
    30.         // check for errors
    31.         if (www.error == null)
    32.         {
    33.             Debug.Log("WWW ok!" + www.downloadHandler.text); // www.text replace www.data
    34.             Debug.Log("==END==");
    35.         }
    36.         else
    37.         {
    38.             Debug.Log("WWW Error:" + www.error);
    39.         }
    40.  
    41.         ListContainer container = JsonUtility.FromJson<ListContainer>(www.downloadHandler.text);
    42.         Debug.Log(container.updateTime);
    43.         Debug.Log("container =" + container.waitTime.Count);
    44.         Debug.Log("www.text length =" + www.downloadHandler.text.Length);
    45.         Debug.Log("1st =" + container.waitTime[0].hospName);
    46.         // [1] ming oi
    47.         Time01Obj.GetComponent<Text>().text = container.waitTime[1].topWait;
    48.  
    49.         // [2] kwong wah
    50.         Time02Obj.GetComponent<Text>().text = container.waitTime[2].topWait;
    51.  
    52.         // [9] yee li
    53.         Time03Obj.GetComponent<Text>().text = container.waitTime[9].topWait;
    54.  
    55.         // [16] chrisian
    56.         Time04Obj.GetComponent<Text>().text = container.waitTime[16].topWait;
    57.  
    58.         updateTime01Obj.GetComponent<Text>().text = "update: " + container.updateTime;
    59.     }
    60. }
    61.  
    62. [Serializable]
    63. public class ListContainer
    64. {
    65.     public List<WaitTime> waitTime = new List<WaitTime>();
    66.     public string updateTime;
    67. }
    68.  
    69. [Serializable]
    70. public struct WaitTime
    71. {
    72.     public string hospName;
    73.     public string topWait;
    74. }
     
  12. ctchan7

    ctchan7

    Joined:
    Jan 13, 2019
    Posts:
    12
    Here ... my Unity setting... any problem that may affect the output apk?
     

    Attached Files:

  13. ctchan7

    ctchan7

    Joined:
    Jan 13, 2019
    Posts:
    12
    extra information.. there are 3 red alert.... appear after output the apk... related to my problem?
     

    Attached Files:

  14. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Errors seems to be unrelated to this script.

    Set timeout to something like 10 / 15 seconds (default is infinity) and try outputting the following on the device:
    Code (CSharp):
    1. www.timeout = 10;
    2.  
    3. yield return ...
    4.  
    5. if (www.isNetworkError || www.isHttpError)
    6. {
    7.     Debug.Log(www.error);
    8. }
    9. else
    10. {
    11.     Debug.Log(www.downloadHandler.text);
    12. }
    Instead of:
    Code (CSharp):
    1. // check for errors
    2.         if (www.error == null)
    3.         {
    4.             Debug.Log("WWW ok!" + www.downloadHandler.text); // www.text replace www.data
    5.             Debug.Log("==END==");
    6.         }
    7.         else
    8.         {
    9.             Debug.Log("WWW Error:" + www.error);
    10.         }
    Check what it outputs. It might be that request fails for some reason.
    To check the output, you can use Unity's console (Connect to the device after you Build & Run), or Monitor from Android tools. (set the filter tag:Unity).
     
  15. ctchan7

    ctchan7

    Joined:
    Jan 13, 2019
    Posts:
    12
    Thanks xVergilx!
    I rewrite the code as you recommend... and it turn out the error show "unknown error"
    i just use UI text to display www.error... and don't know how to use monitor from andriod tools...

    Latest checking: it is unknow error .. and know isNetworkError and responseCode is 200
    hope it help to find out the problem.../ test to install in HTC .. also have the same response/problem

    if it is my case, what i can do next? it is my mobile problem? (my mobile is Xiaomi Redmi Note 4)

    Anyone could write a simple code that using UnityWebRequest to read this json file and can run smoothly on Android.. and let me test my mobile again? quite confuse this moment... Many thanks!
     
    Last edited: Jan 16, 2019
  16. ctchan7

    ctchan7

    Joined:
    Jan 13, 2019
    Posts:
    12
  17. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    I'd suggest testing on different device. Just in case.

    Also, make sure your application has neccessary permissions, and you can actually access that web page.
    (E.g. test it from the browser, maybe your local ISP preventing the access to it).

    Nothing else I can suggest.
     
    ctchan7 likes this.
  18. ctchan7

    ctchan7

    Joined:
    Jan 13, 2019
    Posts:
    12
    Thanks xVergilx . .I install the earlier version instead.. But it turn out that some api have problem. .Need to rewrite again ..Thanks again anyway!