- Home /
How do I get into the data returned from a UnityWebRequest ?
I used the example from the unity manual and threw in more Debug.Log lines to show status:
IEnumerator GetText()
{
UnityWebRequest www = new UnityWebRequest("https://www.investopedia.com/markets/api/partial/historical/?Symbol=SPY&Type=Historical+Prices&Timeframe=Daily&StartDate=Dec+31%2C+2018");
www.downloadHandler = new DownloadHandlerBuffer();
yield return www.SendWebRequest();
Debug.Log("TickerScraper.GetText " + www.isNetworkError + " " + www.isHttpError);
if (www.isNetworkError || www.isHttpError)
{
Debug.Log("TickerScraper.isNetworkError");
Debug.Log(www.error);
}
else
{
// Show results as text
Debug.Log("TickerScraper.downloadHandler.text");
Debug.Log(www.downloadHandler.text);
// Or retrieve results as binary data
byte[] results = www.downloadHandler.data;
}
And the isNet and isHttp erros are flase so the request looks like it worked. I can not find any examples of how to get to the text data itself. There are two data lines past the headings on the page:
Jan 02, 2019 13.80 14.55 13.61 14.37 14,862,962Date Open High Low Adj. Close Volume
Dec 31, 2018 14.23 14.25 13.64 14.03 7,636,510
The log shows :
01-03 23:23:54.938: I/Unity(10070): TickerScraper.downloadHandler.text
01-03 23:23:54.938: I/Unity(10070): c__Iterator0:MoveNext() (at C:\Users\User\Documents\UnityProjects\Project\Assets\TickerScraper.cs:33)
So I am very excited this worked. I am using this page because of the low text bytes count. I have other larger web pages I will be requesting from. Just wanted to keep it simple at first.
In further research I found this line:
if (result != null) result(www.downloadHandler.text);
But how is result then accessed or displayed?
Any help would be appreciated. Thanks in advance.
What sort of data are you expecting and do you have a representation of it on your C# side? If it's JSON, then you can use a json conversion to parse the response:
SomeObject data = JsonUtility.FromJson<SomeObject>(request.downloadHandler.text);
The return is supposed to be a text line. Is the text returned Html, Json, or the xml hierarchy data?
It will depend on what you requested. For that endpoint there, it doesn't seem like they support Content-Type headers specifying JSON or X$$anonymous$$L, so HT$$anonymous$$L is probably all you're going to get.
I am a bit rusty in my C# data acquisition coding.
For your example endpoint there, that format is a bit ugly and I'm surprised Unity uses that as their example. You can parse that response with regular expressions, but HT$$anonymous$$L parsing can get a little ugly.
If you're comfortable with a more traditional format like JSON, try pinging something like the jsonplaceholder service.
You can get simple sample data individually:
https://jsonplaceholder.typicode.com/todos/1
or all at once as an array:
https://jsonplaceholder.typicode.com/todos/
At this point I just want to see the data that is supposed to be text. I will parse out any data items later. $$anonymous$$y assumption is it supposed to be the actual display data that I posted there copied from the browser page and nothing internal. There is no real coding examples of this process that I can find. A simple snippet of code showing how to get the text to the debug.log or console would be helpful. I see too many answers extolling the complexities of C# and not enough examples when it comes to sparse usage of newer unity features. Would the obsolete www examples be close to what I need? Hate to sound like a noob but I am working towards a goal and not a complete education. A working example will send me in the correct direction and from there I can delve further into the intricacies.
Answer by TreyH · Jan 04, 2019 at 05:44 PM
An example might be easier. Drop this script onto an empty scene:
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class WebRequestExample : MonoBehaviour
{
// Where to send our request
const string DEFAULT_URL = "https://jsonplaceholder.typicode.com/todos/1";
string targetUrl = DEFAULT_URL;
// Keep track of what we got back
string recentData = "";
void Awake()
{
this.StartCoroutine(this.RequestRoutine(this.targetUrl, this.ResponseCallback));
}
// Web requests are typially done asynchronously, so Unity's web request system
// returns a yield instruction while it waits for the response.
//
private IEnumerator RequestRoutine(string url, Action<string> callback = null)
{
// Using the static constructor
var request = UnityWebRequest.Get(url);
// Wait for the response and then get our data
yield return request.SendWebRequest();
var data = request.downloadHandler.text;
// This isn't required, but I prefer to pass in a callback so that I can
// act on the response data outside of this function
if (callback != null)
callback(data);
}
// Callback to act on our response data
private void ResponseCallback(string data)
{
Debug.Log(data);
recentData = data;
}
// Old fashioned GUI system to show the example
void OnGUI()
{
this.targetUrl = GUI.TextArea(new Rect(0, 0, 500, 100), this.targetUrl);
GUI.TextArea(new Rect(0, 100, 500, 300), this.recentData);
if (GUI.Button(new Rect(0, 400, 500, 100), "Resend Request"))
{
this.StartCoroutine(this.RequestRoutine(targetUrl, this.ResponseCallback));
}
}
}
This will give you a screen that starts off looking like the image. You can edit the topmost box to change the URL and then resend the request with the button, with the response data being printed into that box.
I created an empty scene. I created a new script in the project tab. When I drag to scene Unity shows the circle with a slash, meaning it wont let me drag and drop. I try putting it in the camera object but unity barks that 'Cant add script behavior ovrAvatarLogger. The script needs to derive from monobehavior.' I keep running into these complexities in trying to do simple things that posters say 'Just do this'. It isnt as simple as what everyone seems to give instructions to do. Or is my Unity clobbered some how. I am in unity 2018.2.2f1 and really dont want to go through the upgrade process again. I just went through 2 of them and alot of my other projects need attention as they are now broke. I want to make progress in this one. I do see the callback routine. That is probably all i need in my script.
You will need to name the file "WebRequestExample.cs" btw.
One would think I should remember this one... Arf! I will try that. I did add the data statements to my script am trying that one now. and data returned empty
You, Sir are an angel! The data is in html:
<th class="date">Date</th>
<th class="num">Open</th>
<th class="num">High</th>
<th class="num">Low</th>
<th class="num">Adj. Close</th>
<th class="num">Volume</th>
</tr>
<tr class="in-the-money">
<td class="date">Jan 03, 2019</td>
<td class="num">17.90</td>
<td class="num">18.48</td>
<td class="num">17.55</td>
<td class="num">18.45</td>
<td class="num">12,276,755</td>
</tr>
<tr class="in-the-money">
<td class="date">Jan 02, 2019</td>
<td class="num">17.55</td>
<td class="num">17.78</td>
<td class="num">16.80</td>
<td class="num">17.36</td>
<td class="num">9,590,347</td>
</tr>
<tr class="in-the-money">
<td class="date">Dec 31, 2018</td>
<td class="num">16.54</td>
<td class="num">17.52</td>
<td class="num">16.21</td>
<td class="num">17.50</td>
<td class="num">10,007,208</td>
I can rip and strip this. It looks like my original script needs some overhaul now. Due to Unity's sparse documentation it is going to take some effort. It looks like the parsing is going to take a lot of string functions or I have to import to an sql database in hopes the carriage returns will do the trick.
I am perturbed that Unity's example doesn't work or is not fully tested.
Answer by dradb · Aug 30, 2019 at 11:41 AM
This doesn't seem to work when built to WebGL. Help please?
I've used this same structure for WebGL projects without issue, but do note that browsers can limit how requests are handled -- particularly when the resource / data being requested hasn't been flagged for cross-origin sharing.
When you open your WebGL project, open your browser's developer / console tab and see if it's complaining about something called CORS.