Diego
Diego

Reputation: 371

Unity works in Editor not on device. Loading remote JSON storing locally then populating dropdown

So I'm loading in a remote json file, storing it locally then reading the local file to populate a list which is ultimately inserted into an onscreen dropdown. I tried all sorts of things, using litjson and had errors handling, using application.various paths.

Anyway, I got it all working eventually but only in the editor, I popped a text box on the screen called Debug to load text onscreen, it should show contents of the file and it does in the editor but not on my android device.

I changed all the folder routes to move and load everything to the resources folder as I read that could be an issue.

Changed the code to writer instead of litjson writealltext() and after all that I have the same result.

It works in unity but not on the device, it's as if the populateList() function isn't firing or something.

I'm stuck. Help appreciated.

Heres the code :

using UnityEngine;
using System.Collections;
using LitJson;
using System;
using System.IO;
using System.Collections.Generic;
using UnityEngine.UI;

public class loadJSONFoodCats : MonoBehaviour {

    public string url;
    private string jsonString;
    private JsonData itemData;
    public List<Category> myListCats = new List<Category>();
    private List<string> catTags = new List<string>();

    public Dropdown typeFilter;

void Start (){
      WWW www2 = new WWW(url);
      StartCoroutine(WaitForRequest(www2));
}

IEnumerator WaitForRequest(WWW www2){
  yield return www2;

  // check for errors
  if (www2.error == null)
  {
    //SAVE JSON FROM ONLINE LOCALLY
        jsonString = www2.text;
        string path = "Assets/Resources/JSON/FoodnDrinkCats.json";
        string str = jsonString;
         using (FileStream fs = new FileStream(path, FileMode.Create)){
             using (StreamWriter writer = new StreamWriter(fs)){
                 writer.Write(str);
             }
         }

       // Debug.Log("PASSED");

    //READ SAVED FILE
        TextAsset file = Resources.Load("JSON/FoodnDrinkCats") as TextAsset;

    jsonString = file.ToString();
    itemData = JsonMapper.ToObject(jsonString);

    //SORT DATA OUT
        ConstructCatsDatabase();
        //Debug.Log(myList[0].post_title);

        //Category cat = fetchItemByID(255);
        //listing.post_title;
        //Debug.Log(cat.Slug);
        Text singleText = GameObject.Find("Debug").GetComponent<Text>();
        singleText.text = "LOADING:"+myListCats[0].Name;

        populateList();

      } else {
      Debug.Log("WWW Error: "+ www2.error);
      }    
  }

    void ConstructCatsDatabase(){

        for (int i = 0; i < itemData.Count; i++) {
            myListCats.Add(new Category((int)itemData[i][0], itemData[i][1].ToString(), itemData[i][2].ToString()));
        }

  }

    public Category fetchItemByID(int id){

        for (int i = 0; i < myListCats.Count; i++) {
            if(myListCats[i].Term_ID == id){
                return myListCats[i];
            }

        }
        return null;
 }


    void populateList(){
        for (int i = 0; i < myListCats.Count; i++) {
            //TRANSLATION DONE, NOW ADD THEM
            catTags.Add(myListCats[i].Name);

            Text singleText = GameObject.Find("Debug").GetComponent<Text>();
            singleText.text = "info:"+myListCats[i].Name;
        }
        catTags.Sort();
        typeFilter.AddOptions(catTags);



    }



}




public class Category {

    public int Term_ID {get; set;}
    public string Name {get; set;}
    public string Slug {get; set;}

    public Category(int id, string name, string slug){

        this.Term_ID = id;
        this.Name = name;
        this.Slug = slug;

    }

}

Upvotes: 0

Views: 880

Answers (3)

Diego
Diego

Reputation: 371

Here's the solution.

This code will manage the file system on various platforms. Write read and path management. So far for me it works perfectly. It came from a unity forum by a guy named FAEZ.

public void writeStringToFile( string str, string filename )
{
#if !WEB_BUILD
string path = pathForDocumentsFile( filename );
FileStream file = new FileStream (path, FileMode.Create, FileAccess.Write);

StreamWriter sw = new StreamWriter( file );
sw.WriteLine( str );

sw.Close();
file.Close();
#endif  
}


public string readStringFromFile( string filename)//, int lineIndex )
{
#if !WEB_BUILD
string path = pathForDocumentsFile( filename );

if (File.Exists(path))
{
FileStream file = new FileStream (path, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader( file );

string str = null;
str = sr.ReadLine ();

sr.Close();
file.Close();

return str;
}

else
{
return null;
}
#else
return null;
#endif 
}


public string pathForDocumentsFile( string filename ) 
{ 
if (Application.platform == RuntimePlatform.IPhonePlayer)
{
string path = Application.dataPath.Substring( 0, Application.dataPath.Length - 5 );
    path = path.Substring( 0, path.LastIndexOf( '/' ) );
    return Path.Combine( Path.Combine( path, "Documents" ), filename );
}

else if(Application.platform == RuntimePlatform.Android)
{
string path = Application.persistentDataPath;   
path = path.Substring(0, path.LastIndexOf( '/' ) ); 
return Path.Combine (path, filename);
}   

else 
{
string path = Application.dataPath; 
path = path.Substring(0, path.LastIndexOf( '/' ) );
    return Path.Combine (path, filename);
    }
}

Upvotes: 0

In you can't write so easily to the FileSystem. There is something called isolated storage there.

Use instead Application.persistentDataPath as path for JSON. It's recommended from Unity3D and works on all platforms.


Also make sure your manifest file for Android contains: (located in Assets/Plugins/Android)

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Check build configuration in Android for the write access:

enter image description here

Upvotes: 1

Zohaib Javed
Zohaib Javed

Reputation: 343

For writing on different platform use Application.persistentDataPath

So your path in code will become for writing like that :

string path = Application.persistentDataPath + "FoodnDrinkCats.json";

Upvotes: 0

Related Questions