繁体   English   中英

Facebook 的 FBConnect SDK 问题出现在 iOS

[英]Facebook's FBConnect SDK issues on iOS

我正在使用 FBConnect sdk 通过我的应用程序将帖子发布到用户的个人资料。 我对此有很多问题:

当相关代码在设备上首次运行时,用户会根据需要被重定向到 facebook 应用程序/网站,并要求他对其进行授权。 如果用户授权它,它返回到应用程序,弹出一个“连接到 facebook”视图 controller 要求用户登录。这很奇怪,因为用户已经登录,否则他怎么能授权应用程序? 但我想这可能没问题,因为他还没有通过应用程序登录。 他登录后,它什么也不做。 只有在第二次运行代码时,在他授权应用程序后,用户才会获得发布对话框。

如果用户没有授权该应用程序,当它在授权对话框后返回我的应用程序时,它会要求用户登录(就像他授权一样),并且在他登录后什么也不做。只有第二次代码运行,授权对话框打开,使用 optinos“授权”和“离开应用程序”,而不是“授权”和“不授权”/“允许”和“不允许”。

此外,如果用户通过他的帐户在 facebook 上的设置删除了他的授权,而不是仅仅要求他重新授权,则会弹出一个 facebook 对话框(而不是发布/授权对话框),说:“发生错误。请稍后再试。” 以后再试也没有用。 即使您重新启动应用程序,它也会始终弹出。 使其 go 消失的唯一方法是重新安装应用程序,这将导致它重新弹出授权对话框。

所以这就是我想要实现的目标:

  1. 用户授权应用程序后,他不必再次登录。
  2. 用户授权应用程序后,发布对话框将立即弹出,而无需他重新运行代码(顺便说一句,使用按钮触发)。
  3. 如果用户取消对应用程序的授权,将再次使用授权对话框提示他,而不是错误对话框
  4. 如果他拒绝授权,我将调用显示错误/等的 function。

以下是相关代码:

我的视图控制器.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 协议,尽管他没有从那里实现任何 function。

如果你们能帮助我,我会非常高兴,因为这对我来说非常令人沮丧。 我在互联网上找不到任何关于此的内容,我觉得我在这里淹死了。

提前Tnx!

第一的:

[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委托方法中调用此方法(或类似方法)。 如果 session 仍然有效,也可以在您的原始方法中调用它,即:

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)cancelled FBSessionDelegate方法,如下所示:

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

Fourth, as far as your bizarro errors go: A) the Facebook SDKs in general are not great, and B) I'd only set the auth token and the expiration date on your facebook object if

A)您还没有实例化一个(即,它是nil

B)您设置的expirationDate 在未来(即timeIntervalSinceNow [ NSDate实例方法] 调用它返回> 0)。

听起来您遇到了此Facebook 平台开发人员论坛帖子中描述的相同问题。 我遇到了同样的问题,但在 web 上。 Facebook 在该线程中只给出了一个响应,这是错误的信息。

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

我有类似但不同的问题:消息“发生错误。请稍后再试。” 一直显示。

问题在于未正确配置 App ID - 它是由客户提供的(所以我不确定到底出了什么问题); 一切正常,因为我用我自己的测试应用程序 ID(来自以前的应用程序)替换了它。

我已经在很多应用程序中集成了 FBConnect,但从未遇到过这样的关键问题。 因此,您的代码中会缺少一些东西:

要检查 FBAccessTokenKey 和 FBExpirationDateKey,只需尝试使用 FBConnect 的 session object 的 FBSession class 即可。

只需尝试使用很少条件的我的代码:

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 方法中释放 session object,而不是在任何其他方法中释放它。

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

希望这能解决您的问题。

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

您是否考虑过为此使用开源库? ShareKit 就是一个很好的例子: http://getsharekit.com 集成非常简单,它可以满足您的一切需求。

I was having the exact same issue, and used Ben Mosher's response above, but I also decided to create a simple singleton class for the Facebook object, so that in my AppDelegate I can handle the following function properly:

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

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

    //return [facebook handleOpenURL:url]; 
}

我的 singleton class 既是FBSessionDelegate又是FBDialogDelegate ,所以它处理相应的方法。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM