""

Tag Archive: json

Why flush ?

Interesting stuff i came to know about which i was unaware of. This post is more of a discussion on the problem. I haven’t understood the solution and so would request you to have a say.

I have done json parsing numerous times. I can tell if json is valid or not by looking it. I was using google-gson for android application and its awesome. Application was supported by php web service. The solution that fixed the problem is related to php and i am not a php developer and don’t have that much inner understanding of it. It was regular json parsing routine. Application just crashed when gson was parsing the json response from php service.

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2

From error I understood the reason but that was not it. I was very confident that something else was the problem because json response was perfect. I wrote quick objective-c routine(SBJSON) to parse same json response and it worked there. I even did validation on jsonlint.com
After doing bit of research I came across a working solution. In php before sending response I had to put this:

ob_clean();
echo header('Content-Type: application/json');

I checked the php manual to understand what those lines means, header function was quite obvious. According to manual, ob_clean:

This function discards the contents of the output buffer.

Now I have no idea why discarding the contents of output buffer was working. This was the case for android, I mean in iphone I didn’t need ob_clean. I am still looking for the explanation on this.

Another not so interesting tale…Lots of thing you learn from mistakes and lots of knowledge you gain. When I started iphone development, I chose non-ARC way to know and learn the concepts of memory management. It was fun and good experience apart from objective-c being ugly(syntax). Whenever there was memory leak and any crash due to low on memory, it used to give me dose of excitement, debugging tits and bits had been good learning experience. It has been good journey for me. I started ARC later and life’s been good and easy for me.

I was trying to do some experiment with one iphone project based on facebook. I remember when my project was already using SBJSON for parsing json, then later when I had to integrate facebook to my project and I had lots of sbjson conflict errors. It seemed facebook was using another version of SBJSON library, so I had to remove my SBJSON and integrate the library that facebook was using. I found it in github facebook project. So that was another experience and at that time I was working on non-arc environment. So recently I tried to do something to see the result on what would happen if I do along these lines. So I created ARC based project and integrated facebook sdk 3.1 and then I integarted that same SBJSON that I had integrated on past to avoid conflict. This time my project and facebook sdk was ARC based and SBJSON was non-arc. So I decided to see the result by changing all lines of releasing memory to setting them to nil on the source codes of SBJSON. As release call will throw syntax error in arc environment so I was replacing them by nil assignment. Why nil assignment ? Well I wanted to see if there is any harm with that?

Everthing was fine. I was making rest call to my web services and parsing json. Then moment came and one crash sting me like a bee. So my crash error was this:

MyApp(2121,0xb0185000) malloc: *** error for object 0x1068310: double free
*** set a breakpoint in malloc_error_break to debug

From the description it was clear that I was trying to release already released memory. But big question was WHERE? Then as error asked me to do, I did set a breakpoint on malloc_error_break but still it was not enough for me. I need more clear error log, so I enabled zombies and trust me!! at this point of time zombies is your best friend. So as I knew I got a very clear picture, yeah NAKED CLEAR

[NSDecimalNumber retain]: message sent to deallocated instance

So it seems my decimal number has already been released before retain was called. Now another big question was NSDecimalNumber ????

I decided to play with parsing json because this crash was coming only parsing certain type of value. So I need to dig up more deeper. I was parsing every kind of value and trying to replicate the crash. Then crash happened and I had a big stupid grin on my face. I again tested parsing same kind of data and crash happened again and my stupid grin went wider. So crash was happening when I was parsing numbers. Something like this {“answer”:5} Now time was to follow the trails. So I started from [responseString JSONValue] , responseString is string and JSONValue is a method added via category. So I opened NSSting+SBJSON.m file and looked for the function. Now within function SBJsonParser was being used to parse the string, so I opened SBJsonParser.m file and searched for NSDecimalNumber because my best friend zombie told me I had a memory boom with decimal numbers. I got goosebumps when I found the stupid but very critical mistake I had made and it was the culprit of existence of this post that you are reading now. 😀 So my mistake happend on this method

