2012-11-09 13 views
6

Biz:
(1) Facebook OAuth işlevselliği (“FB web uygulaması”) ile Facebook API tabanlı web uygulaması
(2) iPad (“Tarayıcı”)UIWebView'ı iOS 5 ve iOS 6'daki OAuth isteğine yanıt olarak Facebook giriş sayfasını açmak için nasıl alabilirim?

Our üzerinde UIWebView tabanlı tarayıcı Amaç, iPad'deki UIWebView Tabanlı Tarayıcının (2) içindeki FB web uygulamasında (1) oturum açmak için Facebook Giriş sayfasını açmaktır. kullanıcı Facebook forma giriş ve şifre girer sonra
http://facebook.stackoverflow.com/questions/11337285/no-longer-able-to-login-to-ios-app-via-oauth-the-page-requested-was-not-found

Ancak bu soruya konusunun olur: Burada biraz benzer bir sorun vardır

. Sorunumuz, Facebook giriş formunu en başta görüntüleyemiyoruz. Uygulama türünün bu soruda önerildiği gibi “Web” den “Yerel/Masaüstü” olarak değiştirilmesi yardımcı olmadı.

Adımlar:
2. tıklayın
3. OnClick JavaScript OAuth'u başlatma girişiminde bu sayfadaki “FB web uygulaması” fırlatma düğmesine bu UIWebView Browser ile
1. Açık web sayfası (basit HTML sayfası) hangi FB web uygulaması

Güncel sonucu (sorunu) oturum açmak için Facebook giriş ekranını açmak olmalıdır: - web sayfası
değişmeden kalır iOS 5. + ve iOS 6. üzeri cihazlar
günü
- Facebook giriş sayfası N

Beklenen sonuç Facebook giriş sayfası Tarayıcı aynı UIWebView nesne açılır (bizim web sayfası yerine geçer) -
: OT gösterilen iOS 4.3 üzerinde
(olarak beklenen çalışır) (web sayfası hala görüntülenir) :
- Facebook giriş sayfası görüntülenir ve kullanıcı Facebook girişine girebilir parola
- iOS'ta Safari + + iOS 6'da çalışır. Facebook giriş sayfası ayrı bir sekmede açılır (aksine vardır UIWebView hiçbir ayrı sekmeler)

Soru: iOS OAuth isteğine yanıt olarak Facebook giriş sayfasını açmak için UIWebView alabilirim nasıl 5+ ve iOS 6 +?

Daha teknik detaylar:

Biz

-(BOOL)webView(UIWebView*)webView shouldStartLoadWithRequest(NSURLREquest*)request navigationType:… 

içinden farklı NSURLRequest alanları log Ve biz “doğru” ve “yanlış” davranışları için günlüklerinde bazı fark. İşte yürütme Beni arama akışlarının nasıl: Birincisi

, o zaman bazı durumlar

iOS 4.3, “doğru”
istek www.facebook.com adresine gidin OAuth'u başlatmak için “FB Web Uygulaması” başlatma düğmesine basın/dialog/oauth? ...
fbwebapp.com adresine istekte bulunabilirsiniz
talep m.facebook.com/login.php? ....
--here facebook login iOS 5.0

, “incorrect1”
istek? ...
isteği m.facebook için
isteği fbwebapp.com için www.facebook.com/dialog/oauth görünmektedir. com/login.php? ... Sonra

o sqlite hatası
ardından parametrelerin
yılında ... sonraki m.facebook.com/login.php?...with ait
-a çok şey olabilir - şimdi görüyorum “Üzgünüm, bir şeyler ters gitti” pa ge facebook dan

iOS 6.0 “incorrect2”
isteği www.facebook.com/dialog/oauth için? ...
isteği fbwebapp.com için (o bunu karşılaşmak hiç de ilk kez)

-(void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error is invoked with error code -999

Bu davranışın kesinlikle iOS sürümüne bağlı olduğunu görebilirsiniz. Ancak genel durum, bu hatanın m.facebook.com/login.php .. URL'sini alma adımında gerçekleşmesidir. Ama bu, bulabildiğimiz her şey.

Bütün gün boyunca çözümler aramak için kafalarımızı o duvara dayaylıyoruz. Umutsuzca.
OAuth'a yanıt olarak UIWebView'da açılan Facebook Giriş sayfasını almamıza yardım edebilir misiniz?

cevap

0

Kullanıcının oturum açmasını istemek için FBDialog sınıfını kullanın. Sonra sınıf FBDialogDelegate protokole uymak ve dersinize bu işlev eklemek yapmak

NSString *kRedirectURL = @"fbconnect://success"; 
NSString *kSDK = @"ios" ; 
NSString *kLogin = @"oauth"; 
NSString *kDialogBaseURL = @"https://m.facebook.com/dialog/"; 

NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
           AE_FACEBOOK_APPID, @"client_id", 
           @"user_agent", @"type", 
           kRedirectURL, @"redirect_uri", 
           @"touch", @"display", 
           kSDK, @"sdk", 
           nil]; 

