2

I am using Sharekit for Facebook sharing with the Facebook Graph API. I have tried to find the latest, most up to date code (troppoli on github seems pretty up-to-date).

Using sharekit to log out of Twitter works fine with the line: [SHK logoutOfService:@"SHKTwitter"]; but the same line for Facebook, [SHK logoutOfService:@"SHKFacebook"], yields different results.

When I go to log back in, the login screen does not show. Instead, a screen with the text: "You have already authorized ... Press okay to continue." Then at the bottom of the screen, "Logged in as ..." and "Log out" . But the user is supposedly already logged out.

Even worse, if I press the "Okay" button to continue on, I get the error: "The operation couldn't be completed. (NSURLErrorDomain error -999.)

I think I may need to tweak ShareKit to make this work but I hate to do that. Has anyone else come across this?

SAHM
  • 4,078
  • 7
  • 41
  • 77

2 Answers2

2

You need to make sure you set up the URL scheme in your info.plist properly. In your info.plist, make sure you have your CFBundleURLTypes set up for Facebook:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string></string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>fb{app_id}</string>
        </array>
    </dict>
</array>

Replace {app_id} with your facebook app id.

You also need to add a handler in your app delegate to respond to the callback after the user has authenticated through Mobile Safari:

-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
    return [SHKFacebook handleOpenURL:url];
}

-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication 
         annotation:(id)annotation{
    return [SHKFacebook handleOpenURL:url];
}

These changes fixed this issue for me.

Mark Struzinski
  • 32,945
  • 35
  • 107
  • 137
  • Thanks for the reply Mark. My first question is - are you currently using oAuth 2.0 and the Facebook Graph API? I had this working perfectly in the regular FBConnect, it is just since updating (and using Sharekit to do so) that I have this logout problem. I did already have the handler(s) set up correctly in the app delegate. I also have the plist set up... but I have a few additional questions for you. My app is not an iPad app, and instead of CFBundleURLTypes/CFBundleURLName/CFBundleURLSchemes, my plist has the keys: URL types/URL identifier/URL Schemes.... – SAHM Oct 12 '11 at 17:06
  • I can't change this (that I know of) but I think I read that it is still the same within the actual plist as the CF names. Does that ring true? Also, I have seen this in different examples with and without the URL identifier/CFBundleURLName. I tried with both, and still get the same result. Anyway, I'd love to hear any more thoughts you have on this issue. Thanks again. – SAHM Oct 12 '11 at 17:07
  • Marked your answer up because it is good info and will hopefully help someone. Just didn't solve this particular problem, at this point. – SAHM Oct 12 '11 at 17:09
  • @JPK, I'm using this fork of ShareKit which integrates the graph API: https://github.com/troppoli/ShareKit. This is the best fork I've found, since the main branch of the ShareKit API hasn't been updated in quite some time. The CFBundleURLTypes are simply the XML names under the hood if you open the PList in code. Once I switched to the graph API, I had to add the handlers. – Mark Struzinski Oct 12 '11 at 17:24
  • I am also using troppoli's version of Sharekit. Good to know I picked the right one. So, it seems as though we are doing the exact same thing? But you can COMPLETELY log out from Facebook? Are you just using [SHKFacebook logout] or [SHK logoutOfService:@"SHKFacebook"], or do you also do something else? – SAHM Oct 12 '11 at 17:51
  • Mark - on a related but unrelated note, have you noticed that troppoli's Sharekit has a lot of potential memory leaks when run through Analyze? I thought he said in his comments that his code had no leaks.. – SAHM Oct 13 '11 at 01:47
  • We haven't come across any leaks on the Troppoli fork. When we log out, we are calling [SHKFacebook logout]; – Mark Struzinski Oct 13 '11 at 03:51
  • Funny, when I Build with Analyze in xCode 4 I get over 20 potential memory leaks. – SAHM Oct 13 '11 at 17:23
1

I'm pretty sure this has something to do with the new Facebook Single-Sign-On (SSO). If the user has Facebook version 3.2.3 or greater installed, or if Safari is on the device (or simulator), authorization now takes place OUTSIDE of the app. Will post more as I find it.

EDIT: Apart from the NSURL error, it seems that this is the expected behavior with the new Facebook SSO. Users are supposed to remain in a pseudo-logged in/logged out state after 'logging out' of your app, in case they are logged into another app, etc. - it's all connected now. To really log out of facebook (to say, log in as someone else, etc.) it seems that the user needs to click the logout link on the authorization webview that shows when they are "logged out" of facebook in your app. I could be wrong but I'm pretty sure about this.

Apart from the above, I did find a way to get rid of the NSURL error and this makes things a lot better, and much more palatable. See How Do I Fix NSURLErrorDomain Error -999 in iPhone.

For more on the new Facebook SSO:

Excerpt from Facebook iOS Tutorial (see especially last paragraph):

Step 3: Implementing Single Sign-On (SSO)

One of the most compelling features of the iOS SDK is Single-Sign-On (SSO). SSO lets users sign into your app using their Facebook identity. If they are already signed into the Facebook iOS app on their device they do not have to even type a username and password. Further, because they are signing to your app with their Facebook identity, you can get permission from the user to access to their profile information and social graph.

SSO primarily works by redirecting the user to the Facebook app on her device. Since the user is already logged into Facebook, they will not need to enter their username and password to identify themselves. They will see the auth dialog with the permissions that your app has asked for and if they allow then they will be redirected to your app with the appropriate access_token.

Developers should be aware that Facebook SSO will behave slightly different depending on what is installed on the user's device. This is what happens in certain configurations:

If the app is running in a version of iOS that supports multitasking, and if the device has the Facebook app of version 3.2.3 or greater installed, the SDK attempts to open the authorization dialog within the Facebook app. After the user grants or declines the authorization, the Facebook app redirects back to the calling app, passing the authorization token, expiration, and any other parameters the Facebook OAuth server may return.

If the device is running in a version of iOS that supports multitasking, but it doesn't have the Facebook app of version 3.2.3 or greater installed, the SDK will open the authorization dialog in Safari. After the user grants or revokes the authorization, Safari redirects back to the calling app. Similar to the Facebook app based authorization, this allows multiple apps to share the same Facebook user access_token through the Safari cookie.

If the app is running a version of iOS that does not support multitasking, the SDK uses the old mechanism of popping up an inline UIWebView, prompting the user to log in and grant access. The FBSessionDelegate is a callback interface that your app should implement: The delegate's methods will be invoked when the app successful logs in or logs out. Read the iOS SDK documentation for more details on this delegate.

...

When the user wants to stop using Facebook integration with your app, you can call the logout method to clear the app state and make a server request to invalidate the current access_token.

[facebook logout:self]; You may implement the fbDidLogout method of the FBSessionDelegate protocol to handle any post-logout actions you wish to take.

Note that logging out will not revoke your application's permissions, but will simply clear your application's access_token. If a user that has previously logged out of your app returns, they will simply see a notification that they are logging into your app, not a notification to grant permissions. To modify or revoke an application's permissions, the user can visit the "Applications, Games, and Websites" tab of their Facebook privacy settings dashboard. You can also revoke an app's permissions programmatically using a Graph API call.

Hope this helps, let me know if you find anything different.

Community
  • 1
  • 1
SAHM
  • 4,078
  • 7
  • 41
  • 77