1

I have prepared xml files with some content and want to load it while playing on iOS device but also I want to change loaded data and serialize it in the same file again. In Unity Editor (Windows) it works perfectly, but when I test it on iOS device it seems that I can read from StreamingAssets using WWW class, but I can't write into it. Also I have found that I can read and write into path created by Application.persistentDataPath. But it seems that location somewhere in device and I can't put my xml into that location and users have access to that folder so that isn't good solution, isn't it?

Here code that I use to load and save the data.

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using System.Xml;

public class testxml : MonoBehaviour {

public Text result;
public InputField firstPart, secondPart;
public Toggle toggle;

private List<int> listToSave;

// Use this for initialization
void Start () {
    listToSave = new List<int>();
}

public void Save()
{
    Serialize();
}

public void Load()
{
    StartCoroutine(Deserialize());
}

private void Serialize()
{
    string path = GetPath();
    try
    {
        Debug.Log("trying to save");

        var serializer = new XmlSerializer(typeof(List<int>));
        using (var fs = new FileStream(path, FileMode.OpenOrCreate))
        {
            serializer.Serialize(fs, listToSave);
        }
    }
    catch (XmlException e)
    {
        result.text = "error";
        Debug.LogError(path + "  with " + (toggle.isOn ? "persistent data path" : "data path"));
        Debug.LogError("xml exc while des file : " + e.Message);
    }
    catch (System.Exception e)
    {
        result.text = "error";
        Debug.LogError("exc while des file : " + e.Message);
        Debug.LogError(path + "  with " + (toggle.isOn ? "persistent data path" : "data path"));
        System.Exception exc = e.InnerException;
        int i = 0;
        while (exc != null)
        {
            Debug.Log("inner " + i + ": " + exc.Message);
            i++;
            exc = exc.InnerException;
        }
    }
}

private IEnumerator Deserialize()
{
    Debug.Log("trying to load");
    string path = GetPath();
    var www = new WWW(path);
    yield return www;
    if (www.isDone && string.IsNullOrEmpty(www.error))
    {
        try
        {
            var serializer = new XmlSerializer(typeof(List<int>));
            MemoryStream ms = new MemoryStream(www.bytes);
            listToSave = serializer.Deserialize(ms) as List<int>;
            ms.Close();
            result.text += "Done\n";
            foreach (var i in listToSave)
                result.text += i + "\n";
        }
        catch (XmlException e)
        {
            result.text = "error";
            Debug.LogError(path + "  with " + (toggle.isOn?"persistent data path":"data path"));
            Debug.LogError("xml exc while des file : " + e.Message);
        }
        catch (System.Exception e)
        {
            result.text = "error";
            Debug.LogError("exc while des file : " + e.Message);
            Debug.LogError(path + "  with " + (toggle.isOn ? "persistent data path" : "data path"));
            System.Exception exc = e.InnerException;
            int i = 0;
            while(exc!=null)
            {
                Debug.Log("inner "+i+": " + exc.Message);
                i++;
                exc = exc.InnerException;
            }
        }

        yield break;
    }
    else
    {
        Debug.LogError("www exc while des file " + www.error);
        Debug.LogError(path + "  with " + (toggle.isOn ? "persistent data path" : "data path"));
        yield break;
    }
}

private string GetPath()
{
    string path = firstPart.text;
    if (toggle.isOn)
    {
        path += Application.persistentDataPath;
    }
    else
        path += Application.dataPath;
    path += secondPart.text;
    return path;
}
}
user2686299
  • 427
  • 8
  • 25
  • you're sure you're using http://stackoverflow.com/a/36236745/294884 at all times right? – Fattie May 13 '16 at 19:03
  • so i have to use Application.persistentDataPath all the time? but where that folder is? – user2686299 May 13 '16 at 19:19
  • you must only use Application.persistentDataPath ever. (It is extremely confusing that Unity documentation ever *mentions* anything else.) You can not know "where it is", it is decided each time. If you mean, on your Mac or PC, you want to look in the folder (to check something), simply add this code anywhere `Debug.Log(Application.persistentDataPath);` and you'll see it. Hope it helps. – Fattie May 13 '16 at 19:27
  • yeah, i have something like /var/mobile/Containers/Data/Application/419FA6FF-1ACC-452E-A54F-4470FDA0F2E2/Documents but i can't find this folder – user2686299 May 13 '16 at 19:32
  • Do you mean on Android? Right ***you are not allowed to see it***. That's how phones work. (Maybe if you jailbreak you can see it.) – Fattie May 13 '16 at 19:33
  • i mean IPhone. But I want to put my xml file in this folder, and then read it. It's like default info for game – user2686299 May 13 '16 at 19:36

1 Answers1

2

"I want to put my xml file in this folder, and then read it. It's like default info for game"

easy, just put it in your assets. go like this...

 public TextAsset myXMLFile;

in Inspector drag the file there. You're done.


"but then I also want to change that file and save"

Fair enough. What you have to do is

(1) make a path p = Application.persistentDataPath + "values.txt"

(2) program launches.

(3) check if "p" exists. if yes, read it and go to (6)

(4) IF NOT, read the textasset and save that to "p"

(5) go to point (3)

(6) you're done.

It's the only way to do it. This is indeed the normal procedure in Unity, you do it in every Unity app. There's no other way!

Fattie
  • 27,874
  • 70
  • 431
  • 719