使用时出错

我正在更新应用程序以使用最新的Facebook SDK以访问iOS6原生Facebook支持。 它目前使用一个漂亮的旧版本的Facebook SDK。

该应用程序需要Facebook的“publish_actions”权限才能使用Facebook的唯一function。

我最初以为我可以使用[FBSession openActiveSessionWithPublishPermissions: ...]但是当用户在iOS6设置中configuration了Facebook时,这在iOS6上失败。 由于这个要求, 从Facebook文档中失败:

请注意,要使用iOS 6本地身份validation,应用程序需要更改用户向用户请求权限的方式 – 应用程序必须将读取和写入权限的请求分开。 适用于iOS的Facebook SDK支持这些function,并帮助开发人员使用它们构build适用于多个iOS版本和设备configuration的应用程序。

这是一个大的PITA,IMO。 我们的首选是提醒用户一次许可并完成它,但每个Apple / Facebook的“新”理想是在需要但尚未授予的情况下提示特定的权限。

目前的计划是保留我们对iOS5用户和未在设置中configurationFacebook的iOS6用户的旧行为。 并符合使用本机访问的iOS6用户的新的双提示。

问题是,做这件事的最好方法是什么? 我应该如何去检测Facebook SDK是否会selectiOS6本地login与回退机制? 我可以忽略明显的东西吗?

编辑:

杰拉德威廉把我放到正确的轨道上。 他的解决scheme几乎可以工作,除了ACAccountTypeIdentifierFacebook在iOS5中不可用。 另外,如果用户阻止FB在设置中访问应用程序,那么accountsWithAccountType调用将返回一个空数组。

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

但第二个问题是无法解决的。 我的新计划是始终在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: ...] } 

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

如果帐户是零(或者它可能会返回一个空数组,我不确定),那么用户还没有在iOS6中configurationFacebook。 你可以testing一下,如果这个值表明Facebook还没有configurationiOS6,你可以调用你的回退机制。

基于我在Facebook的开发者网站上阅读的所有内容(这有些矛盾),“只发布”应用程序的工作stream程并不是他们已经考虑过的,苹果/ iOS似乎完全忽视了这一点。

Facebook在您引用的文档中提供了一些指导:

提示5:禁用本地login对话框

在某些情况下,应用程序可能会select禁用本地login对话框来使用Facebook SDK的新版本,但要避免重写他们向用户请求权限的方式。 要使用fast-app-switch以前的行为进行login,请使用不推荐使用的FBSession方法openActiveSessionWithPermissions和reauthorizeWithPermissions。

这是我目前正在遵循的路线。 略有不同,但总体效果相同。

 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集成login发布,在大多数情况下(因为用户通常已经在手机上安装了Facebook)切换到Facebook应用程序进行单个授权审批。

如果用户select使用他们的Facebook帐户login我们的应用程序,我打电话给openActiveSessionWithReadPermissions ,如果有的话,将使用IOS6 Facebook集成。 如果他们随后决定分享,那么我会调用reauthorizeWithPublishPermissions,如果可用的话,也会使用IOS6集成。

鉴于可用的最小和混乱的文件,我不能确定这是否是“正确”的方式来处理这个,但似乎工作。 您可以使用IOS5或IOS6应用程序相同的代码,因为它只能通过Facebook SDK进行调用。 它还尊重Facebook中现在正在推广的同一请求中不混合的读取/发布权限。

而不是使用以下内容:

 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; }]; 

对不起,但对我来说,在ios6线

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

即使用户没有configuration帐户,也不返回nil

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

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

此链接可能有帮助。