(BOOL)scanNumber:(NSNumber **)o

See this is why I love zombie as it told me the problem was with decimalnumber and see where did I end up with. Yeah scanNumber! 😛 Now time for showing my mistake, but I would also like you to check the source code and look by yourself and I guess you already have SBJSON library.

@autoreleasepool {
    id str = [[NSString alloc] initWithBytesNoCopy:(char*)ns
                                            length:c - ns
                                          encoding:NSUTF8StringEncoding
                                      freeWhenDone:NO];

    if (str && (*o = [NSDecimalNumber decimalNumberWithString:str]))
        return YES;
}

and original lines of code was like this:

id str = [[NSString alloc] initWithBytesNoCopy:(char*)ns
                                            length:c - ns
                                          encoding:NSUTF8StringEncoding
                                      freeWhenDone:NO];
[str autorelease];
if (str && (*o = [NSDecimalNumber decimalNumberWithString:str]))
    return YES;

My mistake was that I used @autoreleasepool block because in hurry I couldn’t see that in original source code NSAutoreleasePool was not used and when I was using @autoreleasepool then all the autoreleased object was getting released after finish of the block. In my case decimalNumberWithString got released after releasepool block was finished and YES carriage was return. So later *o was pointing to deallocated memory and my app was crashing whenever I was parsing numbers.

But this was worth it and lots of fun debugging this crash. Also I am posting screenshot of enabling zombie objects

Iphone development has been a smooth ride for me, more smoother than when i started android :D. I am still playing and learning. I started with non-arc projects cuz i wanted to learn and grasp the concept of memory management, today i won’t be talking about memory management but JSON representation of your custom objects. Its a common topic and almost every person might had a requirement to create JSON array of your objects and send it to server. I was introduced to very awesome library called SBJson, after that i have been using this only because its been perfect for me till date. If you are working with non-arc project then i would recommend to use version 3.0.4, which is latest for non-arc.

Let’s begin, we have our class called Student. Student has got some properties like student id, photo, teacher id etc. So lets see how our Student class looks like:

@interface Student : NSObject{
    NSString *name;
    NSInteger sid;
    UIImage *simage;
    NSString *email;
}

Student has got four members: name, id, image and email. Now your requirement requires you to create list of students and send it to server on network. First thing that would come to mind is add all students to an array and send that array to the server. Second thought would be, how would i send an array to server ? Best bet would have been creating a json array of students. So lets call our array studentsArray which contains all students. Basically we are looking json representation something like this:

[{"student_name":"Student1","student_id":1,"email":"abc@email.com"},{"student_name":"Student2","student_id":2,"email":"def@email.com"}]

As you can see, its a json array of two students. Creating this representation isnt hard at all since SBJson does all work for you except you have to keep few things in mind else it will blow up. Code for creating json representation is this simple:

NSString *jsonString = [studentArray JSONRepresentation];

Yeah that simple. But above will crash your program. Error will be something related to serialization problem of one of your member of student object. If we look at our Student class definition above, there is member of type UIImage. It seems we have issues with serializing UIImage type. So things that work are strings, integers and booleans. Now what you can do is to remove that UIImage from definition but i don’t want to do that. If i don’t do that then how will i create json representation ? So someone comes to rescue:

#import "SBJson.h"

@interface Student : NSObject{
    NSString *name;
    NSInteger sid;
    UIImage *simage;
    NSString *email;
}

- (id) proxyForJson;

proxyForJson gets called when you ask for json representation of your object. Inside proxy you tell what members to serialize and give your custome key names for your member. Implemenation looks like this:

- (id) proxyForJson{
    return [NSDictionary dictionaryWithObjectsAndKeys:
            name, @"student_name",
            [NSNumber numberWithInt:sid], @"student_id",
            email, @"email",
            nil ];
}

