使用[FBSession openActiveSessionWithPublishPermissions:..]时出错

时间:2012-10-10 00:35:56

标签: ios facebook-ios-sdk

我正在更新应用以使用最新的Facebook SDK,以便获得对iOS6原生Facebook支持的访问权限。它目前使用的是旧版本的Facebook SDK。

该应用程序需要Facebook的“publish_actions”权限才能与Facebook合作。

我最初认为我可以使用[FBSession openActiveSessionWithPublishPermissions: ...]但是当用户在iOS6设置中配置了Facebook时,这在iOS6上失败了。由于此要求,from the Facebook docs

,它失败了
  

请注意,要使用iOS 6原生身份验证,应用需要更改其请求方式   用户的权限 - 应用必须将他们的读取请求分开   并写入权限。适用于iOS的Facebook SDK支持这些   功能并帮助开发人员使用它们来构建可用的应用程序   多个iOS版本和设备配置。

这是一个大型的PITA,IMO。我们的偏好是提示用户一次获得许可并完成它,但每个Apple / Facebook的“新”理想是在需要但尚未授予时在上下文中提示特定权限。

目前的计划是保留iOS5用户和未在“设置”中配置Facebook的iOS6用户的旧行为。并符合使用原生访问的iOS6用户的新双提示。

问题是,最好的方法是什么?我应该如何检测Facebook SDK是否会选择iOS6原生登录与后备机制?我忽略了一些明显的东西吗?

修改

杰拉尔德威廉姆让我走上正轨。他的解决方案几乎可以工作,除了在iOS5中没有ACAccountTypeIdentifierFacebook。此外,如果用户阻止设置中的FB访问应用程序,则accountsWithAccountType调用将返回一个空数组。

可以通过询问帐户类型匹配标识符“com.apple.facebook”来解决第一个问题 - 这将在iOS5上返回nil,在iOS6上返回真实帐户类型对象。

但第二个问题是无法解决的。我的新计划是始终在iOS6上以只读权限打开初始会话,并在上下文中根据需要提示发布权限。在iOS5上,我仍然会打开初始会话,指定所需的publish_actions权限。这是代码:

ACAccountStore* as = [[ACAccountStore new] autorelease]; 
ACAccountType* at = [as accountTypeWithAccountTypeIdentifier: @"com.apple.facebook"]; 
if ( at != nil ) {
    // iOS6+, call  [FBSession openActiveSessionWithReadPermissions: ...]

} else  {
    // iOS5, call [FBSession openActiveSessionWithPublishPermissions: ...] 
}

4 个答案:

答案 0 :(得分:6)

基于我在Facebook的开发者网站上阅读的所有内容(这有些矛盾),“仅发布”应用程序的工作流程并不是他们经常想到的,Apple / iOS似乎完全被忽视了

Facebook在docs you referenced中提供了一些指导:

  

技巧5:禁用本机登录对话

     

在某些情况下,应用可能会选择禁用本机登录对话框以使用新版本的Facebook SDK,但要避免重写他们向用户请求权限的方式。要使用fast-app-switch的先前行为进行登录,请使用已弃用的FBSession方法openActiveSessionWithPermissions并重新授权WithPermissions。

这是我目前正在关注的路线。略有不同,但效果相同。

if (FBSession.activeSession.isOpen  == NO) {
    // This will bypass the ios6 integration since it does not allow for a session to be opened
    // with publish only permissions!
    FBSession* sess = [[FBSession alloc] initWithPermissions:[NSArray arrayWithObject:@"publish_actions"]];
    [FBSession setActiveSession:sess];
    [sess openWithBehavior:(FBSessionLoginBehaviorWithFallbackToWebView) completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
        [self onSessionStateChange:session
                          andState:status
                          andError:error];
    }];

结果是,该应用程序将始终绕过IOS6集成以进行签名发布,并且在大多数情况下(因为用户通常已经在手机上安装了Facebook)切换到Facebook应用程序以进行单一授权批准。 / p>

如果用户选择使用他们的Facebook帐户登录我们的应用程序,我会拨打openActiveSessionWithReadPermissions,如果有,我将使用IOS6 Facebook集成。如果他们随后决定分享,我会致电reauthorizeWithPublishPermissions,如果可以的话,我也会使用IOS6集成。

鉴于可用的文档极少且令人困惑,我无法确定这是否是解决此问题的“正确”方法,但它似乎有效。您可以为IOS5或IOS6应用程序使用相同的代码,因为它只通过Facebook SDK进行调用。它还尊重Facebook现在推广的同一请求中不混合的读/发权限。

答案 1 :(得分:5)

ACAccountStore *store = [[ACAccountStore alloc] init];

ACAccountType *accountType  = [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSArray *accounts = [store accountsWithAccountType:accountType];
NSLog(@"accounts:%@", accounts);

如果account为nil(或者它可能返回一个空数组,我不确定),那么用户还没有在iOS6中配置Facebook。您可以测试它,如果值表明Facebook尚未配置iOS6,您可以调用您的回退机制。

答案 2 :(得分:2)

而不是使用以下内容:

NSArray *readPermissions = [[NSArray alloc]         initWithObjects:@"email",@"friends_location",@"status_update",@"publish_actions",nil];
[FBSession openActiveSessionWithPublishPermissions:readPermissions defaultAudience:FBSessionDefaultAudienceEveryone allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
//Your code here for handling forward things;
}

使用此代码:

NSArray *readPermissions = [[NSArray alloc] initWithObjects:@"email",@"friends_location",@"status_update",@"publish_actions",nil];
FBSession* sess = [[FBSession alloc] initWithPermissions:[NSArray arrayWithObject:readPermissions]];
[FBSession setActiveSession:sess];
[sess openWithBehavior:(FBSessionLoginBehaviorWithFallbackToWebView) completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
    [self onSessionStateChange:session
                      andState:status
                      andError:error];

//Your code here for handling forward things;

}];

答案 3 :(得分:0)

很抱歉,但在ios6中对我来说 这条线

ACAccountType* at = [as accountTypeWithAccountTypeIdentifier: @"com.apple.facebook"];

即使用户没有配置帐户,也不会返回nil

这意味着你可以查看用户的ios版本是什么(5或6)

NSString *currSysVer = [[UIDevice currentDevice] systemVersion];

This link可能会有所帮助。