Using Parse SDK with Unity – running on an Android Device

unityandroid

If you are using Parse for your back-end server in a Unity app, and you want to deploy the app to Android, you may run into some issues with the built-in Parse plugin. Specifically (at least in my case with Unity 4.6 and Android KitKat) the Parse query object doesn’t ever return a result.

As a work-around I ended up going with a solution using Unity’s WWW class and the Parse REST API.

 

 

 


private IEnumerator GetParseDataForAndroid () {

	//new WWW object
	WWWForm form = new WWWForm();


	//set headers, not sure why but I had to set twice to get it to work
	Hashtable headers = form.headers.AddAuthorizationHeader("Your-Parse-Application-Id", "javascript-key=Your-Parse-REST-API-Key");

	headers.Add("X-Parse-Application-Id","Your-Parse-Application-Id");
	headers.Add("X-Parse-REST-API-Keyd","Your-Parse-REST-API-Key");

	WWW parseRequest = new WWW("https://Your-Parse-Application-Id:javascript-key=Your-Parse-REST-API-Key@api.parse.com/1/classes/yourObject", null, headers);


		//yield until request is done
		yield return parseRequest;


		//request is done, process results
		Debug.Log (" MergeVRBridge parse query eror result is " + parseRequest.error);


		//using simplejson
		var V = JSON.Parse (parseRequest.text);

		JSONArray results = V ["results"].AsArray;

		for (int i=0; i<results.Count; i++) {

			JSONClass jObject = results[i].AsObject;
			
			//do something interesting with results
			string sTitle = jObject["title"];
			Debug.Log(" yourObject " + sTitle);

			
			
		}




}


Unity3d and Parse.com error messages

I’ve used Parse.com quite a bit for iOS development and been very happy with it. Performance and scaling is good, and working with the cloud based service is very straight forward.

I decided to use Parse.com as the back end database solution for my latest Unity3d project. Parse now has an official Unity SDK that you can download from the Unity3d asset store.

Despite all of the benefits of using Parse with Unity there is one glaring problem. Because of the way the Unity implements their WWW class we can’t access response headers containing error information from Parse operations.  So requests sent using the Parse SDK from Unity return responses which can be either successful, failed because of no connection, or failed because of some unknown cause.

Kalekindev has a great blog post addressing this issue. The solution is to create custom cloud code functions on Parse.com and call them instead. The cloud code handles the request and then returns either a success code or an appropriate error message.

Below is my initial cloud code running on Parse (cloud code is in javascript) to handle user signup.

Parse.Cloud.define("SignUp", function(request, response)
{
    var user = new Parse.User();
 
    user.set("username", request.params.username);
    user.set("password", request.params.password);
    user.set("email", request.params.email);
 
    user.signUp(null,
    {
        success: function(user)
        {
            response.success(
                {
                    "success": "Sign up successful."
                });
        },
        error: function(user, error)
        {
            // We must respond with a success in order to access the
            // result of the request inside Unity.
            response.success(
                {
                    "error": "Sign up failed.",
                    "code": error.code,
                    "message": error.message
                });
        }
    });
});

 

And here is the Unity3d C# code snipped that makes the call to the Parse.com cloud code and handles the return code appropriately if there is an error..

 

private IEnumerator CloudSignUp(string sUsername,string sPassword,string sEmail)
{
	var userInfo = new Dictionary
	{
		{"username", sUsername},
		{"password", sPassword},
		{"email", sEmail}


	};
	
	var t = ParseCloud.CallFunctionAsync<Dictionary>("SignUp", userInfo);
	
	while (!t.IsCompleted)
	{
		yield return null;
	}
	
	if (t.IsFaulted)
	{
		var parseException = (ParseException)t.Exception.InnerExceptions[0];
		
		if (parseException.Message.StartsWith("Could not resolve"))
		{
			Debug.Log("Failure: Connection error.");
			objStatus.text="Failure: Connection error.";
			objStatusPanel.SetActive(true);
		}
		else
		{
			// Possible mystery case?
			Debug.Log("Failure: Unknown cause.");
			objStatus.text="Failure: Unknown cause..";
			objStatusPanel.SetActive(true);
		}
	}
	else // Our request is successful but may still have failed server side.
	{
		object code;
		
		if (t.Result.TryGetValue("code", out code))
		{
			// Handle our call specific errors here.
			Debug.Log(string.Format("Failure: Code {0}", code));

			string sCode = string.Format("{0}", code);
	
			if (sCode.Equals("125")) {

				objStatus.text="Email is invalid";
				objStatusPanel.SetActive(true);

				Debug.Log("bad email");
			}

			 else if (sCode.Equals("202")) {
				
				objStatus.text="Username is already in use.";
				objStatusPanel.SetActive(true);
				
				Debug.Log("bad username");
			}

			else if (sCode.Equals("203")) {
				
				objStatus.text="Email is already in use.";
				objStatusPanel.SetActive(true);
				
				Debug.Log("bad username");
			}

			else {

				objStatus.text=string.Format("Failure: Code {0}", code);
				objStatusPanel.SetActive(true);
	
			}


		}
		else
		{
			Debug.Log("Success!");
		}
	}
}

 

This approach can be used for all Parse.com functions called from Unity and gives us a robust way to handle exceptions and errors.

iOS Projects We’re Working On

Here are some of our recent iOS projects…

* YourTeacher.com – We continue to be the iOS app development arm for yourteacher.com. They have over thirty titles in the Apple App store – majority of which have 4.5+ average ratings with literally hundreds of thousands of downloads per app.

Algebra, ASVAB, or Math are some examples of the work we’ve done for them.

* Just Picture It – created in partnership with the Mason Software Company. It evolves a mobile photo sharing into a word game with friends and family. In a turn-based game you can play in single and multiplayer mode.

Just Picture It uses the Parse.com api extensively for user authentication, push notifications, and storage of games and messages.

Using Parse to add a backend to your iOS app

We’ve had to write over a dozen server back ends for iOS applications. There is a lot of manual work involved, no matter what platform you choose (we’ve used Google App engine or custom php solutions based on Joomla). There is the code and database development on the server side, plus a lot of code on the iOS side to handle the calls to the server, error handling, etc. It’s a royal pain and something we’d like to avoid in the future if possible.

Parse is a new service that simplifies back end development for iOS immensely – it can take literally minutes to add a simple server side component to your iOS app.

Pricing is free in Beta and looks very reasonable going forward as well.

We recently used Parse to add server functionality to an iOS Math application for YourTeacher.com. The app stores user preferences to a simple Parse object. Adding Parse to our project, testing, and deploying took less than an hour. Performance is good – besides being able to save and retrieve standard dictionary objects you can use Parse to store and manipulate remote files and geo location objects.

They have a very good overview of the integration process for iOS, plus the API is available as a REST service and for the Android as well.

Highly Recommended