16
votes

I'm working with the new facebook-ios-sdk and have successfully integrated the api into my native app. I am able to authenticate a user and properly setup permissions using a popup dialog with the ios-sdk classes.

For a portion of my app I need to use the facebook connection within a UIWebView, using javascript and html to process data within the webview. Given that the user is already logged in and authenticated via the above routine, I would have assumed that the UIWebView would share those credentials, or that there would at least be some way to pass or assign the credentials to the webview.

Unfortunately, I found this earlier post which seems to suggest that this scheme doesn't quite work (iOS - being logged-in in a webView after logging in with the SDK). Has anyone else encountered this and/or found a work around? This seems like it would be a fairly straightforward use case given that I'm not trying to launch mobile safari or something like that - it's all within the same native app.

It just seems like there must be some sort of easy trick or setting that I'm missing. Maybe somehow setting cookies in the new UIWebView? or something like this?

3
This is my problem too, but looks like there is no hope for an answer :(Ivan Suhinin
almost 2 years later,I'm having the same problem. Any solution in the meanwhile?Claus

3 Answers

1
votes

--BY this way Facebook-ios-sdk

@property (nonatomic, retain) 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];
            }

        }];
1
votes

I would probably get the Access token in this method

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

This code is in Swift, but the method exists for Obj C as well. Then you would use the access token in the web view as suggested by Sandy and Steve

0
votes

Once you have the FB access token, you should be able to use the Faceboook JavaScript API in your web view. See http://developers.facebook.com/docs/reference/javascript/ for the official documentation. This SO post gives a reasonable explanation: Retrieve Access Token Using Javascript API. As that post describes, you can use the access token in an AJAX call directly. I would not mess with cookies -- just pass along the access token.

You didn't explain exactly what you want to do with Facebook in the web view, so I'm not sure this answers your question 100%. I presume you know how to pass the access token to the web view (UIWebView's stringByEvaluatingJavaScriptFromString).