0

I am uploading data to database using WWW. I have two data classes for data object.

[Serializable]
public class pushdatawrapper{
    public string email;
    public pushdata[] shotsArray=new pushdata[1];
}
[Serializable]
public class pushdata{
    public string timehappened;
    public string clubtype;     
    public pushdata(string timestamp_,string clubtype_)
    {
        timehappened = timestamp_;
        clubtype = clubtype_;           
    }
}

Loading Json array of data object to database, I tried two approaches. The first one was ok, but the second one is always failed at calling StartCoroutine function.

First approach

public class BLEBridge : MonoBehaviour {
    void Start () {
       pushdata_ pdata = new pushdata_("123123123123.0","15","123.0","123.0", "123.0", "123.0","123.0", "123.0","123.0","123.0","123.0","123.0", "First");
        pushdatawrapper_ pw = new pushdatawrapper_ ();
        pw.email = "test@gmail.com";
        pw.shotsArray[0] = pdata;
        StartCoroutine (PushData_ (pw));
    }

    private IEnumerator PushData_(pushdatawrapper_ pdata){
        WWW www;
        Hashtable postHeader = new Hashtable();
        postHeader.Add("Content-Type", "application/json");
        string dataToJason = JsonUtility.ToJson(pdata);
        Debug.Log ("dataToJason " + dataToJason);
        // convert json string to byte
        var formData = System.Text.Encoding.UTF8.GetBytes(dataToJason);
        www = new WWW("http://rmotion.rapsodo.com/api/push/new", formData, postHeader);
        StartCoroutine(WaitForRequest(www));
        return www;

    }
    IEnumerator WaitForRequest(WWW data)
    {
        yield return data; // Wait until the download is done
        if (data.error != null)
        {
            Debug.Log("There was an error sending request: " + data.text);
        }
        else
        {
            Debug.Log("WWW Request: " + data.text);
        }
    }

}

This first method is always ok. But in actual implementation, I need to upload data from a static function. Those private IEnumerator PushData_(pushdatawrapper_ pdata) and IEnumerator WaitForRequest(WWW data) can't be static.

So what I did was I made a separate class as

public class UploadData: MonoBehaviour{
    public void uploadindividualshot(pushdatawrapper pw){       
        StartCoroutine (PushData (pw));


    }

    private IEnumerator PushData(pushdatawrapper pdata){
        WWW www;
        Hashtable postHeader = new Hashtable();
        postHeader.Add("Content-Type", "application/json");
        string dataToJason = JsonUtility.ToJson(pdata);
        Debug.Log ("dataToJason " + dataToJason);
        // convert json string to byte
        var formData = System.Text.Encoding.UTF8.GetBytes(dataToJason);
        Debug.Log ("before www ");
        www = new WWW("http://rmotion.rapsodo.com/api/push/new", formData, postHeader);
        Debug.Log ("after new ");
        StartCoroutine(WaitForRequest(www));
        Debug.Log ("after WaitForRequest ");
        return www;

    }
    IEnumerator WaitForRequest(WWW data)
    {
        Debug.Log ("start pushing ");
        yield return data; // Wait until the download is done
        if (data.error != null)
        {
            Debug.Log("There was an error sending request: " + data.text);
        }
        else
        {
            Debug.Log("WWW Request: " + data.text);
        }
    }

}

Then call the instance of the class from static method as

public class BLEBridge : MonoBehaviour {

    void Start(){}

    public unsafe static void GetGolfREsult()
    {
       pushdata pdata = new pushdata("123123123123.0","15","123.0","123.0", "123.0", "123.0","123.0", "123.0","123.0","123.0","123.0","123.0", "First");
       pushdatawrapper pw = new pushdatawrapper();
       pw.email = Login.loginName;
       pw.shotsArray[0] = pdata;
       UploadData up = new UploadData ();
        up.uploadindividualshot (pw);
    }
}

I always have error as

after new 
UploadData:PushData(pushdatawrapper)
BLEBridge:GetGolfREsult()

(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)

libc++abi.dylib: terminating with uncaught exception of type Il2CppExceptionWrapper
2018-04-29 17:25:25.565292+0800 RMotion[270:7241] 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.

The program has error at StartCoroutine(WaitForRequest(www));

What is wrong with second approach?

derHugo
  • 83,094
  • 9
  • 75
  • 115
batuman
  • 7,066
  • 26
  • 107
  • 229
  • What's your Unity version? – PassetCronUs Apr 29 '18 at 09:44
  • 2017.2.0f3 personal – batuman Apr 29 '18 at 09:45
  • 1
    While the duplicate explains your error, there very serious issues with your code: **1**. When you called `WaitForRequest`, you should yield it to actually wait until the `WaitForRequest` function returns. That should be changed to `yield return StartCoroutine(WaitForRequest(www));`. **2**. The `UploadData` class derives from `MonoBehaviour`. You can't use the `new` keyword to create new instances of it. See [this](https://stackoverflow.com/questions/37398538/unity-null-while-making-new-class-instance/) post for how to create instance of a class that derives from`MonoBehaviour`. – Programmer Apr 29 '18 at 10:47
  • @Programmer Thanks. Initially I was trying to push every data I receive at static method to server. Calling `MonoBehaviour` class from a static method has some issue. I followed the link you mentioned, but still have issues. So I changed my approach as stored data into a sqlite table first and push to server when the app switches to background mode. So I don't need to deal with static method. But your comment is useful for me. Thanks – batuman May 02 '18 at 01:52

1 Answers1

-1

In unity calling this line of code automatically start http request

WWW www = new WWW("url");

yield is just the convenience way to tell the coroutine to wait for the process to finish. Don't separate your calls in 2 IEnumerator.

private IEnumerator PushData_(pushdatawrapper_ pdata){
    WWW www;
    Hashtable postHeader = new Hashtable();
    postHeader.Add("Content-Type", "application/json");
    string dataToJason = JsonUtility.ToJson(pdata);
    Debug.Log ("dataToJason " + dataToJason);
    // convert json string to byte
    var formData = System.Text.Encoding.UTF8.GetBytes(dataToJason);
    www = new WWW("http://rmotion.rapsodo.com/api/push/new", formData, postHeader)
    Debug.Log ("start pushing ");
    yield return www; // Wait until the download is done
    if (www.error != null)
    {
        Debug.Log("There was an error sending request: " + www.text);
    }
    else
    {
        Debug.Log("WWW Request: " + www.text);
    }

}

And I don't see any use of pointer in your static method so why did you use the unsafe keyword?

buffalo94
  • 159
  • 5