For an app I'm working on I need the users to be able to login to Facebook using the native SDK, but there is also a separate part of the app using an FB comments widget in a webview. The problem is after the user logs in using native SDK they are not logged in within the webview comments widget. Is there a way to have the user login using the native iOS SDK and then also log them into Facebook in a UIWebView. I tried using openAccessTokenFromData:completionHandler: in the FBSession class after the user signed in but couldn't get that to work, like below
- (void)didLogin
{
FBAccessTokenData *data = [FBAccessTokenData createTokenFromString:[FBSession activeSession].accessTokenData.accessToken
permissions:[FBSession activeSession].accessTokenData.permissions
expirationDate:[FBSession activeSession].accessTokenData.expirationDate
loginType:FBSessionLoginTypeWebView
refreshDate:nil];
[[FBSession activeSession] closeAndClearTokenInformation];
FBSession *session = [[FBSession alloc] init];
[session openFromAccessTokenData:data
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
}];
}
Replace the code in AppDelegate.swift method with the following code. This code initializes the SDK when your app launches, and allows the SDK handle results from the native Facebook app when you perform a Login or Share action.
Facebook provides an easy to use SDK to allow app developers to implement the login and logout function inside their apps. After user authentication is verified, app can query the user data on behalf of the user or even share media to Facebook. The data can include user public profile, email and even friend list.
Nowadays, Facebook is a necessity in most people’s life. Facebook provides an easy to use SDK to allow app developers to implement the login and logout function inside their apps. After user authentication is verified, app can query the user data on behalf of the user or even share media to Facebook.
Before you configure Native Facebook login for your native app via Auth0, you must: Navigate to Auth0 Dashboard > Applications > Applications, and create an application with Auth0 (if you have not already). At the bottom of the settings page, select Show Advanced Settings and then the Device Settings view.
I used following code to open Facebook iOs SDK login in Webview in my native app and its works fine for me.
-(void)openFacebookAuthentication
{
NSArray *permission = [NSArray arrayWithObjects:kFBEmailPermission,kFBUserPhotosPermission, nil];
FBSession *session = [[FBSession alloc] initWithPermissions:permission];
[FBSession setActiveSession: [[FBSession alloc] initWithPermissions:permission] ];
[[FBSession activeSession] openWithBehavior:FBSessionLoginBehaviorForcingWebView completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
switch (status) {
case FBSessionStateOpen:
[self getMyData];
break;
case FBSessionStateClosedLoginFailed: {
// prefer to keep decls near to their use
// unpack the error code and reason in order to compute cancel bool
NSString *errorCode = [[error userInfo] objectForKey:FBErrorLoginFailedOriginalErrorCode];
NSString *errorReason = [[error userInfo] objectForKey:FBErrorLoginFailedReason];
BOOL userDidCancel = !errorCode && (!errorReason || [errorReason isEqualToString:FBErrorLoginFailedReasonInlineCancelledValue]);
if(error.code == 2 && ![errorReason isEqualToString:@"com.facebook.sdk:UserLoginCancelled"]) {
UIAlertView *errorMessage = [[UIAlertView alloc] initWithTitle:kFBAlertTitle
message:kFBAuthenticationErrorMessage
delegate:nil
cancelButtonTitle:kOk
otherButtonTitles:nil];
[errorMessage performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];
errorMessage = nil;
}
}
break;
// presently extension, log-out and invalidation are being implemented in the Facebook class
default:
break; // so we do nothing in response to those state transitions
}
}];
permission = nil;
}
Create facebook Appid Facebook Appid creating link Creating time follow facebook guide lines you must give bundile identfier in register time
Then Use this Code
@interface LoginViewController : UIViewController<UIWebViewDelegate>
@property(nonatomic,retain)UIWebView *webview;
@property (nonatomic, retain) NSString *accessToken;
@property(nonatomic,retain)UIActivityIndicatorView *FbActive;
@end
@interface LoginViewController ()
@end
@implementation LoginViewController
@synthesize accessToken,webview,FbActive;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//Removeing the UIWebview Cookies
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in [storage cookies]) {
[storage deleteCookie:cookie];
}
[[NSUserDefaults standardUserDefaults] synchronize];
}
-(IBAction)fbLoginPage:(UIButton *)sender1
{
NSString *facebookClientID =facebookAppId;
NSString *redirectUri = @"http://www.facebook.com/connect/login_success.html";
NSString *extended_permissions=@"user_photos,user_videos,publish_stream,offline_access,user_checkins,friends_checkins,email";
NSString *url_string = [NSString stringWithFormat:@"https://graph.facebook.com/oauth/authorize?client_id=%@&redirect_uri=%@&scope=%@&type=user_agent&display=touch", facebookClientID, redirectUri, extended_permissions];
NSURL *url = [NSURL URLWithString:url_string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
CGRect webFrame =[self.view frame];
webFrame.origin.y = 0;
UIWebView *aWebView = [[UIWebView alloc] initWithFrame:webFrame];
[aWebView setDelegate:self];
self.webview = aWebView;
self.FbActive = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
self.FbActive.color=[UIColor darkGrayColor];
self.FbActive.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2);
[self.FbActive startAnimating];
[webview loadRequest:request];
[self.webview addSubview:self.FbActive];
[self.view addSubview:webview];
}
- (void)webViewDidFinishLoad:(UIWebView *)_webView {
/**
* Since there's some server side redirecting involved, this method/function will be called several times
* we're only interested when we see a url like: http://www.facebook.com/connect/login_success.html#access_token=..........
*/
//get the url string
[self.FbActive stopAnimating];
NSString *url_string = [((_webView.request).URL) absoluteString];
//looking for "access_token="
NSRange access_token_range = [url_string rangeOfString:@"access_token="];
//looking for "error_reason=user_denied"
NSRange cancel_range = [url_string rangeOfString:@"error_reason=user_denied"];
//it exists? coolio, we have a token, now let's parse it out....
if (access_token_range.length > 0) {
//we want everything after the 'access_token=' thus the position where it starts + it's length
int from_index = access_token_range.location + access_token_range.length;
NSString *access_token = [url_string substringFromIndex:from_index];
//finally we have to url decode the access token
access_token = [access_token stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//remove everything '&' (inclusive) onward...
NSRange period_range = [access_token rangeOfString:@"&"];
//move beyond the .
access_token = [access_token substringToIndex:period_range.location];
//store our request token....
self.accessToken = access_token;
//remove our window
// UIWindow* window = [UIApplication sharedApplication].keyWindow;
// if (!window) {
// window = [[UIApplication sharedApplication].windows objectAtIndex:0];
// }
[self.webview removeFromSuperview];
self.webview=nil;
//tell our callback function that we're done logging in :)
// if ( (callbackObject != nil) && (callbackSelector != nil) ) {
// [callbackObject performSelector:callbackSelector];
// }
//the user pressed cancel
}
else if (cancel_range.length > 0)
{
//remove our window
// UIWindow* window = [UIApplication sharedApplication].keyWindow;
// if (!window) {
// window = [[UIApplication sharedApplication].windows objectAtIndex:0];
// }
[self.webview removeFromSuperview];
self.webview=nil;
//tell our callback function that we're done logging in :)
// if ( (callbackObject != nil) && (callbackSelector != nil) ) {
// [callbackObject performSelector:callbackSelector];
// }
}
[self getuserdetailes];
}
-(void)getuserdetailes
{
NSString *action=@"me";
NSString *url_string = [NSString stringWithFormat:@"https://graph.facebook.com/%@?", action];
//tack on any get vars we have...
NSDictionary *get_vars=nil;
if ( (get_vars != nil) && ([get_vars count] > 0) ) {
NSEnumerator *enumerator = [get_vars keyEnumerator];
NSString *key;
NSString *value;
while ((key = (NSString *)[enumerator nextObject])) {
value = (NSString *)[get_vars objectForKey:key];
url_string = [NSString stringWithFormat:@"%@%@=%@&", url_string, key, value];
}//end while
}//end if
if (accessToken != nil)
{
//now that any variables have been appended, let's attach the access token....
url_string = [NSString stringWithFormat:@"%@access_token=%@", url_string, self.accessToken];
url_string = [url_string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@",url_string);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url_string]];
NSError *err;
NSURLResponse *resp;
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:&resp error:&err];
NSString *stringResponse = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSLog(@"%@",stringResponse);
NSError* error;
NSDictionary *FBResResjson = [NSJSONSerialization
JSONObjectWithData:response//1
options:kNilOptions
error:&error];
NSLog(@"%@",FBResResjson);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With