NSString *loginDialogURL = [kDialogBaseURL stringByAppendingString:kLogin]; 

FBLoginDialog* loginDialog = [[FBLoginDialog alloc] initWithURL:loginDialogURL 
                loginParams:params 
                 delegate:self]; 
[loginDialog show]; 

: Bu kullanıcı hiçbir UIWebView iç kaydedilecektir başarılı giriş dolayısıyla uygulamasının içinde bir web görüntülemesini kullanır

-(void)fbDialogLogin: (NSString *)token expirationDate:(NSDate *)expirationDate{ 
    // Store the token and expiration date into the FB SDK 
    self.facebook.accessToken = token; 
    self.facebook.expirationDate = expirationDate; 
    // Then persist these so the SDK picks them up on next load 

    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; 

[defaults setObject:self.facebook.accessToken forKey:ACCESS_TOKEN_KEY]; 
[defaults setObject:self.facebook.expirationDate forKey:EXPIRATION_DATE_KEY]; 
[defaults synchronize]; 
} 

HTH!

+0

3., bu çözümü hakkında daha fazla açıklayabilir? IOS'de bir yeni kullanıcıyım, ancak bazı Facebook SDK örneklerini denedim. Bakın – owlmsj

3

Bu bir kesmek gibi, ama iOS 6 UiWebView üzerinde js facebook sdk giriş çalışır.

Bu nasıl yapılabilir? Bu saf bir JS + Facebook JS SDK + UIWebView Delege taşıma fonksiyonları çözümdür.

JS - Birinci aşama)

Yüz JS giriş/oauth diyaloglar tetikleyecek bir giriş düğmesi (facebook ile bağlanmak için) bu işlevi örneği çağırır:

function loginWithFacebookClick(){ 

FB.login(function(response){ 
    //normal browsers callback 
}); 

} 

JS - İkinci aşama)

authResponseChange dinleyicisi, kullanıcı web sayfasını her yüklediğinde ekle (FB'den sonra.'Ne zaman

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
{ 
NSString *url = [[request URL] absoluteString]; 

//when user status == connected (has a access_token at facebook oauth response) 
if([url hasPrefix:@"https://m.facebook.com/dialog/oauth"] && [url rangeOfString:@"access_token="].location != NSNotFound) 
{ 
    [self backToLastPage]; 
    return NO; 
} 

return YES; 
} 

- (void)webViewDidFinishLoad:(UIWebView *)webView 
{ 

NSString *url = [[webView.request URL] absoluteString]; 

if([url hasPrefix:@"https://m.facebook.com/dialog/oauth"]) 
{ 
    NSString *bodyHTML = [webView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML"]; 

    //Facebook oauth response dead end: is a blank body and a head with a script that does 
    //nothing. But if you got back to your last page, the handler of authResponseChange 
    //will catch a connected status if user did his login and auth app 
    if([bodyHTML isEqualToString:@""]) 
    { 
     [self backToLastPage]; 
    } 
} 

} 

Yani, Üçüncü Aşama) -

FB.Event.subscribe('auth.authResponse.Change', function(response){ 
//UIWebView login 'callback' handler 
var auth = response.authResponse; 
if(auth.status == 'connected'){ 
    //user is connected with facebook! just log him at your webapp 
} 
}); 

VE uygulamanın UIWebView temsilci fonksiyonları ile facebook oauth yanıtları

Objective C işleyicisi edebilirsiniz: init()) Kullanıcının bağlı durumunu yakalamak için Kullanıcıyı son yüklenen sayfaya yönlendir, ikinci adım ise facebook oturum açma diyaloglarında kullanıcı eylemini gerçekleştirecek.

Bu cevapla çok hızlı adım attıysam lütfen bana sorun! Umut eder.

4

sadece kullanın: Bu kodu

if (![FBSDKAccessToken currentAccessToken]) 
{ 
    FBSDKLoginManager *manager = [[FBSDKLoginManager alloc]init]; 
    manager.loginBehavior = FBSDKLoginBehaviorWeb; 
    [manager logInWithReadPermissions:@[@"public_profile", @"email", @"user_friends"] handler: 
    ^(FBSDKLoginManagerLoginResult *result, NSError *error) { 

     NSLog(@"result.token: %@",result.token.tokenString); 
     NSLog(@"%@",result.token.userID); 
     NSLog(@"%hhd",result.isCancelled);  
    }]; 
} 

// burada manager.loginBehavior = FBSDKLoginBehaviorWeb; sen durumda herkes yılında UIWebview

1

yılında Googling olan facebook açmak için gereken tek şey, burada benim için çalıştı budur:

-(BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)inType { 
    if ([request.URL.absoluteString containsString:@"m.facebook.com"]) { 
     if ([request.URL.absoluteString rangeOfString:@"back"].location == 0) { 
      [self.popUp removeFromSuperview]; 
      self.popUp = nil; 
      return NO; 
     } 
     if (self.popUp) { 
      return YES; 
     } 

     UIWebView *wv = [self popUpWebView]; 
     [wv loadRequest:request]; 
     return NO; 
    } 
    return YES; 
} 

