我正在尝试创建帮助程序来验证和请求 Facebook 的发布权限。Facebook 有一个非常令人困惑的 API,例如[FBSession openActiveSessionWithReadPermissions:allowLoginUI:completionHandler:]
, wherecompletionHandler
不是你想的那样。completionHandler
每次会话状态更改时都会混淆地调用,而不是在openActiveSession
完成时调用。
我的流程非常简单。问题是我偶尔会收到那些常见的 FBSession 错误,例如FBSession: an attempt was made reauthorize permissions on an unopened session
.
谁能告诉我我可能做错了什么?
- (void)openSessionWithBasicInfoThenRequestPublishPermissions:(void(^)(NSError *error))completionBlock
{
[self openSessionWithBasicInfo:^(NSError *error) {
if(error) {
completionBlock(error);
return;
}
[self requestPublishPermissions:^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(error);
});
}];
}];
}
- (void)openSessionWithBasicInfo:(void(^)(NSError *error))completionBlock
{
if([[FBSession activeSession] isOpen]) {
completionBlock(nil);
return;
}
self.openBlock = completionBlock;
[FBSession openActiveSessionWithReadPermissions:@[@"basic_info"] allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self sessionStateChanged:session state:status error:error open:YES permissions:NO];
});
}];
}
static NSString *const publish_actions = @"publish_actions";
- (void)requestPublishPermissions:(void(^)(NSError *error))completionBlock
{
if([[[FBSession activeSession] permissions] indexOfObject:publish_actions] != NSNotFound) {
completionBlock(nil);
return;
}
self.permissionsBlock = completionBlock;
[FBSession.activeSession requestNewPublishPermissions:@[publish_actions] defaultAudience:FBSessionDefaultAudienceEveryone completionHandler:^(FBSession *session, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self sessionStateChanged:session state:session.state error:error open:NO permissions:YES];
});
}];
}
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState)state error:(NSError *)error open:(BOOL)open permissions:(BOOL)permissions
{
if(self.openBlock && open) {
dispatch_async(dispatch_get_main_queue(), ^{
self.openBlock(error);
self.openBlock = nil;
});
}
else if(self.permissionsBlock && permissions) {
dispatch_async(dispatch_get_main_queue(), ^{
self.permissionsBlock(error);
self.permissionsBlock = nil;
});
}
}
我对完成块的目标不是每次会话状态更改时都调用它们,而是在我打开会话并在完成时在用户墙上发布的一次性使用块。这就是为什么我将块存储在一个属性上,然后在使用后将它们清零。