6


(1) Facebook OAuth 機能を備えた Facebook API ベースの Web アプリケーション (「FB Web アプリ」) (
2) UIWebViewiPad 上のベースのブラウザ (「ブラウザ」)

ここでの目的は、Facebook ログイン ページを開いて、iPad の UIWebView ベースのブラウザー (2) 内で FB Web アプリ (1) にサインインすることです。

ここにやや似た問題があります:
http://facebook.stackoverflow.com/questions/11337285/no-longer-able-to-login-to-ios-app-via-oauth-the-page-requested-was-見つかりません

ただし、その質問の問題は、ユーザーがログインとパスワードを Facebook フォームに入力した後に発生します。私たちの問題は、そもそも Facebook のログイン フォームを表示できないことです。その質問で提案されているように、アプリの種類を「Web」から「ネイティブ/デスクトップ」に変更しても役に立ちませんでした。

手順: 1. このブラウザ
で Web ページ (単純な HTML ページ) を開きます 2. このページの [FB Web アプリ] 起動ボタンをクリックします 3. OnClick JavaScript は OAuth を開始しようとします。これにより、Facebook のログイン画面が開き、サインインします。 FBウェブアプリへ UIWebView

現在の結果 (問題):
iOS 5.+ および iOS 6.+ デバイス
- 当社の Web ページは変更されていません
- Facebook ログイン ページは表示されません (当社の Web ページは引き続き表示されます)
iOS 4.3 の場合 (期待どおりに動作します):
- FacebookログインページがUIWebViewブラウザの同じオブジェクトで開かれます (Web ページを置き換えます)

期待される結果:
- Facebook のログイン ページが表示され、ユーザーは Facebook のログインとパスワードを入力できます
- iPad の Safari ブラウザで起動した場合、iOS 5.+ および iOS 6.+ で動作します。Facebook のログイン ページは別のタブで開かれます (対照的に、 には別のタブはありませんUIWebView) 。

UIWebView質問: iOS 5 以降および iOS 6 以降で OAuth 要求に応答して Facebook ログイン ページを開く にはどうすればよいですか?

技術的な詳細:

NSURLRequest内部からさまざまなフィールド をログに記録します

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

また、「正しい」動作と「正しくない」動作のログにいくつかの違いがあることに気付きました。ここでは、実行フローがどのように見えるかを示します。

まず、「FB Web App」の起動ボタンを押して OAuth を開始します。

iOS 4.3、「正しい」<br> www.facebook.com/dialog/oauth?...
へのリクエスト fbwebapp.com への
リクエスト m.facebook.com/login.php?.... へのリクエスト --
こちら facebook ログインが現れる

iOS 5.0、「incorrect1」<br> www.facebook.com/dialog/oauth?...
へのリクエスト fbwebapp.com への
リクエスト m.facebook.com/login.php?... へのリクエスト

それから
-- たくさんの m.facebook.com/login.php?... 次の... パラメータ
に sqlite エラーが続きます --
今、facebook から「申し訳ありませんが、問題が発生しました」というページが表示されます (これは初めて遭遇しました)

iOS 6.0 “incorrect2”<br> www.facebook.com/dialog/oauth?...
へのリクエスト fbwebapp.com へのリクエスト

-(void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error がエラー コード -999 で呼び出されます

動作は iOS のバージョンに確実に依存していることがわかります。しかしよくあるのは、m.facebook.com/login.php.. URL を取得する段階でエラーが発生することです。しかし、それが私たちが検出できるすべてです。

私たちは一日中その壁に頭をぶつけて解決策を探しています。絶望的に。OAuth に応答し
て Facebook のログイン ページを開くのを手伝ってもらえますか?UIWebView

4

5 に答える 5

4

ちょうど使用:このコード

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

// manager.loginBehavior = FBSDKLoginBehaviorWeb;facebook を開くために必要なのはこれだけですUIWebview

于 2015-05-21T11:10:10.897 に答える
3

誰かがグーグルしている場合、これが私のために働いたものです:

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

私は here からこの実装の束を手に入れました

Web の実装によっては、追加の手順が 1 つある可能性があります。Facebook スクリプトは、実際には a window.close()then a window.open()then aを実行しwindow.close()ます。Web 側では、このログインが完了した後、私のウィンドウ (つまり、ユーザーにログインさせたい webView) がwindow.close()Facebook SDK からの呼び出しを受けていたため、私にとってはこれが問題を引き起こしていました。これは、Facebook SDK がそのwindow.open()呼び出しで新しいウィンドウが開き、それが閉じられることを期待しているためだと思います。

の機能をオーバーライドしていないためwindow.open()、呼び出しwindow.open()ても何も実行されず、Facebook SDK がウィンドウを閉じようとします。これはあらゆる種類の問題を引き起こす可能性がありますが、私はParseを使用しているため、window.localStorageに設定されていたnullため、あらゆる種類のエラーが発生していました.

このような問題が発生した場合は、修正するための 2 つのオプションがあります。

  1. Web コードを制御でき、ちょっとしたハッキン​​グに失敗した場合は、これを投入してくださいwindow.close=function(){}
  2. Web コードを制御できない場合はwindow.close、popUp webView で行ったようにメインの webView にオーバーライドを追加するか、window.open関数をオーバーライドして別のポップアップを開くことができます (詳細はこちらで説明されています) 。
于 2016-01-13T21:47:40.310 に答える
0

FBDialog クラスを使用して、ユーザーにログインを促します。これはアプリ内で webview を使用するため、ログインに成功すると、ユーザーは任意の UIWebView 内でログインされます。

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];

次に、クラスを FBDialogDelegate プロトコルに準拠させ、この関数をクラスに追加します。

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

チッ!

于 2013-01-11T16:59:36.070 に答える
0

UIWebViewでFacebookにログインする方法。

Objective-c

taylorstine's answerを使用してください。彼は私の一日を救った。テイラースティンありがとう

しかし、私は Swift 3 を使用しているので、taylorstine の回答から以下のコードを変換しました。

スイフト3。

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)")

    }

}
于 2017-02-08T08:37:34.873 に答える