1

我正在尝试创建帮助程序来验证和请求 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;
        });
    }
}

我对完成块的目标不是每次会话状态更改时都调用它们,而是在我打开会话并在完成时在用户墙上发布的一次性使用块。这就是为什么我将块存储在一个属性上,然后在使用后将它们清零。

4

0 回答 0