我正在更新应用以使用最新的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: ...]
}
答案 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可能会有所帮助。