it-swarm.com.de

Unity GET/POST-Wrapper

Dies ist eine Unity3d in C # -Frage. Das Ziel ist es, ein Objekt so zu erstellen, dass ich eine URL übergeben und Daten über GET empfangen kann, ein Objekt, das ich erstellen würde. Das wäre ein Wrapper für die WWW-Logik. Ich möchte auch ein "POST" -Objekt, bei dem ich eine URL und ein "Dictionary" mit Schlüssel-Wert-Paaren als Nachargumente angeben könnte. Sooo ... wir möchten letztendlich so etwas wie:

get_data = GET.request("http://www.someurl.com/somefile.php?somevariable=somevalue");

UND

post_data = POST.request("http://www.someurl.com/somefile.php", post)
// Where post is a Dictionary of key-value pairs of my post arguments. 

Um dies zu versuchen, verwende ich das WWW-Objekt. Um dem WWW-Objekt Zeit zum Herunterladen zu geben, müssen wir dies innerhalb eines MonoBehaviour-Objekts und yield der Ergebnisse durchführen. Also habe ich das bekommen, was funktioniert:

public class main : MonoBehavior
{
    IEnumerator Start()
    {
        WWW www = new WWW("http://www.someurl.com/blah.php?action=awesome_stuff"); 
        yield return www;
        Debug.Log(www.text);
    }
}

Was ich wirklich will, ist folgendes:

public class main : MonoBehavior
{
    IEnumerator Start()
    {
        GET request = new GET("http://www.someurl.com/blah.php?action=awesome_stuff"); 
        Debug.Log(request.get_data()); // Where get_data() returns the data (which will be text) from the request.   
    }
}

Jetzt habe ich das Hauptskript an die einzelne GameObject in der Hierarchie angehängt (genannt root). Muss das Skript GET auch an das Stammverzeichnis GameObject angehängt sein? Kann ich das dynamisch aus main machen?

Letztendlich brauche ich eine Lösung, mit der ich problemlos GET- und POST-Anfragen senden kann.

Prost!

17

Ah, verstehe!

Mein Problem war ein Missverständnis darüber, wie MonoBehaviour und Coroutines funktionierten. Die Lösung ist sehr einfach.

Erstellen Sie im Editor ein leeres GameObject. Ich habe es DB genannt. Fügen Sie dann das folgende Skript hinzu:

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
class DB : MonoBehaviour
{
    void Start() { }

    public WWW GET(string url)
    {
        WWW www = new WWW(url);
        StartCoroutine(WaitForRequest(www));
        return www;
    }

    public WWW POST(string url, Dictionary<string, string> post)
    {
        WWWForm form = new WWWForm();
        foreach (KeyValuePair<String, String> post_arg in post)
        {
            form.AddField(post_arg.Key, post_arg.Value);
        }
        WWW www = new WWW(url, form);

        StartCoroutine(WaitForRequest(www));
        return www;
    }

    private IEnumerator WaitForRequest(WWW www)
    {
        yield return www;

        // check for errors
        if (www.error == null)
        {
            Debug.Log("WWW Ok!: " + www.text);
        }
        else
        {
            Debug.Log("WWW Error: " + www.error);
        }
    }
}

Dann können Sie dies in der Startfunktion Ihres Hauptskripts tun!

private DB db;
void Start()
{
    db = GameObject.Find("DB").GetComponentInChildren<DB>();
    results = db.GET("http://www.somesite.com/someAPI.php?someaction=AWESOME");
    Debug.Log(results.text);
}

Ich habe die POST - Anforderungen nicht getestet, aber jetzt ist die gesamte Logik eingepackt! Senden Sie HTTP-Anfragen nach Herzenslust, Prost!

17

Was ist das GET-Skript, auf das Sie sich beziehen? Mit der WWW-Klasse können Sie GET-Daten einfach abrufen. Die benötigten Informationen befinden sich in der Texteigenschaft des instanziierten WWW-Objekts. Hier ist die Dokumentation:

http://unity3d.com/support/documentation/ScriptReference/WWW-text.html http: //unity3d.com/support/documentation/ScriptReference/WWW.html

Alles, was Sie tun müssen, ist das WWW-Objekt zu erhalten, wie Sie es gerade tun, und dann die Eigenschaften, die Sie interessieren, einfach und einfach zu lesen. Es sind keine zusätzlichen Klassen erforderlich.

Für das Senden eines POST -Objekts ist dies die Klasse WWWForm:

http://unity3d.com/support/documentation/ScriptReference/WWWForm.html

Kurz gesagt, Sie erstellen einfach ein WWWForm-Objekt, fügen Felder über AddField () hinzu und konstruieren dann einfach ein neues WWW-Objekt mit der URL POST und dem vorherigen Objekt. Geben Sie das WWW-Objekt ab, und sobald es zurückkommt, wurden Ihre Daten übermittelt. Antworten sind wiederum in der Texteigenschaft & Fehler im entsprechenden Feld. Einfach, sauber und einfach.

HTH!

2
jmpp

Hier ist der Code von @ pandemoniumsyndicate so geändert, dass ein Rückruf hinzugefügt wird. Der ursprüngliche Code ist nicht vollständig korrekt, da die Funktionen GET und POST sofort nach dem Aufruf der Coroutine beendet werden. Zu diesem Zeitpunkt ist es wahrscheinlich, dass die WWW-Anforderung noch nicht abgeschlossen ist und der Zugriff auf ein beliebiges Feld außer (www.isDone) sinnlos ist.

Der folgende Code definiert einen Delegaten, WWWRequestFinished, der aufgerufen wird, wenn die Anforderung mit dem Ergebnis der Anforderung und den erhaltenen Daten abgeschlossen ist, sofern vorhanden.

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class WWWRequestor : MonoBehaviour 
{

    Dictionary<WWW, object> mRequestData = new Dictionary<WWW, object>();
    public delegate void WWWRequestFinished(string pSuccess, string pData);

    void Start() { }

    public WWW GET(string url, WWWRequestFinished pDelegate)
    {
        WWW aWww = new WWW(url);
        mRequestData[aWww] = pDelegate;

        StartCoroutine(WaitForRequest(aWww));
        return aWww;
    }

    public WWW POST(string url, Dictionary<string, string> post, WWWRequestFinished pDelegate)
    {
        WWWForm aForm = new WWWForm();
        foreach (KeyValuePair<String, String> post_arg in post)
        {
            aForm.AddField(post_arg.Key, post_arg.Value);
        }
        WWW aWww = new WWW(url, aForm);

        mRequestData[aWww] = pDelegate;
        StartCoroutine(WaitForRequest(aWww));
        return aWww;
    }

    private IEnumerator WaitForRequest(WWW pWww)
    {
        yield return pWww;

        // check for errors
        string aSuccess = "success";
        if (pWww.error != null)
        {
            aSuccess = pWww.error;
        }

        WWWRequestFinished aDelegate = (WWWRequestFinished) mRequestData[pWww];
        aDelegate(aSuccess, pWww.text);
        mRequestData.Remove(pWww);
    }

}
0
questionman