【问题标题】:Facebook-ios-sdk with embedded UIWebView带有嵌入式 UIWebView 的 Facebook-ios-sdk
【发布时间】:2010-12-26 21:22:31
【问题描述】:

我正在使用新的 facebook-ios-sdk 并已成功地将 api 集成到我的本机应用程序中。我能够使用带有 ios-sdk 类的弹出对话框验证用户并正确设置权限。

对于我的应用程序的一部分,我需要在UIWebView 中使用 facebook 连接,使用 javascript 和 html 来处理 webview 中的数据。鉴于用户已经通过上述例程登录并进行了身份验证,我会假设UIWebView 将共享这些凭据,或者至少会有某种方式将凭据传递或分配给 webview。

不幸的是,我发现这个较早的帖子似乎表明这个方案不太有效(iOS - being logged-in in a webView after logging in with the SDK)。有没有其他人遇到过这个和/或找到解决方法?这似乎是一个相当简单的用例,因为我没有尝试启动移动 safari 或类似的东西 - 它都在同一个本机应用程序中。

似乎我缺少某种简单的技巧或设置。也许以某种方式在新的UIWebView 中设置cookie?或类似的东西?

【问题讨论】:

  • 这也是我的问题,但看起来没有希望得到答案:(
  • 差不多 2 年后,我遇到了同样的问题。同时有什么解决办法吗?

标签: facebook ios uiwebview


【解决方案1】:

--通过这种方式 Facebook-ios-sdk

@property (nonatomic, 保留) NSString *chk;

@end

@implementation SettingsViewController
@synthesize chk,viewFbLogin;
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell;
AppDelegate *appDelegate;
UIViewController *tweetComposer;
ACAccount *twitterAccount;
ACAccountStore *account;
ACAccountType *accountType;
NSArray *arrayOfAccounts ;
int arr_row_num;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
           }
    return self;
}


- (void)storeAccountWithAccessToken:(NSString *)token secret:(NSString *)secret
{
    //  Each account has a credential, which is comprised of a verified token and secret
    ACAccountCredential *credential =
    [[ACAccountCredential alloc] initWithOAuthToken:token tokenSecret:secret];

    //  Obtain the Twitter account type from the store
    accountType =
    [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];

    //  Create a new account of the intended type
    twitterAccount = [[ACAccount alloc] initWithAccountType:accountType];

    //  Attach the credential for this user
    twitterAccount.credential = credential;

    //  Finally, ask the account store instance to save the account
    //  Note: that the completion handler is not guaranteed to be executed
    //  on any thread, so care should be taken if you wish to update the UI, etc.
    [account saveAccount:twitterAccount withCompletionHandler:^(BOOL success, NSError *error) {
        if (success) {
            // we've stored the account!
            NSLog(@"the account was saved!");
        }
        else {
            //something went wrong, check value of error
            NSLog(@"the account was NOT saved");

            // see the note below regarding errors...
            //  this is only for demonstration purposes
            if ([[error domain] isEqualToString:ACErrorDomain]) {

                // The following error codes and descriptions are found in ACError.h
                switch ([error code]) {
                    case ACErrorAccountMissingRequiredProperty:
                        NSLog(@"Account wasn't saved because "
                              "it is missing a required property.");
                        break;
                    case ACErrorAccountAuthenticationFailed:
                        NSLog(@"Account wasn't saved because "
                              "authentication of the supplied "
                              "credential failed.");
                        break;
                    case ACErrorAccountTypeInvalid:
                        NSLog(@"Account wasn't saved because "
                              "the account type is invalid.");
                        break;
                    case ACErrorAccountAlreadyExists:
                        NSLog(@"Account wasn't added because "
                              "it already exists.");
                        break;
                    case ACErrorAccountNotFound:
                        NSLog(@"Account wasn't deleted because"
                              "it could not be found.");
                        break;
                    case ACErrorPermissionDenied:
                        NSLog(@"Permission Denied");
                        break;
                    case ACErrorUnknown:
                    default: // fall through for any unknown errors...
                        NSLog(@"An unknown error occurred.");
                        break;
                }
            } else {
                // handle other error domains and their associated response codes...
                NSLog(@"%@", [error localizedDescription]);
            }
        }
    }];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    account = [[ACAccountStore alloc] init];
    accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
    arrayOfAccounts = [account accountsWithAccountType:accountType]; 
   // [self storeAccountWithAccessToken:@"119745010-g6YqvIdpyvBvYuaweR5oI1V1h9ugIqlj0toetlqg" secret:@"ysBO2E6dgOWj2vKEFoC3PCEypMaPrpycy5WIeodUNro"];



    appDelegate= (AppDelegate *)[[UIApplication sharedApplication] delegate];
    chk=appDelegate.chk_login;

    if (!appDelegate.session.isOpen) {
        // create a fresh session object
        appDelegate.session = [[FBSession alloc] init];
        if (appDelegate.session.state == FBSessionStateCreatedTokenLoaded) {
            // even though we had a cached token, we need to login to make the session usable
            [appDelegate.session openWithCompletionHandler:^(FBSession *session,
                                                             FBSessionState status,
                                                             NSError *error) {
                // we recurse here, in order to update buttons and labels

            }];
        }
    }


    if ([chk isEqualToString:@"YES"] && (appDelegate.setting_flag==FALSE))
    {

        appDelegate.arr=[NSMutableArray arrayWithObjects:@"Change Password",@"Facebook Login",@"Twitter Login",nil];

    }

    else

    {
        if(appDelegate.setting_flag==FALSE) 
        appDelegate.arr=[NSMutableArray arrayWithObjects:@"Facebook Login",@"Twitter Login",nil];
    }



}


