Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SDK 3.1: How to tell whether SDK is using iOS6 accounts or not?

If I have a Facebook account set up in iOS6 but the user has switched it off, the SDK just gives me a FBSessionStateClosedLoginFailed status. From that, I can't tell if the user has switched us off in iOS (case 1) or doesn't have an account set up in iOS and declined permission from the FB app or web app (case 2).

The error messages I need to present are quite different in the two cases. In the first case, we need to tell the user how to switch us back on, but those instructions would be confusing for someone in case 2.

I tried using the iOS Accounts framework, but if I'm switched off, I'm told there ARE no Facebook accounts even if there are. I also tried writing down the account identifier if I ever successfully authenticate, but accountWithIdentifier fails similarly if we are switched off.

Anybody know of a way to find out if our rejection is coming from iOS or FB itself?

like image 716
Michael McDaniel Avatar asked Oct 03 '12 15:10

Michael McDaniel


1 Answers

The policy of the SDK in general is that if some operation is in the process of failing, the underlying error information from the OS is bubbled up to the app. (Of course not all failure cases start with an OS API failing.) The reason for this policy is to support more precise error handling and logging scenarios like the one that you describe. As an aside, if you ever find a place in the SDK that does not follow this pattern, it is a bug and please report it.

In this case FBSession is passing an NSError object to your handler, and it sets the FBErrorInnerErrorKey value in the userInfo to the error object returned by the OS. In order to provide a precise error message to your user, you can use a snippet of code like this in your FBSessionStateClosedLoginFailed case:

if (error) {
    NSError *innerError = error.userInfo[FBErrorInnerErrorKey];
    if ([innerError.domain isEqualToString:ACErrorDomain] &&
        innerError.code == ACErrorPermissionDenied) {
        NSLog(@"User dissallowed permissions via iOS 6.0 integration");
    }
}

Hope this helps!

* UPDATE * Just tried this on a device and found two bugs; one in iOS 6.0, and the other in the SDK. The iOS 6.0 bug is that when the switch is off, no NSError object is passed by the OS, and so there is no inner error. Thus making the general solution from above not work for the specific case in question. The second bug does provide you a temporary solution to this problem using the SDK 3.1.1.

The bug in the SDK 3.1.1 is that we set error.userInfo[FBErrorLoginFailedReason] to the value of FBErrorLoginFailedReason. In the case where the inner error is NIL, you can check for this reason value to determine that the slider for the app was set to off. When this bug is fixed in the SDK, then the code testing for this will break, however, since we will be setting the reason to a more logical reason related to iOS 6. This is a gotcha to watch out for in a future build of your application, if you decide to rely on this value.

like image 80
Jason Clark Avatar answered Nov 18 '22 22:11

Jason Clark