So basically it will make json representation of your student object like this:

{"student_name":"value","student_id":value,"email":"value"}

As you can see that we have skipped UIImage type, so u can skip those members that cannot be serialized. So now you are free to call [studentArray JSONRepresentation] and it will give you your perfect json representation. You must also have noticed that i am using NSNumber from integer above, this is because dictionary takes pointer types aka objects not primitives.

I hope it helped you. Now i’l go back to play borderlands as i am still farming crawmerax for pearl aries revolver 😛

Gracias.

Today i was doing some experiment with google translate API. I was trying to use google translate API with AS3. I found many snippets while googling that was using flex but i wanted to do it in flash as3. So I wrote a very basic code snippet to translate text from one language to other using google translate API.

Well i have created two combobox on my fla. I have given instance name to them and then i am just taking the language input for translating text from one language to other.

The main crucial part:

‘http://ajax.googleapis.com/ajax/services/language/translate’+’?v=2.0’+’&q=’+escape(my_input)+’&langpair=’+’es’+’%7C’+’en’

I am just making a GET HTTP Call to google translate API passing input, and language pair (i.e en(english) to es(espanol) etc). It returns result in JSON. On my flash client i decode that JSON and display the translated result.
Note: escape method is used to encode the string to url encoded format

Here is the source code:

package 
{
	import com.adobe.serialization.json.JSON;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import fl.data.DataProvider; 
	
	/**
	 * ...
	 * @author padam
	 */
	public class Main extends Sprite 
	{
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			initGUI();
			button_p.addEventListener(MouseEvent.CLICK, translate);
		}
		
		private function initGUI():void {
			var itemsFrom:Array = [ 
			{label:"English", data:"en"}, 
			{label:"Spanish", data:"es"}, 
			{label:"French", data:"fr"}, 
			{label:"Italian", data:"it"}
			];
			
			var itemsTo:Array = [
			{label:"Hindi", data:"hi"},
			{label:"English", data:"en"}, 
			{label:"Spanish", data:"es"}, 
			{label:"French", data:"fr"}, 
			{label:"Italian", data:"it" }
			];
			
			fromLanguageCombo.prompt = "Select Language"; 
			fromLanguageCombo.dataProvider = new DataProvider(itemsFrom);
			toLanguageCombo.dataProvider = new DataProvider(itemsTo);
			
		}
		
		private function translate(event:MouseEvent):void {
			var request:URLRequest=new URLRequest();
			request.url='http://ajax.googleapis.com/ajax/services/language/translate'+'?v=2.0'+'&q='+escape(fromInput.text)+'&langpair='+fromLanguageCombo.selectedItem.data+'%7C'+toLanguageCombo.selectedItem.data;
			request.method = URLRequestMethod.GET;
			
			var loader:URLLoader=new URLLoader();
			loader.addEventListener(Event.COMPLETE,messageSent);
			try 
			{
				loader.load(request);
			} 
			catch (error:Error) 
			{
				
			}
		}
		
		private function messageSent(evt:Event):void
		{
			var loader:URLLoader=URLLoader(evt.target);
			var result:String = loader.data as String;
			
			var json_1:Object = JSON.decode(result);
			output.text = json_1["responseData"]["translatedText"];
			translationLabel.text = fromLanguageCombo.selectedItem.label + " to " + toLanguageCombo.selectedItem.label+" translation";
		
		}
		
	}
	
}

Well there is nothing much in code. Just taking the language values from two combo box list and passing it to the translate api. Then after decoding json that i received from api call, i am displaying on textfield. Anyway please note that translate api has been officialy depracated.

Here is the quote from API site:

Important: The Google Translate API has been officially deprecated as of May 26, 2011. Due to the substantial economic burden caused by extensive abuse, the number of requests you may make per day will be limited and the API will be shut off completely on December 1, 2011. For website translations, we encourage you to use the Google Translate Element.

