C# / Unity 学んだこと #4

# Unity

## HTTPリクエスト

- UnityEngine.WWWというHTTPリクエストを簡便に行うためのクラスが用意されている
- WWWはCustomYieldInstruction(はIEnumeratorを継承)を継承しているので、yieldの返り値として使える

```csharp
public class MainController : MonoBehaviour
{

    const string PhotozouUrl = "https://api.photozou.jp/rest/search_public.json?keyword=うさぎ";

    bool isLoading = false;

    // Use this for initialization
    void Start()
    {
        StartCoroutine(LoadPhotozouPublic());
    }

    // Update is called once per frame
    void Update()
    {
    }


    IEnumerator LoadPhotozouPublic()
    {
        if (isLoading)
        {
            yield break;
        }

        isLoading = true;

        var www = new WWW(PhotozouUrl);
        yield return www;
        var resp = PhotozouResponse.FromJson(www.text);
        Debug.Log(resp.info.photo_num);

        foreach (var photo in resp.info.photo)
        {
            Debug.Log(photo.image_url);
        }

        isLoading = false;
    }
}
```

- とまぁ非常に便利に使えることがわかった

## JSONデシリアライズ

- UnityEngine.JsonUtilityというクラスを利用する(先程のソースコードで既に利用済み)
- よくあるデシリアライザーなのだが、なんとなくJavaのそれよりもスッキリしているような(例えばMoshi)
- フォト蔵のjsonと対応するレスポンスクラスは次のように書ける

```csharp
/// <summary>
/**
{
  "info": {
    "photo_num": ###,
    "photo": [
      {
        "photo_id": ###,
        "user_id": ###,
        "album_id": ###,
        "photo_title": "タイトル",
        "favorite_num": ###,
        "comment_num": ###,
        "view_num": ###,
        "copyright": "normal/creativecommons",
        "copyright_commercial": "yes/no"
        "copyright_modifications": "yes/no/share"
        "original_height": ##,
        "original_width": ###,
        "geo": {
            "latitude": ###,
            "longitude": ###
        },
        "date": "YYYY-MM-DD",
        "regist_time": "YYYY-MM-DDThh:mm:ss+09:00",
        "url": "URL",
        "image_url": "URL",
        "original_image_url": "URL",
        "thumbnail_image_url": "URL",
        "large_tag": "<a href=\"...\">...</a>",
        "medium_tag": "<a href=\"...\">...</a>"
      },
      ...
    ]
  }
}
 */
/// </summary>

[System.Serializable]
struct PhotozouResponse
{
    public PhotozouInfo info;

    public static PhotozouResponse FromJson(string text)
    {
        return JsonUtility.FromJson<PhotozouResponse>(text);
    }
}

[System.Serializable]
struct PhotozouInfo
{
    public int photo_num;
    public Photo[] photo;
}

[System.Serializable]
struct Photo
{
    public int photo_id;
    public int user_id;
    public int album_id;
    public string photo_title;
    public int favorite_num;
    public int comment_num;
    public int view_num;
    public string copyright;
    public string copyright_commercial;
    public string copyright_modifications;
    public int original_height;
    public int original_width;
    public Geo geo;
    public string date;
    public string regist_time;
    public string url;
    public string image_url;
    public string original_image_url;
    public string thumbnail_image_url;
    public string large_tag;
    public string medium_tag;
}

[System.Serializable]
struct Geo
{
    public double latitude;
    public double longitude;
}
```

- 後はこれを、JsonUtility.FromJson<PhotozouResponse>(text)などとすれば簡単にレスポンスが手に入る