""

Tag Archive: facebook

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

Facebook authentication error: Iphone

Facebook has released new 3.1 version of sdk for ios (and ios 6 compatible). You can target ios 5 also, just need to do small tweak during setup. They have details and tutorial on developers’ site. This post is not about any how to’s, here I will be talking about another few things that you need to be aware of and take care of it. I have integrated facebook sdk with android and iphone projects many times, but you can fall into one basic pitfall if not taken care of.

So your facebook app is ready. You have its app id and facebook sdk is well integrated with your project. You are ready to go. Now during facebook authentication from your app it gives this error (screenshot
below):

the operation couldn’t be completed com.facebook.sdk error 2
Now you will be thinking what went wrong? You’ll double check the facebook app id, and go through all settings you made and see if you have missed anything? But you find that everything is in its place. So what the duck is wrong with the program? What we are missing out is one basic setting during facebook app creation. If you check the facebook app dashboard again and look for native IOS App section. There you will find Bundle ID field, here you will have to enter your application bundle identifier so that facebook knows which app to redirect back to once auth is complete. This is very safe and you should provide this field on dashboard setting. Your application might run without that detail as I have tested this and confirmed it too that it has run on many other application without that setting but then in some devices/scenario it will definitely hit you. Your simulator and testing device might be running without issue but when you distribute it to some other device then you will face it eventually. So just be on safe side and provide your bundle identifier to your facebook app settings.

Another post on phonegap and my not so called “adventure”. This time something interesting happened. I am working on phonegap project targeting both iphone and android devices. Its mostly been REST based. So i was testing on various android and iphone devices, things went well except few things like static footer and header not working from android 2.x and below phones but i’l come to this issue on my next post. I hadn’t tested on android 4.0 and above, so yeah when i ran the app on icecream sandwich(Sony Xperia U and Samsung galaxy s2) mighty exception punched me on my face. Here is the long excpetion trace

10-26 10:19:45.998: E/AndroidRuntime(23917): FATAL EXCEPTION: main
10-26 10:19:45.998: E/AndroidRuntime(23917): android.os.NetworkOnMainThreadException
10-26

10:19:45.998: E/AndroidRuntime(23917):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
10-26 10:19:45.998: E/AndroidRuntime

(23917):  at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at java.net.InetAddress.getAllByName

(InetAddress.java:220)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at libcore.net.http.HttpConnection.(HttpConnection.java:71)
10-26 10:19:45.998:

E/AndroidRuntime(23917):  at libcore.net.http.HttpConnection.(HttpConnection.java:50)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:460)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:432)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at libcore.net.http.HttpEngine.sendRequest

(HttpEngine.java:232)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at libcore.net.http.HttpURLConnectionImpl.getResponse

(HttpURLConnectionImpl.java:273)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at libcore.net.http.HttpURLConnectionImpl.getInputStream

(HttpURLConnectionImpl.java:168)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at libcore.net.http.HttpsURLConnectionImpl.getInputStream

(HttpsURLConnectionImpl.java:270)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at com.facebook.android.Util.openUrl(Util.java:215)
10-26 10:19:45.998:
.
.

(FbDialog.java:146)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.java:234)
10-26

10:19:45.998: E/AndroidRuntime(23917):  at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:349)
10-26 10:19:45.998: E/AndroidRuntime(23917):  

at android.os.Handler.dispatchMessage(Handler.java:99)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at android.os.Looper.loop(Looper.java:137)
10-26

10:19:45.998: E/AndroidRuntime(23917):  at android.app.ActivityThread.main(ActivityThread.java:4507)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

java.lang.reflect.Method.invokeNative(Native Method)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at java.lang.reflect.Method.invoke(Method.java:511)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
10-26 10:19:45.998:

E/AndroidRuntime(23917):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
10-26 10:19:45.998: E/AndroidRuntime(23917):  at

dalvik.system.NativeStart.main(Native Method)

So exception thrown was NetworkOnMainThreadException, so first thing, i checked out the documentation for the details. So according to reference:

“The exception that is thrown when an application attempts to perform a networking operation on its main thread.

This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it’s heavily discouraged”.

So one thing became clear to me that phonegap-facebook plugin is performing networking operation for facebook on main thread rather than separate thread like asynctask. From API level 11, httpclient is not allowed to execute on main thread. So i found the way to remove this restriction by changing the thread policy. Here is the small snippet that goes on onCreate():

if (android.os.Build.VERSION.SDK_INT >= 11) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

Phonegap doing facebook

I am here again to write on few more pitfalls that i fell into while setting up facebook-phonegap plugin. Set up is explained in the github project site. Just read the steps carefully and follow them one by one, don’t skip steps just for safety. Steps are clear enough to have setup your facebook plugin with phonegap project on xcode. My story starts when i finished all steps and finished setting up my project. So after everything was covered i built my project and fell straight into issues (not many issues and this particular one wasn’t any big):

1) “SenTestingKit.h not found”, yeah so some files from facebook sdk were using SenTestingKit.h which wasn’t created on my project. So to solve this issue, i had to link SenTestingKit.framework from Build phases tab -> Link Binary with libraries to project target.

Now my above issue was resolved. But real pain came next and new issue arose:

2) Undefined symbols for architecture i386: “_OBJC_CLASS_$_SenTestCase”, this gave me pain in my wherever you can think of, for hours. To be honest i was totally blank on this and didn’t know what to do. So i searched forums for this. It seemed that similar kind of problem was faced by many people. I tried every available answers and fixes but none worked for me. I even created and setup project from scratch again just to make sure if i hadn’t skipped any steps. But again, (yeah there is always a but somewhere) nothing worked. So i dig more deeper into my source files of facebook sdk. It seemed all the source files inside test folder were using this “SenTestingKit”. So i simply deleted that test folder from my project navigator, and it really resolved this issue or i removed the source of issue. No more such errors and no more pain and i don’t know about any gain.

But i wasn’t still sure if it didn’t break up the project as you don’t simply delete files and folders from external libraries without knowing. So i tested my project and performed all facebook activities and it seemed to worked fine. I haven’t found any issue till now but lets see.