Gracias.

While working on submitting and retrieving global game high scores from a remote database like mysql i learned few things. During start experiment i decided to use PHP to connect to mysql database. What i was trying to do is that i wanted to call php, then php would make a database connection and make a sql query and retrieve the result, then php would encode that result into JSON format and i would decode this JSON at my android program and display the results. I haven’t done much PHP before(never actually setup PHP server before :D). So i came to know this xampp server, so i installed/setup the xampp server(its a php apache server and it comes with mysql also). I am not telling how to setup xampp and create a databse and tables as you can find it in their wiki.

I create a php file, which makes a database connection and makes a query and encodes a result. As i told before i am not familiar to PHP so i wrote this code looking here and there by googling it :D. Code looks like this:


Well code is not that hard to understand. You are making a mysql connection by providing credentials. Then you select a databse. Then you execute a query and result is assigned to $q. Next what i seen is that result is in ArrayCollection type (i saw it in xampp console) so i think we are converting it into Array while iterating through collection(I am not quite sure so if u know then please share). Then You are just encoding the result into JSON.

Now lets see how we will decode the JSON at our android program. Code looks like this:

void parseJSON()
    {
    	
    	String result = "";
    	String x = "";
    	InputStream is=null;
    	//http post
    	try{
    			ArrayList nameValuePairs = new ArrayList();
    	        HttpClient httpclient = new DefaultHttpClient();
    	        HttpPost httppost = new HttpPost("http://localhost/game_php_testing/android_database.php");
    	        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    	        HttpResponse response = httpclient.execute(httppost);
    	        HttpEntity entity = response.getEntity();
    	        is = entity.getContent();
    	}catch(Exception e){
    	        Log.e("log_tag", "Error in http connection "+e.toString());
    	}
    	//convert response to string
    	try{
    		 	
    	        BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
    	        StringBuilder sb = new StringBuilder();
    	        String line = null;
    	        while ((line = reader.readLine()) != null) {
    	                sb.append(line + "\n");
    	        }
    	        is.close();
    	 
    	        result=sb.toString();
    	        
    	}catch(Exception e){
    	        Log.e("log_tag", "Error converting result "+e.toString());
    	}
    	 

//parse json data
try{
JSONArray jArray = new JSONArray(result);
for(int i=0;i catch(JSONException e){ Log.e(“log_tag”, “Error parsing data “+e.toString()); } }

I faced two problems/exception while connecting to php. PHP was connecting to mysql perfectly as when i run in browser it printed results so there was some issues on my above code which i’l address here and this is common problems which will be faced by every newcomer to android like me :D. Before that i’l just explain my php file and localhost path setup. When i installed xampp, in xampp folder there must be folder called htDocs so i have to make a project folder here inside htDocs and inside this project folder will be my php. So my php path would look like this “/htDocs/game_php_testing/android_database.php” So when i will make a call to php via “http://localhost/game_php_testing/android_database.php”

Now i will address the two problems that i faced.
First,

java.net.socketexception -permission denied

yes whenever i was trying to call my php i was getting this exception. How did i solved it ??? Well i just provided a permission to internet access at AndroidManifest.xml file. You have to put this permission above tag


Now second Problem, this one is very important.

java.net.ConnectException -Connection Refused.

Well what i found is that when u call localhost android thinks that u r calling to android emulator itself not the localhost machine. So localhost/127.0.0.1 wouldn’t work. So i found the solution to that: instead of localhost use 10.0.2.2, code will be like this:

HttpPost httppost = new HttpPost("http://10.0.2.2/game_php_testing/android_database.php");

Well problem solved :D. Now i decode the json that i got from php. I am printing the result on LOG. Please see that when i am calling “json_data.getString(“Player_name”)“, Player_name is a column/attribute in my database table and its type is varchar so i used getString() on it.

I hope this post helped you as you may also faced similar problem at first time.

Gracias.