必须指定 FBSession 解析

Posted

技术标签:

【中文标题】必须指定 FBSession 解析【英文标题】:FBSession Must Be Specified Parse 【发布时间】:2015-01-04 05:07:09 【问题描述】:

我正在尝试遵循 Parse 使用 Facebook 登录的教程。但是,示例代码与指南不匹配,因此那里的代码毫无用处。我已完全按照指南进行操作,但登录后,它会将我定向到 Facebook 应用程序,我给予许可,它会返回到我正在构建的应用程序,但我收到以下错误

FBSDKLog: Error for request to endpoint 'me': An open FBSession must be specified for calls to this endpoint.

发生了什么事?在登录控制器中:

- (void)viewWillAppear:(BOOL)animated 
    [super viewWillAppear:animated];


    FBRequest *request = [FBRequest requestForMe];
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) 
        if (!error) 
            // handle successful response
         else if ([[[[error userInfo] objectForKey:@"error"] objectForKey:@"type"]
                    isEqualToString: @"OAuthException"])  // Since the request failed, we can check if it was due to an invalid session
            NSLog(@"The facebook session was invalidated");
            [self logoutButtonAction:nil];
         else 
            NSLog(@"Some other error: %@", error);
        
    ];
    if ([PFUser currentUser] && // Check if user is cached
        [PFFacebookUtils isLinkedWithUser:[PFUser currentUser]])  // Check if user is linked to Facebook
        // Present the next view controller without animation
        [self _presentUserDetailsViewControllerAnimated:NO];
    

- (IBAction)loginButtonTouchHandler:(id)sender  
    // Set permissions required from the facebook user account
    NSArray *permissionsArray = @[ @"user_about_me", @"user_relationships", @"user_birthday", @"user_location"];
    [PFFacebookUtils initializeFacebook];
    // Login PFUser using Facebook
    [PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) 
        [_activityIndicator stopAnimating]; // Hide loading indicator

        if (!user) 
            NSString *errorMessage = nil;
            if (!error) 
                NSLog(@"Uh oh. The user cancelled the Facebook login.");
                errorMessage = @"Uh oh. The user cancelled the Facebook login.";
             else 
                NSLog(@"Uh oh. An error occurred: %@", error);
                errorMessage = [error localizedDescription];
            
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Log In Error"
                                                            message:errorMessage
                                                           delegate:nil
                                                  cancelButtonTitle:nil
                                                  otherButtonTitles:@"Dismiss", nil];
            [alert show];
         else 
            if (user.isNew) 
                NSLog(@"User with facebook signed up and logged in!");
             else 
                NSLog(@"User with facebook logged in!");
            
            [self _presentUserDetailsViewControllerAnimated:YES];
        
    ];

    [_activityIndicator startAnimating]; // Show loading indicator until login is finished


- (void)_presentUserDetailsViewControllerAnimated:(BOOL)animated 
    UserDetailsViewController *detailsViewController = [[UserDetailsViewController alloc] init];
    [self.navigationController pushViewController:detailsViewController animated:YES];

在我的 UserDetailsViewController 中:

- (void)viewDidLoad 
    // ...
    [self _loadData];


- (void)_loadData 
    // ...
    FBRequest *request = [FBRequest requestForMe];
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) 
        if (!error) 
            // result is a dictionary with the user's Facebook data
            NSDictionary *userData = (NSDictionary *)result;

            NSString *facebookID = userData[@"id"];
            NSString *name = userData[@"name"];
            NSString *location = userData[@"location"][@"name"];
            NSString *gender = userData[@"gender"];
            NSString *birthday = userData[@"birthday"];
            NSString *relationship = userData[@"relationship_status"];

            NSURL *pictureURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=large&return_ssl_resources=1", facebookID]];
            // URL should point to https://graph.facebook.com/facebookId/picture?type=large&return_ssl_resources=1
                       NSURLRequest *urlRequest = [NSURLRequest requestWithURL:pictureURL];

            // Run network request asynchronously
            [NSURLConnection sendAsynchronousRequest:urlRequest
                                               queue:[NSOperationQueue mainQueue]
                                   completionHandler:
             ^(NSURLResponse *response, NSData *data, NSError *connectionError) 
                 if (connectionError == nil && data != nil) 
                     // Set the image in the header imageView
                     self.headerImageView.image = [UIImage imageWithData:data];
                 
             ];

            // Now add the data to the UI elements
            // ...
        
    ];


【问题讨论】:

两个问题:一,你在哪里看到错误? (我假设通过您的登录回调中的警报,因为您描述了从 Facebook 返回后发生这种情况)二,您是否在应用程序的 appDelegate 中调用 [PFFacebookUtils initializeFacebook]:didFinishLaunchingWithOptions:?我相信那个调用也应该初始化会话。 - 哎呀,刚刚在你的方法中看到了初始化,我仍然建议将它移到应用程序委托 如果用户被缓存,您可能会想到另一个想法。也许注销并再次尝试会有所帮助。由于在按下登录按钮之前您不会初始化 Facebook,如果用户被缓存并且您转换到下一个屏幕,您可能会在初始化 Facebook 之前尝试 requestForMe。这可能会抛出没有打开会话的错误。 我将尝试将其移至应用程序委托。我没有把它放在那里,因为我只是按照教程,把它放在他们说的地方。愚蠢的我认为公司可以正确地获得自己的教程。 哈哈,让我知道这是否有效。我不确定缓存剩余登录是否存在问题,但看起来在初始化 Facebook 之前尝试登录缓存的用户,这将是一个问题。如果您从未通过第一次登录,那就不会是这种情况,但如果是这样,那么它是可能的! 很高兴听到!我会发布一个答案,以防其他人偶然发现这个 【参考方案1】:

我们在尝试使用此功能创建自动登录功能时发现了这一点:

- (void)viewWillAppear:(BOOL)animated 
    [super viewWillAppear:animated];
    FBRequest *request = [FBRequest requestForMe];
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) 
        if (!error) 
            // handle successful response
         else if ([[[[error userInfo] objectForKey:@"error"] objectForKey:@"type"]
                isEqualToString: @"OAuthException"])  // Since the request failed, we can check if it was due to an invalid session
            NSLog(@"The facebook session was invalidated");
            [self logoutButtonAction:nil];
         else 
            NSLog(@"Some other error: %@", error);
        
    ];
    if ([PFUser currentUser] && // Check if user is cached
        [PFFacebookUtils isLinkedWithUser:[PFUser currentUser]])  // Check if user is linked to Facebook
        // Present the next view controller without animation
        [self _presentUserDetailsViewControllerAnimated:NO];
    
  

我们实际上最终跳过了 [PFFacebookUtils initializeFacebook] 调用,因为它仅在您按下登录按钮时发生。解决方案是将此调用放入appDelegate中的方法application:didFinishLaunchingWithOptions:

【讨论】:

以上是关于必须指定 FBSession 解析的主要内容,如果未能解决你的问题,请参考以下文章

使用未解析的标识符 FBSession

在 iOS 上使用现有令牌数据打开 FBSession

Facebook SDK 3.0 会话

初始 FBSession 检查始终失败

一次登录成功后,FBSession 返回 FBSessionStateClosedLoginFailed

FBSession.activeSession.permissions 似乎没有准确描述有效的授予权限