2013-07-25 19 views
6

Per un'applicazione a cui sto lavorando Ho bisogno che gli utenti possano accedere a Facebook utilizzando l'SDK nativo, ma c'è anche una parte separata dell'app che utilizza un widget di commenti FB in una webview. Il problema è dopo che l'utente ha effettuato l'accesso utilizzando l'SDK nativo e non ha effettuato l'accesso all'interno del widget commenti webview. C'è un modo per avere l'accesso utente utilizzando l'SDK iOS nativo e quindi anche registrarli in Facebook in un UIWebView. Ho provato ad utilizzare openAccessTokenFromData: completionHandler: nella classe FBSession dopo che l'utente firmato in, ma non sono riuscito a convincere quello per funzionare, come qui di seguitoFacebook iOS SDK login nativo e UIWebView login

- (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) { 
       }]; 
}  

risposta

8

ho usato seguente codice per aprire Facebook SDK per iOS login in Webview nella mia app nativa e funziona bene per 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; 
} 
+0

Cool Ci proverò presto e ti faccio sapere – marchinram

+0

Certo, fammi sapere se hai qualche problema. –

+1

Questo apre una webview per il login e poi quando vado al controller della vista con l'interfaccia utente ho già effettuato l'accesso a Facebook, il che è buono. Il problema è che se prima vado su uiwebview e accedo a facebook, i dati possono essere condivisi con il sdk nativo? – marchinram

3

Crea facebook APPID Facebook Appid creating link Creazione tempo linee guida follow facebook è necessario dare bundile Identficatore in tempo registro Give Facebook appid information in **plist** like blow image

quindi utilizzare questo codice

@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 *[email protected]"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 *[email protected]"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); 


    } 
} 
1

grazie a Divya Bhalodiya risposto. questa è la versione 3 rapida con Facebook SDK 4.x. Se il codice ha qualche problema, sentiti libero di modificare il commento &. Spero che questo ti sia d'aiuto.

func verifyFromWebView() { 
    let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager() 
    fbLoginManager.loginBehavior = FBSDKLoginBehavior.web 
    fbLoginManager.logIn(withReadPermissions: ["email"], from: self) { (result, error) in 
    if error != nil { 
     print(error!.localizedDescription) 
     self.dismiss(animated: true, completion: nil) 
    }else if (result?.isCancelled)!{ 
     print("Cancelled") 
     self.dismiss(animated: true, completion: nil) 
    }else{ 

     if let fbLoginResult = result { 
      if fbLoginResult.grantedPermissions != nil && fbLoginResult.grantedPermissions.contains("email"){ 

       self.getFBData() 

      } 
     } 
    } 
    } 
} 
+0

Questo sta funzionando per consentire all'utente di accedere utilizzando l'SDK nativo, ma è comunque necessario accedere anche alla visualizzazione Web. Quindi questa soluzione non funziona più per risolvere il problema dell'OP. – plgrenier