LoginSignup
1
2

More than 3 years have passed since last update.

Unity で REST API を呼ぶ (そして Json を parse して Class に変換する)

Last updated at Posted at 2020-06-28

注意

UniRx 周りの理解が甘いので、変なこと書いてるかもです。
https://www.hanachiru-blog.com/entry/2020/02/29/120000
現在この辺りを読みながら勉強中なので、何かわかれば追記、修正します。

やること

https://xxxxx.com/xxxxx にアクセスすると下記のような Json を返す API を、

{
    "items": [
        {
            "user_name": "post",
            "points": {
                "of_distance": 5,
                "of_coin": 5
            },
            "total_point": 10,
            "timestamp": 1592761117
        },
        {
            "user_name": "post",
            "points": {
                "of_distance": 5,
                "of_coin": 5
            },
            "total_point": 10,
            "timestamp": 1592761117
        }
    ]
}

Unity から呼び出して、 同じ構造を持った Class へ Deserialize, Parse する。

ライブラリのインポート

UniRx

Unity で非同期処理のタイミング調整(?)が行えるライブラリ。
async/await が使えるようになる。

書き方によっては使わなくても良さそう。

導入方法

AssetStore から一式インポート

unirx.png

Newtonsoft.Json

Json の Deserialize, Parse をいい感じにやってくれる。

導入方法

この方法で NuGet を import して、 NuGet の機能で Newtonsoft.Json を取得。

nuget.png

すると、 Assets/Packages/Newtonsoft.Json.12.0.3 が取得できる。

実装

通信を行うクラス

UnityWebRequest を使って json を取得して、JsonConvert.DeserializeObject を使って Deserialize, Parse を行う。

using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using System.Collections.Generic;
using Newtonsoft.Json;

public class HttpSample
{
    public string url;
    public Scores scores { get; private set; }

    public IEnumerator Get(System.IObserver<Scores> observer)
    {
        UnityWebRequest req = UnityWebRequest.Get(url);
        yield return req.SendWebRequest();
        if (req.isNetworkError)
        {
            Debug.Log(req.error);
        }
        else if (req.isHttpError)
        {
            Debug.Log(req.error);
        }
        else
        {
            // json が返る
            string result = req.downloadHandler.text;
            // Scores 型に変換
            this.scores = JsonConvert.DeserializeObject<Scores>();
            observer.OnNext(scores);
            observer.OnCompleted();
        }
    }

    // クラスに `[JsonObject("xxxxx")]` ,
    // クラスプロパティに `[JsonProperty("xxxxx")]` をつけると、
    // json parse 時のフォーマットを変更できる
    [JsonObject("scores")]
    public class Scores {
        [JsonProperty("items")]
        public List<Score> items;
        [JsonObject("score")]
        public class Score
        {
            [JsonProperty("user_name")]
            public string user_name;
            [JsonProperty("points")]
            public Points points;
            [JsonProperty("total_point")]
            public int total_point;
            [JsonProperty("timestamp")]
            public int timestamp;

            [JsonObject("points")]
            public class Points
            {
                [JsonProperty("of_distance")]
                public int of_distance;
                [JsonProperty("of_coin")]
                public int of_coin;
            }
        }
    }
}

呼び出すクラス

async/await を使って同期的に結果を取得し、取得したクラスを使っていく。

using UnityEngine;
using UniRx;

public class ScoresController : MonoBehaviour
{
    // UniRx を入れると async が書ける
    async void Start()
    {
        HttpSample scoreHttp = new HttpSample("https://xxxxxxxxxxxxxxx.com/api");
     // await を使うことで、結果を同期的に扱える。
        HttpSample.Scores result = await Observable.FromCoroutine<HttpSample.Scores>(observer => scoreHttp.Get(observer));
        Debug.Log(result)
    }
}
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2