-(void) updateView
{



}
- (void)viewWillAppear:(BOOL)animated
{



}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}



- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [appDelegate.arr count];
}


- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{



  cell = [self.SettingsTable dequeueReusableCellWithIdentifier:CellIdentifier];
    if(!cell)
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];




    if([[appDelegate.arr objectAtIndex:indexPath.row] isEqualToString:@"Twitter Login"])
    {




        twitterAccount = [arrayOfAccounts objectAtIndex:0];
        NSLog(@"array=%@",[arrayOfAccounts objectAtIndex:0]);
        NSDictionary *tempDict = [[NSDictionary alloc] initWithDictionary:
                                  [twitterAccount dictionaryWithValuesForKeys:[NSArray arrayWithObject:@"properties"]]];
        NSString *tempUserID = [[tempDict objectForKey:@"properties"] objectForKey:@"user_id"];
        NSLog(@"temp=%@",tempUserID);






        if (!IsEmpty(tempUserID))
        {
            [appDelegate.arr replaceObjectAtIndex:indexPath.row withObject:@"Twitter Logout"];
            cell.textLabel.text=@"Twitter Logout";
        }
        else
        {
             cell.textLabel.text=[appDelegate.arr objectAtIndex:indexPath.row];
        }



    }

    else if([[appDelegate.arr objectAtIndex:indexPath.row] isEqualToString:@"Facebook Login"])
    {
        if (appDelegate.session.isOpen) {
            [appDelegate.arr replaceObjectAtIndex:indexPath.row withObject:@"Facebook Logout"];
            cell.textLabel.text=[appDelegate.arr objectAtIndex:indexPath.row];
        }
        else
        {
           cell.textLabel.text=[appDelegate.arr objectAtIndex:indexPath.row]; 
        }


    }

    else
    {

         cell.textLabel.text=[appDelegate.arr objectAtIndex:indexPath.row];
    }




    return cell;


}

- (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{



    if([[appDelegate.arr objectAtIndex:indexPath.row]isEqualToString:@"Change Password"] && [chk isEqualToString:@"YES"])
    {   [UIView  beginAnimations:nil context:NULL];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        [UIView setAnimationDuration:0.75];



        ForgetPasswordViewController *forgetPassView=[[ ForgetPasswordViewController   alloc] initWithNibName:@"ForgetPasswordViewController" bundle:[NSBundle mainBundle]];
        NSLog(@"Working table");


        [self.navigationController pushViewController:forgetPassView animated:YES];
        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
        [UIView commitAnimations];



    }

    else if([[appDelegate.arr objectAtIndex:indexPath.row]isEqualToString:@"Facebook Login"])
    {
        if (appDelegate.session.state != FBSessionStateCreated) {
            // Create a new, logged out session.
            appDelegate.session = [[FBSession alloc] init];
        }
        [appDelegate.session openWithCompletionHandler:^(FBSession *session,
                                                         FBSessionState status,
                                                         NSError *error) {
            // and here we make sure to update our UX according to the new session state
            if (appDelegate.session.isOpen) {

            [appDelegate.arr replaceObjectAtIndex:indexPath.row withObject:@"Facebook Logout"];
            [self.SettingsTable reloadData];
            }

        }];

【讨论】:

    【解决方案2】:

    我可能会在这种方法中获得访问令牌

    func loginViewFetchedUserInfo(loginView: FBLoginView, user:FBGraphUser ) {
        println(FBSession.activeSession().accessTokenData.accessToken)
    }
    

    这段代码是用 Swift 编写的,但是 Obj C 也有这个方法。 然后,您将按照 Sandy 和 Steve 的建议在 Web 视图中使用访问令牌

    【讨论】:

      【解决方案3】:

      拥有FB access 令牌后,您应该能够在您的网络视图中使用Faceboook JavaScript API。官方文档见http://developers.facebook.com/docs/reference/javascript/。这个 SO 帖子给出了一个合理的解释:Retrieve Access Token Using Javascript API。正如那篇文章所述,您可以直接在AJAX 调用中使用访问令牌。我不会弄乱 cookie —— 只是传递访问令牌。

      您没有在网络视图中准确解释您想对 Facebook 做什么,所以我不确定这是否 100% 回答了您的问题。我想您知道如何将访问令牌传递给 Web 视图 (UIWebView'sstringByEvaluatingJavaScriptFromString)。

      【讨论】:

      • 对于嵌入式网页,你如何将 access_token 传递给 FB.getLoginStatus(),因为它除了回调之外不需要任何参数?
      • 你真的这样做了吗?从理论上讲这是有道理的,但就像@Claus 我真的想要一个代码示例。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-28
      • 2012-04-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多