Unity3dAzure / AppServicesDemo

Azure App Services demos for Unity
https://www.deadlyfingers.net/tutorial/azure-app-services-for-unity3d
MIT License
27 stars 13 forks source link

Unity Web Request and Json Utility #22

Closed deadlyfingers closed 7 years ago

deadlyfingers commented 8 years ago

Unity is adding support for REST and JSON and it would be better to adopt the built-in methods therefore removing the need for external dependencies or plugins.

deadlyfingers commented 8 years ago

UnityWebRequest is marked experimental status - waiting for release before implementing this.

deadlyfingers commented 8 years ago

UnityWebRequest is now out of experimental status in current version of Unity (5.4), but reports that there are problems using the HTTP PATCH method on Android.

Related Articles: http://stackoverflow.com/questions/19797842/patch-request-android-volley http://answers.unity3d.com/questions/1230067/trying-to-use-patch-on-a-unitywebrequest-on-androi.html

@dgkanatsios (who wrote the AzureServicesForUnity library) suggested a workaround for PATCH on Android by using an Easy API update method as a proxy.

deadlyfingers commented 8 years ago

Switching over to UnityWebRequest & JsonUtility will bring in a number of changes to the library...

But I ran into a couple of issues / gotyas with Unity's JsonUtility -

  1. JsonUtility can't parse a top level json array atm. The easiest workaround is to add property with the array as value see http://forum.unity3d.com/threads/how-to-load-an-array-with-jsonutility.375735/
  2. Be careful parsing properties which include the shorthand {get; set;}. I had to remove these shorthand getters & setters from my data model for parsing to work correctly, otherwise I got back empty objects without any parse error info. Use fields for serialization, not properties.

One the plus side it supports the class attribute [Serializable] and property attributes [SerializeField], [NonSerialized]

Another thing I would like with UnityWebRequest is to not have to wrap requests with StartCoroutine(), but atm this still seems like the cleanest way of starting an async request - I'm open to other suggestions...

deadlyfingers commented 7 years ago

Status update: This branch is working on Mac/Windows Unity Editor, iOS and Android. But I appear to be hitting JsonUtililty deserialization issues when running as a W10 universal app. Holding this release as a feature branch until this issue is resolved. I've tried to keep external interfaces as similar as possible, so it should not be too much hassle to update. The main changes will involve:

deadlyfingers commented 7 years ago

To parse a Json array of objects with JsonUtility you have to do a work-around using a wrapper object with a T[] array field. This array wrapper method described on the Unity forum works on iOS and Android and in the Unity Editor Mac/PC, but when running my W10 Universal app I hit an error: Handle is not initialized. This Unity JsonUtility parse error happens when you try to parse a Json array of objects in a Windows Store App...

So far I've found a couple of work-around solutions using platform directives for running on UWP:

  1. Opt for using Newtonsoft.Json; WSA plugin within UNITY_WSA directive. https://github.com/SaladLab/Json.Net.Unity3D/blob/master/docs/UwpWorkaround.md https://github.com/SaladLab/Json.Net.Unity3D/releases/download/8.0.3/JsonNet-UwpWorkaround.8.0.3.zip http://json.codeplex.com/workitem/25220 http://www.newtonsoft.com/json/help/html/deserializeobject.htm
    #if UNITY_WSA
    using Newtonsoft.Json;
    #endif
    #if UNITY_WSA
    T[] array = JsonConvert.DeserializeObject<T[]>(json);
    return array;
    #endif
  2. Opt for using Windows.Data.Json; WinRT API within NETFX_CORE directive. https://docs.unity3d.com/Manual/windowsstore-scripts.html https://msdn.microsoft.com/en-us/library/windows/apps/windows.data.json.jsonobject.tryparse http://stackoverflow.com/questions/10951466/jsonarray-parse-error
    #if NETFX_CORE
    using Windows.Data.Json;
    using System.Collections.Generic;
    using System.Linq;
    #endif
    #if NETFX_CORE
    JsonArray array = new JsonArray();
    if (JsonArray.TryParse(json, out array)) {
    List<T> list = new List<T>();
    foreach(var x in array) {
      T item = JsonUtility.FromJson<T>(x.ToString());
      list.Add(item);
    }
    return list.ToArray();
    }
    return default(T[]);
    #endif