Unity GET/POST Wrapper
Это вопрос Unity3d в С#. Цель состоит в том, чтобы создать объект, чтобы я мог передавать URL-адрес и получать данные через GET
, объект, который я бы создал, был бы оболочкой для логики WWW. Мне также понравился бы объект "POST", где я мог бы предоставить URL-адрес и "Словарь" пар ключ-значение в качестве аргументов post. Sooo... мы в конечном итоге хотели бы что-то вроде этого:
get_data = GET.request("http://www.someurl.com/somefile.php?somevariable=somevalue");
и
post_data = POST.request("http://www.someurl.com/somefile.php", post)
// Where post is a Dictionary of key-value pairs of my post arguments.
Чтобы попытаться выполнить это, я использую объект WWW
. Теперь, чтобы дать время WWW
для загрузки, нам нужно, чтобы это произошло внутри объекта MonoBehaviour
и yield
результатов. Итак, я получил это, которое работает:
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);
}
}
Что я действительно хочу, так это:
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.
}
}
Теперь у меня есть основной script, прикрепленный к одиночному GameObject
в иерархии (называемый root). Нужно ли иметь GET
script, прикрепленный к корню GameObject
, а? Могу ли я сделать это динамически из main
?
В конечном счете, мне нужно решение, которое позволяет мне легко отправлять запросы GET
и POST
.
Ура!
Ответы
Ответ 1
А, получилось!
Моя проблема заключалась в непонимании того, как MonoBehaviour и Coroutines работали. Решение очень просто.
В редакторе создайте пустой GameObject. Я назвал его БД. Затем присоедините к нему следующий script:
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);
}
}
}
Затем в вашей основной функции запуска script вы можете сделать это!
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);
}
Не тестировали POST-запросы, но теперь вся логика завернута! Отправьте HTTP-запросы своим сердцам, приветствуйте!
Ответ 2
Что это такое GET script, о котором вы говорите? Класс WWW позволяет извлекать данные GET очень точно, информация, в которой вы нуждаетесь, находится в текстовом свойстве созданного объекта WWW. Здесь документация:
http://unity3d.com/support/documentation/ScriptReference/WWW-text.html
http://unity3d.com/support/documentation/ScriptReference/WWW.html
Все, что вам нужно сделать, это предоставить объект WWW, как вы сейчас делаете, а затем прочитать любой из интересующих вас свойств, простой и простой, без дополнительных классов.
Что касается отправки POST-объекта, то для чего предназначен класс WWWForm:
http://unity3d.com/support/documentation/ScriptReference/WWWForm.html
Короче говоря, вы просто создаете объект WWWForm, добавляете к нему поля через AddField(), а затем просто создаете новый объект WWW с URL-адресом POST и прежним объектом. Допустим объект WWW, и как только он вернется, вы отправили данные. Кроме того, в свойствах текста и ошибках в соответствующем поле снова возникают ответы. Обычный, чистый и простой.
НТН!
Ответ 3
Вот код @pandemoniumsyndicate, измененный для добавления обратного вызова. Исходный код не совсем корректен, так как функции GET
и POST
выйдут сразу после вызова сопрограммы. В то время, скорее всего, запрос WWW
еще не завершен, и доступ к любому полю, кроме (www.isDone
), бессмысленен.
Следующий код определяет делегата WWWRequestFinished
, который будет вызываться, когда запрос будет завершен с результатом запроса и полученных данных, если таковые имеются.
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);
}
}