「Unity/Csharp/Request」の版間の差分

提供: 初心者エンジニアの簡易メモ
ナビゲーションに移動 検索に移動
編集の要約なし
 
(同じ利用者による、間の31版が非表示)
1行目: 1行目:
==Httpリクエストサンプル==
==Httpリクエストサンプル==
以下delegateを使ったhttpリクエストサンプルコード
以下delegateを使ったhttpリクエストサンプルコード
-WebHttpRequest.cs
*WebHttpRequest.cs
<pre>
<pre>
using System.Collections;
using System.Collections;
using System.Threading;
using UnityEngine;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking;
public class WebHttpRequest : MonoBehaviour {
public class WebHttpRequest : MonoBehaviour {
     string text = "";
     string text = "";
    private int retry = 10;
     public bool errorFlag = false;
     public bool errorFlag = false;
    private int timeout = 2;
    // 現在のretry回数
    private int retryNum = 0;
    UnityWebRequest request;
    SynchronizationContext context;
    WWWForm paramPostForm;
     public enum ResponseType
     public enum ResponseType
     {
     {
         Success,
         Success,
         Faild,
         Failure,
         NetworkError
         NetworkError
     }
     }
     public delegate void CustomCallback(ResponseType responseType);
     public delegate void CustomCallback(ResponseType responseType);
     private CustomCallback callbacks;
     private CustomCallback callbacks;
     public void addCallback(CustomCallback callback)
     public void AddCallback(CustomCallback callback)
     {
     {
         callbacks += callback;
         callbacks += callback;
     }
     }
     public void Exec (string url) {
    public void Init() {
        Debug.Log ("WebHttpRequest.Init()");
        paramPostForm = new WWWForm ();
    }
    public void setTimeout(int sec) {
        timeout = sec;
    }
    public void setRetry(int tmpRetry)
    {
        retry = tmpRetry;
    }
    public int getRetryNum() {
        return retryNum;
    }
     public void Exec(string url) {
         text = "";
         text = "";
         errorFlag = false;
         errorFlag = false;
         StartCoroutine(Get (url));
        context = SynchronizationContext.Current; // メインスレッドでcontextを設置
         StartCoroutine(Get(url));
     }
     }
     public IEnumerator Get (string url) {
     IEnumerator Get(string url) {
         var request = new UnityWebRequest();
         request = new UnityWebRequest();
         request.downloadHandler = new DownloadHandlerBuffer();
         request.downloadHandler = new DownloadHandlerBuffer();
         request.url = url;
         request.url = url;
         request.SetRequestHeader("Content-Type", "application/json; charset=UTF-8");
         request.SetRequestHeader("Content-Type", "application/json; charset=UTF-8");
         request.method = UnityWebRequest.kHttpVerbGET;
         request.method = UnityWebRequest.kHttpVerbGET;
        request.timeout = timeout;
        Debug.Log ("WebHttpRequest Get timeout=" + timeout);
         yield return request.Send();
         yield return request.Send();
        retryNum = 0;
         if (request.isNetworkError) {
         if (request.isNetworkError) {
             errorFlag = true;
             Debug.Log("request.isNetworkError request.error=" + request.error);
             callbacks(ResponseType.NetworkError);
            if (request.error.Equals ("Request timeout")) {
                retryNum++;
                if (retryNum < retry) {
                    Debug.Log ("WebHttpRequest Get timeout " + request.error + " retryNum = "+retryNum);
                    yield return Get(url);
                } else {
                    errorFlag = true;
                    // メインスレッドへ戻す
                    context.Post(d =>
                    {
                        if (callbacks != null)
                        {
                            callbacks(ResponseType.NetworkError);
                        }
                    }, null);
                }
             } else {
                Debug.Log ("WebHttpRequest Get request.error=" + request.error);
                errorFlag = true;
                // メインスレッドへ戻す
                context.Post(d =>
                {
                    if (callbacks != null)
                    {
                        callbacks(ResponseType.NetworkError);
                    }
                }, null);
            }
         } else {
         } else {
             if (request.responseCode == 200) {
             if (request.responseCode == 200) {
                Debug.Log ("WebHttpRequest Get success request.responseCode=" + request.responseCode);
                 text = request.downloadHandler.text;
                 text = request.downloadHandler.text;
                 callbacks(ResponseType.Success);
                 Debug.Log("WebHttpRequest Get text=" + text);
                // メインスレッドへ戻す
                context.Post(d =>
                {
                    if (callbacks != null)
                    {
                        callbacks(ResponseType.Success);
                    }
                }, null);
             } else {
             } else {
                 errorFlag = true;
                 errorFlag = true;
                 callbacks(ResponseType.Faild);
                 Debug.Log ("WebHttpRequest Get failed" + request.responseCode);
                // メインスレッドへ戻す
                context.Post(d =>
                {
                    if (callbacks != null)
                    {
                        callbacks(ResponseType.Failure);
                    }
                }, null);
             }
             }
         }
         }
  }
    }
  public string GetBody() {
    public void ExecPost(string url) {
      return text;
        text = "";
  }
        errorFlag = false;
  public void Reset() {
        context = SynchronizationContext.Current; // メインスレッドでcontextを設置
      text = "";
        StartCoroutine(Post(url));
      errorFlag = false;
    }
  }
    public void ParamPost(string key, string value) {
        paramPostForm.AddField(key, value);
    }
    IEnumerator Post(string url) {
        request = UnityWebRequest.Post(url, paramPostForm);
        request.downloadHandler = new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json; charset=UTF-8");
        request.method = UnityWebRequest.kHttpVerbPOST;
        request.timeout = timeout;
        Debug.Log ("WebHttpRequest Post timeout=" + timeout);
        yield return request.Send();
        retryNum = 0;
        if (request.isNetworkError) {
            Debug.Log("WebHttpRequest Post " + request.error);
            if (request.error.Equals ("Request timeout")) {
                retryNum++;
                if (retryNum < retry) {
                    Debug.Log ("WebHttpRequest Post " + request.error + " retryNum= "+retryNum);
                    yield return Post(url);
                } else {
                    errorFlag = true;
                    // メインスレッドへ戻す
                    context.Post(d =>
                    {
                        if (callbacks != null)
                        {
                            callbacks(ResponseType.NetworkError);
                        }
                    }, null);
                }
            } else {
                Debug.Log ("WebHttpRequest Post " + request.error);
                errorFlag = true;
                // メインスレッドへ戻す
                context.Post(d =>
                {
                    if (callbacks != null)
                    {
                        callbacks(ResponseType.NetworkError);
                    }
                }, null);
            }
        } else {
            if (request.responseCode == 200) {
                Debug.Log ("WebHttpRequest Post success" + request.responseCode);
                text = request.downloadHandler.text;
                Debug.Log("WebHttpRequest Post " + text);
                // メインスレッドへ戻す
                context.Post(d =>
                {
                    if (callbacks != null)
                    {
                        callbacks(ResponseType.Success);
                    }
                }, null);
            } else {
                errorFlag = true;
                Debug.Log ("WebHttpRequest Post failed request.responseCode=" + request.responseCode);
                // メインスレッドへ戻す
                context.Post(d =>
                {
                    if (callbacks != null)
                    {
                        callbacks(ResponseType.Failure);
                    }
                }, null);
            }
        }
    }
    public string GetBody() {
        return text;
    }
    public void Reset() {
        text = "";
        errorFlag = false;
        paramPostForm = new WWWForm();
    }
    public string GetError()
    {
        if (request != null && request.error != null)
        {
            return request.error;
        }
        return "";
    }
}
}
</pre>
</pre>