- (UIWebView *) popUpWebView { 
    toolbar height 
    UIWebView *webView = [[UIWebView alloc] 
      initWithFrame:CGRectMake(0, 0, (float)self.view.bounds.size.width, 
        (float)self.view.bounds.size.height)]; 
    webView.scalesPageToFit = YES; 
    webView.delegate = self; 
    // Add to windows array and make active window 
    self.popUp = webView; 
    [self.view addSubview:webView]; 
    return webView; 
} 

- (void)webViewDidFinishLoad:(UIWebView *)webView { 

    if (self.popUp) { 
     NSError *error = nil; 
     NSString *jsFromFile = @"window.close=function(){window.location.assign('back://' + window.location);};"; 
     __unused NSString *jsOverrides = [webView 
       stringByEvaluatingJavaScriptFromString:jsFromFile]; 

     JSContext *openerContext = [self.webView 
       valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; 
     JSContext *popupContext = [webView 
       valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; 
     popupContext[@"window"][@"opener"] = openerContext[@"window"]; 
    } 


    //this is the secret sauce 
    if (webView == self.popUp 
      && [webView.request.URL.absoluteString containsString:@"m.facebook.com"] 
      && [[webView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML"] isEqualToString:@""]) { 
     [webView stringByEvaluatingJavaScriptFromString:@"eval(document.getElementsByTagName('script')[0].text)"]; 
    } 
} 

I snagged a bunch of this implementation from here. Web uygulamanıza bağlı olarak, muhtemelen bir adım daha olacaktır. Facebook betiği aslında bir window.close() sonra window.open() ve sonra bir window.close() yürütür. Benim için bu sorunlara neden oldu çünkü web oturumunda, bu giriş tamamlandıktan sonra, benim pencerem (yani kullanıcı için giriş yapmasını istediğim webView için), Facebook SDK'sından gelen bir window.close() çağrı alıyordu. Bunu kabul ediyorum çünkü Facebook SDK, window.open()'un kapanacağı yeni bir pencere açmasını bekliyor.

window.open()'un işlevselliğini geçersiz kılmadığımızdan, window.open() numaralı telefonu arayarak hiçbir şey yapmayacaksınız ve Facebook SDK pencerenizi kapatmaya çalışacaktır. Bu, her türlü soruna neden olabilir, ama benim için Parse kullanıyorum, window.localStoragenull olarak ayarlandı, bu yüzden her türlü hata alıyordum.

böyle bir şey sizin için oluyor, bunu düzeltmek için iki seçenek vardır:

  1. web kodunun kontrolünü varsa ve küçük bir hack için aşağı window.close=function(){}
  2. bu atmak
  3. Web kodunun kontrolünü elinizde bulundurmazsanız, ana web sayfası için popUp webView için yaptığımız gibi window.close'a bir geçersiz kılma ekleyebilir veya window.open işlevini başka bir açılır pencereyi (more detail here numaralı belgede açıklanmıştır)
0

UIWebView'da facebook giriş nasıl açılır.

Amaç-c

kullanın taylorstine's answer. O günümü kurtardı. Teşekkürler taylorstine

Ama ben Swift 3 kullanıyorum. Bu yüzden sadece aşağıdaki kodu Taylorstine'in yanıtından değiştirdim.Swift

func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool { 

    if let _ = request.url?.absoluteString.range(of: "m.facebook.com") { 
     if let _ = request.url?.absoluteString.range(of: "back"){ 
      self.popUp?.removeFromSuperview() 
      self.popUp = nil 
      return false 
     } 

     if let _ = self.popUp { 
      return true 
     } 

     let wv = popUpWebView() 
     wv.loadRequest(request) 

     return false 
    } 

    return true 
} 

func popUpWebView() -> UIWebView { 

    let webView = UIWebView(frame: self.view.frame) 

    webView.delegate = self 
    self.popUp = webView 
    self.view.addSubview(webView) 

    return webView 
} 

func webViewDidFinishLoad(_ webView: UIWebView) { 
    if let _ = self.popUp { 

     let jsFromFile = "window.close=function(){window.location.assign('back://' + window.location);};" 

     let _ = webView.stringByEvaluatingJavaScript(from: jsFromFile) 

     let openerContext = self.webView.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as! JSContext 

     let popupContext = webView.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as! JSContext 

     popupContext.setObject("opener", forKeyedSubscript: "window" as (NSCopying & NSObjectProtocol)!) 
     popupContext.setObject(openerContext.objectForKeyedSubscript("window"), forKeyedSubscript: "opener" as (NSCopying & NSObjectProtocol)!) 

    } 

    if webView == self.popUp 
     && (webView.request?.url?.absoluteString.range(of:"m.facebook.com") != nil) 
     && webView.stringByEvaluatingJavaScript(from: "document.body.innerHTML") == "" { 

     webView.stringByEvaluatingJavaScript(from: "eval(document.getElementsByTagName('script')[0].text)") 

    } 

}