Unity3D WWW calls main thread on iOS

In the application we are building, we want to make an attempt by the remote user to save data when the application is suspended. In the Unity Editor and on Android, it's as easy as

WWW www = new WWW(_URL);
while(!www.isDone)
{
    Thread.Sleep(100);
}
Debug.Log(www.text);

      

(full sample: https://github.com/SixMinute/iOSWWWGet )

But on iOS it www.isDone

never evaluates to true while we're blocking, so it all just hangs.

Is this a bug or by design? And then, if it's by design, what's the correct way to do it, because if we put this behind StartCoroutine

it won't properly in the main thread, and in case of pause, what happens when the app resumes (which completely defeats the purpose of what we are trying to do).

edit: After talking to some of the Unity devs on IRC, they admit that this is actually a bug in the code, understand my reasons for this and accept that there must be a way to run the WWW request synchronously, or some other way to include this when called during a stream OnApplicationPause(true)

on iOS, because otherwise (despite being able to do this easily initially) there is no way to run WWW requests at that time, the only option is to queue them before resuming, which is completely unfeasible.

+3


source to share


3 answers


At this point Unity does not start a new thread for the www action, at least on some platforms (iOS, webplayer). Or, if it does, it installs WWW.isDone on the main thread. So this code:

while(!www.isDone)
     Thread.Sleep(500);  

      



does not work.

+1


source


Launch your www call in any way you like. During upgrade check on www.isDone ... if this returns true then act on it ... otherwise go through.

private WWW myRequest = null;

void Update()
{
    if (myRequest != null)
    {
        if (myRequest.isDone)
        {
            // process request here

            myRequest = null;// reset it 
        }
    }
}

      



If you want to support running multiple www requests at once, put your www requests in an array List myRequests = new List () and go through the ones that are in the update and check each status. You cannot remove from myRequests while using it, so take note of the temp removal list.

private List<WWW> myRequests = new List<WWW>()

void Update()
{
    if (myRequests.Count > 0)
    {
        List<WWW> removeList = null;

        foreach (WWW myRequest in myRequests)
        {
            if (myRequest.isDone)
            {
                // process request here

                if (removeList == null)
                {
                    removeList = new List<WWW>();
                }
                removeList.Add(myRequest);
            }
        }
        if (removeList != null)
        {
            foreach (WWW oldReq in removeList)
            {
                myRequests.Remove(oldReq);
            }
        }
    }
}

      

+1


source


Check it out on Unity Documentation

Use Coroutine and the loop will be blocked on the webplayer:

void SaveDate()
{
StartCoroutine("SaveWebData");
}

IEnumerator SaveWebData() 
{
// Start a download of the given URL
WWW www = new WWW(_URL);

// Wait for download to complete
yield return www;

// Completed!
Debug.Log(www.text);
}

      

-1


source







All Articles