iOS上的Facebook FBConnect SDK问题

问题描述:

我正在使用FBConnect sdk为了通过我的应用程序向用户的个人资料发布帖子。我遇到以下几个问题:iOS上的Facebook FBConnect SDK问题

当相关代码第一次在设备上运行时,用户被重定向到Facebook应用程序/网站,并要求他授权它。如果用户授权它,它将返回到应用程序,该应用程序弹出一个“连接到Facebook”视图控制器,要求用户登录。这很奇怪,因为用户已经登录,否则他怎么可能授权应用程序?但我想这可能是好的,因为他还没有通过应用程序登录。登录后,它什么都不做。只有第二次运行代码后,他授权应用程序,用户才能获取发布对话框。

如果用户没有授权该应用程序,当它在授权对话框后回到我的应用程序时,它会要求用户登录(就像他已经授权),并且在他登录后不做任何事情。第二次代码运行,授权对话框打开,optinos“授权”&“离开应用程序”,而不是“授权”&“不授权”/“允许”&“不允许”。另外,如果用户通过他在Facebook上的帐户设置删除了他的授权,而不是只是要求他重新授权,那么会弹出一个facebook对话框(而不是发布/授权对话框),并说:“An发生错误,请稍后再试。“以后尝试不会有帮助。它会一直弹出,即使你重新启动应用程序。让它消失的唯一方法是重新安装应用程序,这会导致它重新弹出授权对话框。

因此,这里是我想达到的目标:用户授权的应用程序

  1. 后,他就不必再次登录。
  2. 在用户授权应用程序后,发布对话框将立即弹出,而不必重新运行代码(这是通过按钮触发的)。
  3. 如果用户未授权的应用程序,他将再次与授权对话框提示,而不是错误对话框
  4. 如果他拒绝授权,我将调用显示错误/等功能。

下面是相关代码:

MyViewController.m

- (void)shareOnFacebook 
{ 
    Facebook *facebook = [[Facebook alloc] initWithAppId:myAppID]; 
    [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] setFacebook:facebook]; 
    [facebook release]; 
    facebook = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] facebook]; 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    if ([defaults objectForKey:@"FBAccessTokenKey"] && [defaults objectForKey:@"FBExpirationDateKey"]) { 
     facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"]; 
     facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"]; 
    } 
    if (![facebook isSessionValid]) { 
     [facebook authorize:[NSArray arrayWithObjects:@"publish_stream", nil] delegate:(MyAppDelegate *)[[UIApplication sharedApplication] delegate]]; 
    } 

    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 
    //Giving the dictionary some parameters for posting defaults 
    [facebook dialog:@"feed" andParams:dictionary andDelegate:self]; //Note: we have 2 different delegates! appDelegate for connections & url switching, and self for dialogs 
} 

MyAppDelegate.h

@interface MyAppDelegate : NSObject <UIApplicationDelegate, FBSessionDelegate, FBDialogDelegate> 
{ 
    Facebook *facebook; // kept for facebook sharing, accessed only from MyViewController although delegate methods are handeled in here 
} 
@property (nonatomic, retain) Facebook *facebook; 

@end 

MyAppDelegate.m

