【Unity】JsonUtilityでルート配列のデシリアライズ
概要
APIのレスポンスが↓こんな感じで返ってくることないでしょうか?
[ { "id": 123, "project_id": 234, }, { "id": 456, "project_id": 567, }, { "id": 789, "project_id": 890, }, ... ]
しかしUnityのJson周りで JsonUtility
を使用している場合
ルートが配列になってしまっている↑のようなJsonはデシリアライズ出来ないです。
これの解決法として自分は以下の2通りで対応しました。
- 配列にも対応できるようにそれ用の機能を作る。
- 使う側で工夫する
実装
今回はより簡単な「使う側で工夫する」方法で話していきたいと思います。
まず以下のようなクラスを追加します。
/// <summary> /// レスポンスで返ってきている配列の1要素 /// </summary> [Serializable] public class Hoge { ... } /// <summary> /// レスポンスで返ってきている配列の1要素 /// </summary> [Serializable] public class ResponceData { public Hoge[] root; }
あとは、レスポンス受け取り部分で以下のような感じに 'json' を編集してあげれば大丈夫です。
※ ここでは例として 'UnityWebRequest' を使用しています。(responce変数)
var data = new ResponceData(); json = "{" + $"\"root\": {responce.downloadHandler.text}" + "}"; JsonUtility.FromJsonOverwrite(json, data);
※ 文字列補完が使えないC#のバージョンでは, string.Formatなどを代わりに使ってください。
もうちょっとだけ使いやすくする為に
以下のようなものを作っておくと同じ対応を行う時
少し便利に使えるようになると思います。
[Serializable] public abstract class ResponceData<T> { public T[] root; } public static void DeserializeArray<T>(T target, string json) where T : ResponceData<T> { string _json = "{" + $"\"root\": {json}" + "}"; JsonUtility.FromJsonOverwrite(_json, data); }
実際に使う際は
// 宣言しておく (Unity2019から要らない予定). [Serializable]public class HogeData : ResponceData<Hoge>{} [SerializeField] HogeData DeserializeArray(data, responce.downloadHandler.text);