使用NewtonSoft插件,用插件里面的Deserialize方法进行json的反序列化,unity导出的程序在WebGL正常运行,但是在安卓出现报错Unable to find a constructor,按照 网上的说法将每个要解析的类添加一个空构造函数,然后试了好像还是不行,然后搜了一会,再给其中一个空构造函数上面添加[Preserve]属性,这个属性是UnityEngine里面的UnityEngine.Scripting命名空间里面的,然后打包之后就可以正常反序列化了,猜测对一个空构造方法方法加了这个属性之后 所有的空构造方法都会保留 如果一个空构造方法都没加这个属性 就会报错。
但是在ios端,要求比安卓会更加严格一点,单纯按照安卓的做法去做的话,能进行json反序列化成对象但是反序列化出来的对象里面的值都是默认值,这个的解决方案是每个反序列化的类定义的时候都要再添加一个带参构造函数,需要反序列化的值都在构造函数的形参里面写好,然后在构造函数内将形参与对象变量进行一一赋值,在这个带参构造函数的定义上一行也需要添加[Preserve]属性,然后还有一点是在ios开发环境中oc的id是个关键字,如果传过来的json里面有个字段的key值是id,在解析之前将小写的id替换称为大写的ID,在定义的反序列化的类里面将id对应的属性改成ID。
每个定义的对象里面不仅需要由[Preserve]声明修饰的带参构造函数,还需要由[Preserve]声明修饰的空构造函数,不然在安卓的反序列化会出错
最后定义好的能在ios进行Newtonsoft Deseriialize进行解析的类如下所示
public class HallShopData
public string unitId { get; set; }
public int type { get; set; }
public string imgUrl { get; set; }
public string name { get; set; }
public string signImgUrl { get; set; }
public string signImgOffsetX { get; set; }
public string signImgOffsetY { get; set; }
public string signImgTilingX { get; set; }
public string signImgTilingY { get; set; }
public string videoCover { get; set; }
public string videoUrl { get; set; }
public List<SingleItemData> unitItemList { get; set; }
public List<SingleProductData> unitProductList { get; set; }
public HallShopRelativeData unitInfo { get; set; }
[Preserve]
public HallShopData()
[Preserve]
public HallShopData(string unitId, int type, string imgUrl,
string name, string signImgUrl, string signImgOffsetX,
string signImgOffsetY, string signImgTilingX, string signImgTilingY,
string videoCover, string videoUrl, List<SingleItemData> unitItemList,
List<SingleProductData> unitProductList, HallShopRelativeData unitInfo)
this.unitId = unitId;
this.type = type;
this.imgUrl = imgUrl;
this.name = name;
this.signImgUrl = signImgUrl;
this.signImgOffsetX = signImgOffsetX;
this.signImgOffsetY = signImgOffsetY;
this.signImgTilingX = signImgTilingX;
this.signImgTilingY = signImgTilingY;
this.videoCover = videoCover;
this.videoUrl = videoUrl;
this.unitItemList = unitItemList;
this.unitProductList = unitProductList;
this.unitInfo = unitInfo;
public virtual string GetPlaceID()
if (unitInfo != null && unitInfo.unitTag != null &&
unitInfo.unitTag != string.Empty)
return unitInfo.unitTag;
Debug.LogError(" HallShopServerLoadAndInitData GetPlaceID return -1 ");
return Const.negativeOneStr;
如果json要解析出来的类是继承了另外一个解析类的话, 可以这样写:
public class PermanentHallShopData : HallShopData
public int ID { get; set; }
public override string GetPlaceID()
if (ID > Const.zeroInt)
return ID.ToString("000");
Debug.LogError(" HallShopServerLoadAndInitData GetPlaceID return -1 " +
"because id is invalid, id value " + ID);
return Const.negativeOneStr;
[Preserve]
public PermanentHallShopData(int id, string unitId, int type, string imgUrl,
string name, string signImgUrl, string signImgOffsetX,
string signImgOffsetY, string signImgTilingX, string signImgTilingY,
string videoCover, string videoUrl, List<SingleItemData> unitItemList,
List<SingleProductData> unitProductList,
HallShopRelativeData unitInfo) : base(unitId, type, imgUrl,
name, signImgUrl, signImgOffsetX,
signImgOffsetY, signImgTilingX, signImgTilingY,
videoCover, videoUrl, unitItemList,
unitProductList, unitInfo)
this.ID = id;
[Preserve]
public PermanentHallShopData()
PermanentHallShopData 继承自HallShopData这个类,这样写可以保证 Newtonsoft在ios进行反序列化的时候PermanentHallShopData类型的对象能生成
如果要解析的类有嵌套的话也是可以的
public class ExhibitionSeatInfo
public int pageNum { get; set; }
public int pageSize { get; set; }
public int totalPage { get; set; }
public int total { get; set; }
public List<ExhibitionPerSeatInfo> rows { get; set; }
[Preserve]
public ExhibitionSeatInfo()
[Preserve]
public ExhibitionSeatInfo(int pageNum, int pageSize,
int totalPage, int total,
List<ExhibitionPerSeatInfo> rows)
this.pageNum = pageNum;
this.pageSize = pageSize;
this.totalPage = totalPage;
this.total = total;
this.rows = rows;
public class ExhibitionPerSeatInfo
public int area { get; set; }
public string areaTag { get; set; }
public string categoryId { get; set; }
public string categoryName { get; set; }
public string categoryNameUs { get; set; }
public int collectNum { get; set; }
public string exhibitionId { get; set; }
public string hallTag { get; set; }
public int hotNum { get; set; }
[JsonProperty(PropertyName = "id")]
public string ID { get; set; }
public string logicTag { get; set; }
public string putSellerId { get; set; }
public int roomType { get; set; }
public string turnover { get; set; }
public string unitTag { get; set; }
public override string ToString()
string str = "ExhibitionPerSeatInfo ID " + ID;
return str;
[Preserve]
public ExhibitionPerSeatInfo()
[Preserve]
public ExhibitionPerSeatInfo(int area, string areaTag, string categoryId,
string categoryName, string categoryNameUs, int collectNum,
string exhibitionId, string hallTag, int hotNum,
string id, string logicTag, string putSellerId,
int roomType, string turnover, string unitTag )
this.area = area;
this.areaTag = areaTag;
this.categoryId = categoryId;
this.categoryName = categoryName;
this.categoryNameUs = categoryNameUs;
this.collectNum = collectNum;
this.exhibitionId = exhibitionId;
this.hallTag = hallTag;
this.hotNum = hotNum;
this.ID = id;
this.logicTag = logicTag;
this.putSellerId = putSellerId;
this.roomType = roomType;
this.turnover = turnover;
this.unitTag = unitTag;
Json解析类ExhibitionPerSeatInfo里面有个变量rows是另外一个解析类ExhibitionPerSeatInfo,只要这两个解析类都按照规范写,在ios上面的解析就没有问题,注意构造函数里面某个要解析的字段不要写漏了,写漏了,ios解析的话这个值是空的
这种方法可能会显得有点繁琐,可以尝试下文中,去掉getset声明的方法
Unity Newtonsoft插件在ios无法序列化出json的问题 以及反序列化的问题
C#开发Android/ios项目时用到的Newtonsoft.Json.dll组件(4.5.11.1),android项目引用lib/android文件里的,ios项目引用lib/ios文件夹里的。
可解决Release模式下生成报版本错误的问题!
Newtonsoft是使用量最多的json插件,我在unity引用了这个插件,在ios端将对象序列化成json的时候出问题了,
我们一开始在网上的学习资料或者其他地方找到定义json解析类的时候,每个变量都会添加{get; set;}字段变成属性块
但是这种写法在ios序列化的时候会导致序列化失败,之前自己找了很久也没找到问题,这里就记录一下
这是改之前的代码:
public class SearchConditionInfo
public string areaTag { get; set;
近段时间在做Unity客户端与python服务器之间的网络通信,由于不同语言之间的类型封装不同,不建议直接收发自定义的协议类型字节序列,而是使用json字符串序列进行过渡。
python提供了json模块进行序列化和反序列化,只需要掌握loads操作和dumps操作即可,使用十分简单。
而C#也可以使用Newtonsoft的动态链接库进行json的序列化和反序列化,下面阐述一下使用的注意事项。
链接:https://pan.baidu.com/s/1kM2euOyT-ivXFJixXkQJSA
在 Unity 中,我们可以使用 JsonUtility 类来实现对象的序列化和反序列化。对于 Dictionary 类型的对象,我们可以通过将其转换为一个包含键值对的 List 类型对象,然后对 List 类型对象进行序列化和反序列化。
下面是一个示例代码:
```csharp
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver
[SerializeField]
private List<TKey> keys = new List<TKey>();
[SerializeField]
private List<TValue> values = new List<TValue>();
// save the dictionary to lists
public void OnBeforeSerialize()
keys.Clear();
values.Clear();
foreach (KeyValuePair<TKey, TValue> pair in this)
keys.Add(pair.Key);
values.Add(pair.Value);
// load dictionary from lists
public void OnAfterDeserialize()
this.Clear();
for (int i = 0; i < keys.Count; i++)
this.Add(keys[i], values[i]);
[System.Serializable]
public class MyData
public SerializableDictionary<string, int> myDict = new SerializableDictionary<string, int>();
public static class JsonHelper
public static string ToJson<T>(T obj)
return JsonUtility.ToJson(obj);
public static T FromJson<T>(string json)
return JsonUtility.FromJson<T>(json);
public class Example : MonoBehaviour
private MyData data = new MyData();
private void Start()
data.myDict.Add("key1", 1);
data.myDict.Add("key2", 2);
string json = JsonHelper.ToJson(data);
Debug.Log(json);
MyData loadedData = JsonHelper.FromJson<MyData>(json);
Debug.Log(loadedData.myDict["key1"]);
Debug.Log(loadedData.myDict["key2"]);
在上面的示例代码中,我们定义了一个 SerializableDictionary 类来实现 Dictionary 的序列化和反序列化。在 MyData 类中使用了 SerializableDictionary 类型的成员变量 myDict。在 JsonHelper 类中,我们定义了 ToJson 和 FromJson 方法来将对象转换为 Json 字符串和从 Json 字符串中加载对象。在 Example 类中,我们创建了一个 MyData 对象,并向其中添加了两个键值对。我们将 MyData 对象转换为 Json 字符串并输出到控制台,然后从 Json 字符串中加载了一个新的对象,并输出了其中的两个值。