- (void)fbDidLogin 
{ 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    [defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"]; 
    [defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"]; 
    [defaults synchronize]; 
} 

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url 
{ 
    return [self.facebook handleOpenURL:url]; 
} 

是否有可能我在MyViewController上遗漏了一些委托函数?因为我看到出于某种原因,我已经标记为实现FBDialogDelegate协议,尽管他没有从那里实现任何功能。

如果你们能帮助我,我会很高兴,因为这对我来说是非常令人沮丧的。我在互联网上找不到任何东西,我觉得我在这里溺水了。

Tnx提前!

+0

这可能不是您的问题的答案,但在我看来,您可能遇到的一个问题是每个共享上重新创建的Facebook实例。从文档看来,Facebook实例通常添加到AppDelegate,并且在应用程序运行时从不重新分配。也许看看我为我正在编写的项目编写的代码,它可能更容易解决您的问题(它还不完美,但似乎就分享而言工作得很好):http://*.com/questions/7085162/facebook-connect-class-with-singleton-access-token-issue/7085809#7085809 –

第一:

[facebook authorize:[NSArray arrayWithObjects:@"publish_stream",@"offline_access",nil] delegate:self]; 

offline_access关键在这里将让您的身份验证令牌活着永远(或者更具体地说,直到用户手动取消授权在他们的Facebook的应用程序设置你的应用程序帐号设定)。此外,将您的活动VC设置为委托(稍后会详细介绍)。

其次:

-(void)popUserShareFeed { 
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 
    //Giving the dictionary some parameters for posting defaults 
    [facebook dialog:@"feed" andParams:dictionary andDelegate:self]; 
} 

呼叫在-fbDidLogin委托方法这个方法(或一个喜欢它)。也称它在你原来的方法,如果会话仍然有效,即:

if (![facebook isSessionValid]) { 
     [facebook authorize:[NSArray arrayWithObjects:@"publish_stream", nil] delegate:(MyAppDelegate *)[[UIApplication sharedApplication] delegate]]; 
} else { 
    [self popUserShareFeed]; 
} 

...和你的新fbDidLogin

- (void)fbDidLogin 
{ 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    [defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"]; 
    [defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"]; 
    [defaults synchronize]; 
    [self popUserShareFeed]; 
} 

(注:你必须在MyViewController.m定义此并用它作为您的FBSessionDelegate。它在功能上等效。您的AppDelegate不需要也是您的FBSessionDelegate

三:

落实-fbDidNotLogin:(BOOL)cancelledFBSessionDelegate方法,像这样:

-(void)fbDidNotLogin:(BOOL)cancelled { 
    if (cancelled) { 
     ... some alert about the user cancelling... 
    } else { 
     ... some alert about how it failed for some reason... 
    } 
} 

第四,至于你比扎罗错误去:A)在一般的Facebook的软件开发工具包并不大,和B)我只设置身份验证令牌和你facebook对象上的失效日期,如果

A)你不已经有一个实例化(即,它是nil

and

B)您设置的过期日期是未来(即, timeIntervalSinceNow [NSDate实例方法]调用它返回> 0)。

听起来就像您遇到了此Facebook Platform Developer forum post中所述的相同问题。我遇到了同样的问题,但在网络上。该线程中只有一个来自Facebook的回复,并且这是错误的信息。

Facebook有史以来最糟糕的开发人员文档和开发人员支持,我不会屏住呼吸等待解决方案。

我已将FBConnect集成到如此多的应用程序中,但从未遇到过这样的关键问题。所以,你的代码中会缺少一些东西:

检查FBAccessTokenKey &没有检查FBExpirationDateKey,只需使用FBConnect的FBSession类的会话对象。

只是尝试使用我的代码有几个conidtions:

session = [[FBSession sessionForApplication:@"key" secret:@"AppSecretKey" delegate:self] retain]; 
     [session resume]; 
     _posting = YES; 

     // If we're not logged in, log in first... 
     if (![session isConnected]) { 
      loginDialog = nil; 
      loginDialog = [[FBLoginDialog alloc] init]; 
      [loginDialog show]; 
     } 
      // If we have a session and a name, post to the wall! 
      else if (_facebookName != nil) { 
         [self postToWall]; // Over here posting dialog will appear , if user has already logged in or session is running. 
        } 

     } 
     else { 
      [FBBtn setTitle:@"Login" forState:UIControlStateNormal]; // if you want to change the title of button 
      [session logout]; 
     } 

另外采取dealloc方法释放会话对象的照顾而已,而不是任何其他方法将其释放。

- (void)dealloc { 
     [super dealloc]; 
     [session release]; 
     session = nil; 
    } 

希望能解决您的问题。

+0

你能提供更多的代码/信息吗?我找不到这门课。我得到的只有Facebook,FBDialog,FBLoginDialog和FBRequest。 – Niv

+2

@Niv他使用旧版的Facebook SDK - FBConnect。您正在使用新版本 - Facebook iOS SDK。 –

不是直接的解决方案为您的代码的问题,但...

你有没有考虑使用开源的库呢? ShareKit就是一个很好的例子:http://getsharekit.com。整合非常简单,它可以满足您的一切需求。

+1

我从ShareKit本身收到这个错误(这个页面是我在Google上第一次点击,试图调试ShareKit)。 ShareKit是可怕的 - Facebook的文档总数说“没有设置Facebook”,这显然是不真实的。我会建议避免它 - 我即将切换回FB iOS SDK,因为ShareKit太糟糕了。 – Adam

我有完全相同的问题,并用本毛思迪的响应上面,但我也决定创建一个Facebook对象一个简单的单例类,所以,在我的AppDelegate我可以处理以下功能正常:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url 
    sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 

    return [[[FBManager defaultManager] facebook] handleOpenURL:url]; 

    //return [facebook handleOpenURL:url]; 
} 

我的单例类是FBSessionDelegateFBDialogDelegate,所以它处理相应的方法。

这允许我只提示用户在他们实际尝试发布内容时登录,而不是在应用程序启动时登录。

我有类似但并非相同的问题:消息“发生错误,请稍后再试。”始终显示。

问题在于没有正确配置的应用程序ID - 它是由客户提供的(所以我不确定是什么错误);一切工作正常,因为我用我自己的测试应用程序ID(从以前的应用程序)取代它。