呼び出し元
呼び出し元
-NewBehaviourScript.cs
*NewBehaviourScript.cs
<pre>
<pre>
public class NewBehaviourScript : MonoBehaviour {
public class NewBehaviourScript : MonoBehaviour {
70行目: 225行目:
         GameObject gameObj = new GameObject();
         GameObject gameObj = new GameObject();
         request = gameObj.AddComponent<WebHttpRequest>();
         request = gameObj.AddComponent<WebHttpRequest>();
        request.AddCallback(OnResponse);
         request.Exec(url);
         request.Exec(url);
        request.addCallback(OnResponse);
         Debug.Log("request=" + url);
         Debug.Log("request=" + url);
     }
     }
77行目: 232行目:
     public void OnResponse(WebHttpRequest.ResponseType responseType)
     public void OnResponse(WebHttpRequest.ResponseType responseType)
     {
     {
         Debug.Log("onResponse=" + responseType);
         Debug.Log("OnResponse=" + responseType);
         if (request)
         if (request)
         {
         {
83行目: 238行目:
             {
             {
             Debug.Log("body=" + request.GetBody());
             Debug.Log("body=" + request.GetBody());
             } else if (responseType.Equals(WebHttpRequest.ResponseType.Faild)) {
             } else if (responseType.Equals(WebHttpRequest.ResponseType.Failure)) {
                 Debug.Log("errorFlag=" + request.errorFlag);
                 Debug.Log("errorFlag=" + request.errorFlag);
if (!request.GetError().Equals(""))
{
Debug.Log(request.GetError()); // 例:huawei android端末(SSL CA certificate error
}
             }
             }
             else if (responseType.Equals(WebHttpRequest.ResponseType.NetworkError))
             else if (responseType.Equals(WebHttpRequest.ResponseType.NetworkError))
             {
             {
                 Debug.Log("NetworkError" + request.errorFlag);
                 Debug.Log("NetworkError" + request.errorFlag);
if (!request.GetError().Equals(""))
{
Debug.Log(request.GetError()); // 例:huawei android端末(SSL CA certificate error
}
             }
             }
             request.Reset();
             request.Reset();
96行目: 259行目:
</pre>
</pre>


==Httpリクエストサンプル(これはDelegateを使ってないダメな例)==
==http通信許可==
using System.Collections;
 
using System.Collections.Generic;
===android===
using UnityEngine;
android9でhttp通信ができなくなってる。
using UnityEngine.UI;
 
using System.Collections;
取り急ぎhttp通信を対応したい場合
using UnityEngine.Networking;
AndroidManifest.xmlのapplicationに以下属性追加
  public class WebHttpRequest : MonoBehaviour {
  android:usesCleartextTraffic="true"
    string text = "";
 
    public bool errorFlag = false;
https://ameblo.jp/znky/entry-12459683348.html
    public void Exec (string url) {
 
      text = "";
===ios===
      errorFlag = false;
 
      StartCoroutine(Get (url));
#unity/build setting/ios/other setting/Configuration
    }
#Allow downloads over HTTPをチェック
    public IEnumerator Get (string url) {
#Supported URL schemesのSizeに1を入れ、許可するドメイン"project1.example.net"などを入れる
      var request = new UnityWebRequest();
 
      request.downloadHandler = new DownloadHandlerBuffer();
チェックをつけると以下警告が出る
      request.url = url;
You are using download over http. Currently Unity adds NSAllowsArbitraryLoads to Info.plist to simplify transition, but it will be removed soon. Please consider updating to https.
       request.SetRequestHeader("Content-Type", "application/json; charset=UTF-8");
 
       request.method = UnityWebRequest.kHttpVerbGET;
====それでも、http通信時、以下が出る時====
       yield return request.Send();
The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
       if (request.isError) {
 
        Debug.Log(request.error);
Info.plistへ以下を追加
       } else {
<pre>
        if (request.responseCode == 200) {
    <key>NSAppTransportSecurity</key>
           text = request.downloadHandler.text;
    <dict>
           Debug.Log(request.downloadHandler.text);
       <key>NSAllowsArbitraryLoads</key>
        }
       <true />
       }
       <key>NSAllowsArbitraryLoadsInWebContent</key>
    }
       <true />
    public string GetBody() {
      <key>NSExceptionDomains</key>
        return text;
       <dict>
    }
           <key>project1.example.net</key>
    public void Reset() {
           <dict>
        text = "";
              <key>NSIncludesSubdomains</key>
        errorFlag = false;
              <true />
    }
              <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
}
              <true />
          </dict>
       </dict>
</pre>
project1.example.netは適宜変更
 
参考:https://clevertap.com/blog/developing-for-ios9-app-transport-security/
 
=====補足=====
unityのiosの設定のAllow downloads over HTTPの下にあるSizeに1を入力しSchemaに、接続するドメイン(project1.example.netなど)を追加しても、以下が追加されるだけで、NSExceptionDomainsではないので、機能しない。


呼び出し側
<pre>
const string uri = "ttp://hogehoge.com/api?param1=";
    <key>CFBundleURLTypes</key>
string param1 = "value1";
    <array>
param1 = WWW.EscapeURL (param1);
      <dict>
string url = uri + param1;
        <key>CFBundleURLName</key>
GameObject gameObj = new GameObject();
        <string></string>
WebHttpRequest request = gameObj.AddComponent<WebHttpRequest>();
        <key>CFBundleURLSchemes</key>
request.Exec (url);
        <array>
          <string>project1.example.net</string>
        </array>
      </dict>
    </array>
</pre>


呼び出し側で受信チェック
====iosで、"Malformed URL"エラーになるとき====
void Update ()
エラー詳細
  {
  WebHttpRequest Get request.error=Malformed URL
    if (request) {
たとえば、urlが
        if (!request.GetBody ().Equals ("")) {
ttps://example.com/unityapi/statusread?uids[]=1515&uids[]=1130
              // 処理
のように、パラメータに"[]"を含むとurl形式エラーとなるみたい。"[]"を"%5B%5D"でエンコードしてあげると、うまくいく。
              request.Reset ();
        } else if (request.errorFlag) {
              request.errorFlag = false;
        }
    }
}

2026年3月24日 (火) 01:29時点における最新版

Httpリクエストサンプル

以下delegateを使ったhttpリクエストサンプルコード

  • WebHttpRequest.cs
using System.Collections;
using System.Threading;
using UnityEngine;
using UnityEngine.Networking;

public class WebHttpRequest : MonoBehaviour {
    string text = "";
    private int retry = 10;
    public bool errorFlag = false;
    private int timeout = 2;
    // 現在のretry回数
    private int retryNum = 0;
    UnityWebRequest request;
    SynchronizationContext context;
    WWWForm paramPostForm;
    public enum ResponseType
    {
        Success,
        Failure,
        NetworkError
    }
    public delegate void CustomCallback(ResponseType responseType);
    private CustomCallback callbacks;
    public void AddCallback(CustomCallback callback)
    {
        callbacks += callback;
    }
    public void Init() {
        Debug.Log ("WebHttpRequest.Init()");
        paramPostForm = new WWWForm ();
    }
    public void setTimeout(int sec) {
        timeout = sec;
    }
    public void setRetry(int tmpRetry)
    {
        retry = tmpRetry;
    }
    public int getRetryNum() {
        return retryNum;
    }
    public void Exec(string url) {
        text = "";
        errorFlag = false;
        context = SynchronizationContext.Current; // メインスレッドでcontextを設置
        StartCoroutine(Get(url));
    }
    IEnumerator Get(string url) {
        request = new UnityWebRequest();
        request.downloadHandler = new DownloadHandlerBuffer();
        request.url = url;
        request.SetRequestHeader("Content-Type", "application/json; charset=UTF-8");
        request.method = UnityWebRequest.kHttpVerbGET;
        request.timeout = timeout;
        Debug.Log ("WebHttpRequest Get timeout=" + timeout);
        yield return request.Send();
        retryNum = 0;
        if (request.isNetworkError) {
            Debug.Log("request.isNetworkError request.error=" + request.error);
            if (request.error.Equals ("Request timeout")) {
                retryNum++;
                if (retryNum < retry) {
                    Debug.Log ("WebHttpRequest Get timeout " + request.error + " retryNum = "+retryNum);
                    yield return Get(url);
                } else {
                    errorFlag = true;
                    // メインスレッドへ戻す
                    context.Post(d =>
                    {
                        if (callbacks != null)
                        {
                            callbacks(ResponseType.NetworkError);
                        }
                    }, null);
                }
            } else {
                Debug.Log ("WebHttpRequest Get request.error=" + request.error);
                errorFlag = true;
                // メインスレッドへ戻す
                context.Post(d =>
                {
                    if (callbacks != null)
                    {
                        callbacks(ResponseType.NetworkError);
                    }
                }, null);
            }
        } else {
            if (request.responseCode == 200) {
                Debug.Log ("WebHttpRequest Get success request.responseCode=" + request.responseCode);
                text = request.downloadHandler.text;
                Debug.Log("WebHttpRequest Get text=" + text);
                // メインスレッドへ戻す
                context.Post(d =>
                {
                    if (callbacks != null)
                    {
                        callbacks(ResponseType.Success);
                    }
                }, null);
            } else {
                errorFlag = true;
                Debug.Log ("WebHttpRequest Get failed" + request.responseCode);
                // メインスレッドへ戻す
                context.Post(d =>
                {
                    if (callbacks != null)
                    {
                        callbacks(ResponseType.Failure);
                    }
                }, null);
            }
        }
    }
    public void ExecPost(string url) {
        text = "";
        errorFlag = false;
        context = SynchronizationContext.Current; // メインスレッドでcontextを設置
        StartCoroutine(Post(url));
    }
    public void ParamPost(string key, string value) {
        paramPostForm.AddField(key, value);
    }
    IEnumerator Post(string url) {
        request = UnityWebRequest.Post(url, paramPostForm);
        request.downloadHandler = new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json; charset=UTF-8");
        request.method = UnityWebRequest.kHttpVerbPOST;
        request.timeout = timeout;
        Debug.Log ("WebHttpRequest Post timeout=" + timeout);
        yield return request.Send();
        retryNum = 0;
        if (request.isNetworkError) {
            Debug.Log("WebHttpRequest Post " + request.error);
            if (request.error.Equals ("Request timeout")) {
                retryNum++;
                if (retryNum < retry) {
                    Debug.Log ("WebHttpRequest Post " + request.error + " retryNum= "+retryNum);
                    yield return Post(url);
                } else {
                    errorFlag = true;
                    // メインスレッドへ戻す
                    context.Post(d =>
                    {
                        if (callbacks != null)
                        {
                            callbacks(ResponseType.NetworkError);
                        }
                    }, null);
                }
            } else {
                Debug.Log ("WebHttpRequest Post " + request.error);
                errorFlag = true;
                // メインスレッドへ戻す
                context.Post(d =>
                {
                    if (callbacks != null)
                    {
                        callbacks(ResponseType.NetworkError);
                    }
                }, null);
            }
        } else {
            if (request.responseCode == 200) {
                Debug.Log ("WebHttpRequest Post success" + request.responseCode);
                text = request.downloadHandler.text;
                Debug.Log("WebHttpRequest Post " + text);
                // メインスレッドへ戻す
                context.Post(d =>
                {
                    if (callbacks != null)
                    {
                        callbacks(ResponseType.Success);
                    }
                }, null);
            } else {
                errorFlag = true;
                Debug.Log ("WebHttpRequest Post failed request.responseCode=" + request.responseCode);
                // メインスレッドへ戻す
                context.Post(d =>
                {
                    if (callbacks != null)
                    {
                        callbacks(ResponseType.Failure);
                    }
                }, null);
            }
        }
    }
    public string GetBody() {
        return text;
    }
    public void Reset() {
        text = "";
        errorFlag = false;
        paramPostForm = new WWWForm();
    }
    public string GetError()
    {
        if (request != null && request.error != null)
        {
            return request.error;
        }
        return "";
    }
}

呼び出し元

  • NewBehaviourScript.cs
public class NewBehaviourScript : MonoBehaviour {
    WebHttpRequest request;
    // http送信
    void Start () {
        const string uri = "http://raw.githubusercontent.com/nlohmann/json/develop/test/data/json.org/1.json";
        string param1 = "value1";
        param1 = WWW.EscapeURL(param1);
        string query = "?hoge=" + param1;
        string url = uri + query;
        GameObject gameObj = new GameObject();
        request = gameObj.AddComponent<WebHttpRequest>();
        request.AddCallback(OnResponse);
        request.Exec(url);
        Debug.Log("request=" + url);
    }
    // httpのresponse受信
    public void OnResponse(WebHttpRequest.ResponseType responseType)
    {
        Debug.Log("OnResponse=" + responseType);
        if (request)
        {
            if (responseType.Equals(WebHttpRequest.ResponseType.Success))
            {
            Debug.Log("body=" + request.GetBody());
            } else if (responseType.Equals(WebHttpRequest.ResponseType.Failure)) {
                Debug.Log("errorFlag=" + request.errorFlag);
		if (!request.GetError().Equals(""))
		{
			Debug.Log(request.GetError()); // 例:huawei android端末(SSL CA certificate error
		}
            }
            else if (responseType.Equals(WebHttpRequest.ResponseType.NetworkError))
            {
                Debug.Log("NetworkError" + request.errorFlag);
		if (!request.GetError().Equals(""))
		{
			Debug.Log(request.GetError()); // 例:huawei android端末(SSL CA certificate error
		}
            }
            request.Reset();
        }
    }
}

http通信許可

android

android9でhttp通信ができなくなってる。

取り急ぎhttp通信を対応したい場合 AndroidManifest.xmlのapplicationに以下属性追加

android:usesCleartextTraffic="true"

https://ameblo.jp/znky/entry-12459683348.html

ios

  1. unity/build setting/ios/other setting/Configuration
  2. Allow downloads over HTTPをチェック
  3. Supported URL schemesのSizeに1を入れ、許可するドメイン"project1.example.net"などを入れる

チェックをつけると以下警告が出る

You are using download over http. Currently Unity adds NSAllowsArbitraryLoads to Info.plist to simplify transition, but it will be removed soon. Please consider updating to https.

それでも、http通信時、以下が出る時

The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.

Info.plistへ以下を追加

    <key>NSAppTransportSecurity</key>
    <dict>
      <key>NSAllowsArbitraryLoads</key>
      <true />
      <key>NSAllowsArbitraryLoadsInWebContent</key>
      <true />
      <key>NSExceptionDomains</key>
      <dict>
          <key>project1.example.net</key>
          <dict>
              <key>NSIncludesSubdomains</key>
              <true />
              <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
              <true />
          </dict>
      </dict>

project1.example.netは適宜変更

参考:https://clevertap.com/blog/developing-for-ios9-app-transport-security/

補足

unityのiosの設定のAllow downloads over HTTPの下にあるSizeに1を入力しSchemaに、接続するドメイン(project1.example.netなど)を追加しても、以下が追加されるだけで、NSExceptionDomainsではないので、機能しない。

    <key>CFBundleURLTypes</key>
    <array>
      <dict>
        <key>CFBundleURLName</key>
        <string></string>
        <key>CFBundleURLSchemes</key>
        <array>
          <string>project1.example.net</string>
        </array>
      </dict>
    </array>

iosで、"Malformed URL"エラーになるとき

エラー詳細

WebHttpRequest Get request.error=Malformed URL

たとえば、urlが ttps://example.com/unityapi/statusread?uids[]=1515&uids[]=1130 のように、パラメータに"[]"を含むとurl形式エラーとなるみたい。"[]"を"%5B%5D"でエンコードしてあげると、うまくいく。