6

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

该应用程序需要 Facebook 的“publish_actions”许可才能对 Facebook 进行唯一的操作。

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

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

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

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

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

编辑:

gerraldWilliam 让我走上了正轨。他的解决方案几乎可以工作,除了 ACAccountTypeIdentifierFacebook 在 iOS5 中不可用。此外,如果用户在设置中阻止 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

4 回答 4

6

根据我在 Facebook 的开发者网站上阅读的所有内容(这有点矛盾),“仅发布”应用程序的工作流程并不是他们考虑太多的事情,Apple/iOS 似乎完全无视。

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

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

在某些情况下,应用程序可能会选择禁用本机登录对话框以使用新版本的 Facebook SDK,但避免重写它们向用户请求权限的方式。要使用之前的快速应用切换行为进行登录,请使用已弃用的 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 集成进行登录以进行发布,并且在大多数情况下(因为用户通常已经在手机上安装了 Facebook)切换到 Facebook 应用程序以获得单一的身份验证批准。

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

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

于 2013-01-23T13:37:08.560 回答
5
ACAccountStore *store = [[ACAccountStore alloc] init];

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

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

于 2012-10-10T03:36:00.247 回答
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;

}];
于 2013-07-19T02:14:53.923 回答
0

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

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

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

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

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

此链接可能会有所帮助。

于 2012-12-19T09:35:24.773 回答