在 IOS 中保存和加载 XML 文件会在我的 Unity 项目中产生问题

Posted

技术标签:

【中文标题】在 IOS 中保存和加载 XML 文件会在我的 Unity 项目中产生问题【英文标题】:Saving and Loading XML File in IOS creates Problem In My Unity Project 【发布时间】:2020-06-15 17:45:51 【问题描述】:

我正在使用 Unity3d 并使用 2019.3.3 编辑器构建游戏。

我在 ios 版本中遇到问题。

我正在 android 设备上尝试我的游戏,它运行良好,但是昨天我在 IOS 设备上尝试了我的游戏,但在 IOS 上保存和加载 xml 文件时遇到了问题。

我正在使用此代码进行保存:

SaveAvatar() 

XmlSerializer serializer = new XmlSerializer(typeof(AvatarData));        
FileStream stream = new FileStream(Application.persistentDataPath + "avatar_data.xml", FileMode.Create);        
serializer.Serialize(stream, avatarData);        
stream.Close();

我正在使用此代码进行加载:

LoadAvatar() 
XmlSerializer serializer = new XmlSerializer(typeof(AvatarData));        
FileStream stream = new FileStream(Application.persistentDataPath + "avatar_data.xml", FileMode.Open);        
avatarData = (AvatarData)serializer.Deserialize(stream);        
stream.Close();


Also in OnEnable function I create my xml file if it does not exists: Without this code, it is not saving the game in editor or android as well.

OnEnable ()  
if (!File.Exists(Application.persistentDataPath + "avatar_data.xml"))                    avatarData.jobID = 10000;
            
SaveAvatar();        

即使序列化一个只包含一个 int 的类,这些代码在 IOS 中也不起作用。 (我尝试保存另一个类,看看我的主要保存类是否有问题)

我的保存类包含以下变量类型:

字符串、整数、枚举、浮点数、列表、其他类和自类变量

这是我班级的示例变量:(所有类型变量的示例)

[System.Serializable]
public class AvatarData 
   
public bool dead;

public string avatarName; 
      
public int age;   
    
public float health;

public AvatarData father; (Self Class variable) 

public EnumGender gender; (Enum)
        
public JobClass job; (Another Class variable)

public List<GroupClass> groups; (Another Class List variable) 
   
public List<AvatarData> children; (Self Class List variable) 
   
public List<PetClass> pets;    
public List<LogClass> logs;    
public List<JobClass> Jobs;    
public List<EventClass> tempEvents;    
public List<ItemsClass> myItems;

当我使用 SaveAvatar 或 LoadAvatar 函数时,在 IOS 中,它会出现错误,并且代码不会继续更进一步的行。没有保存它工作正常。

谁能告诉我我的代码有什么问题

谢谢

【问题讨论】:

永远不要对系统路径使用简单的字符串连接!而是使用Path.Combine,它根据操作系统使用正确的路径分隔符。请注意,尤其是没有分隔符的Application.persistentDataPath + "avatar_data.xml" 毫无意义,因为这将是Application.persistentDataPath 文件夹外部 的文件!而是将其替换为Path.Combine(Application.persistentDataPath, "avatar_data.xml")。它在 Android 上运行的原因可能是不那么严格的文件访问规则.. 当我遇到这样的反序列化 xml 问题时,我会做以下两件事之一: 1) 在 c# 中注释掉属性和类,直到我运行代码以确定哪些属性导致问题。 2)用样本数据创建一个类,然后序列化。然后将序列化 xml 与您正在阅读的进行比较以查看差异。 @jdweng 我已经打开并清空项目并创建了一个带有一个 int 变量的新类。 @derHugo 我已经打开并清空了项目并创建了一个带有一个 int 变量的新类。我还添加了 path.combine 但仍然没有保存在 iOS 中。感谢您的回复 @derHugo if (!File.Exists(Path.Combine(Application.persistentDataPath + "player_data.xml"))) SavePlayerData(); public void SavePlayerData() XmlSerializer 序列化器 = new XmlSerializer(typeof(PlayerData)); FileStream 流 = new FileStream(Path.Combine(Application.persistentDataPath + "player_data.xml"), FileMode.Create);序列化器。序列化(流,播放器数据);流。关闭(); [System.Serializable] public class PlayerData public int number; 【参考方案1】:

如cmets中所说:

从不对系统路径使用简单的字符串连接!

特别要注意

Application.persistentDataPath + "avatar_data.xml" 

没有任何分隔符是没有意义的,因为这将是

之外的文件
Application.persistentDataPath

文件夹,因为它会导致类似

/rootfolder/applicationfolderavatar_data.xml

您需要在它们之间使用\/,例如

/rootfolder/applicationfolder/avatar_data.xml

它在 Android 上运行的原因可能是文件访问规则不那么严格,因此您可以在应用程序文件夹之外写入文件,在 iOs afaik 中,默认情况下您被严格沙盒到应用程序文件夹。


所以宁可使用Path.Combine,它根据运行的操作系统使用正确的路径分隔符

Path.Combine(Application.persistentDataPath, "avatar_data.xml")

【讨论】:

以上是关于在 IOS 中保存和加载 XML 文件会在我的 Unity 项目中产生问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在文档中下载和保存 xml,然后如何从文档中解析 xml 文件?

从 xml 加载关卡并在 Ios 中支持屏幕分辨率

NSUserDefault 无法在 iOS8 的扩展中保存和加载

Unity3D 从 XML 文件保存和加载数据不起作用

SVM 分类器没有保存在“.xml”中?

在保存()之后在我的 XML 文件的开头获取“” [重复]