ios - 如何使用 webview 在 Xamarin.iOS 中实现手动 Facebook 登录

标签 ios facebook xamarin xamarin.ios

我正在尝试在我的 Xamarin.iOS 应用程序中实现 Facebook 登录。我曾尝试使用 Xamarin.Auth 包,但有时用户无法处理并且此包存在一些问题。我发现最好的方法是对我的应用程序实现手动登录流程(使用 WebView )。目前,我已经在 Facebook 开发者门户中创建了一个应用程序,我可以从我的 iOS 应用程序访问该链接。

因此,用户将单击普通按钮,该按钮将转发到 Facebook 登录页面。我的问题是,如何从 Facebook 登录页面获取结果?以及如何获取用户 ID、电子邮件……?

目前的源代码如下:

partial void BtnFacebookLogin_TouchUpInside(UIButton sender)
    {
        NSUrl apiRequest =
            new NSUrl("https://www.facebook.com/dialog/oauth?client_id="
            + SharedResources.fbClientId
            + "&response_type=token&redirect_uri="
            + SharedResources.fbRedirectUrl);

        UIApplication.SharedApplication.OpenUrl(apiRequest);
    }

最佳答案

我通过使用Facebook SDK找到了答案,它被认为是目前最好的现有解决方案,下载官方SDK(Xamarin.Facebook.iOS)后,步骤如下:

  1. 在 Info.plist 文件中,添加以下代码:

<key>NSAppTransportSecurity</key>
  <dict>
    <key>NSExceptionDomains</key>
    <dict>
      <key>facebook.com</key>
      <dict>
        <key>NSIncludesSubdomains</key>
        <true/>
        <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
        <false/>
      </dict>
      <key>fbcdn.net</key>
      <dict>
        <key>NSIncludesSubdomains</key>
        <true/>
        <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
        <false/>
      </dict>
      <key>akamaihd.net</key>
      <dict>
        <key>NSIncludesSubdomains</key>
        <true/>
        <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
        <false/>
      </dict>
    </dict>
  </dict>
  <key>LSApplicationQueriesSchemes</key>
  <array>
    <string>fbapi</string>
    <string>fbapi20130214</string>
    <string>fbapi20130410</string>
    <string>fbapi20130702</string>
    <string>fbapi20131010</string>
    <string>fbapi20131219</string>
    <string>fbapi20140410</string>
    <string>fbapi20140116</string>
    <string>fbapi20150313</string>
    <string>fbapi20150629</string>
    <string>fbauth</string>
    <string>fbauth2</string>
    <string>fb-messenger-api20140430</string>
    <string>fb-messenger-api</string>
    <string>fbauth2</string>
    <string>fbshareextension</string>
  </array>

  1. 同样在 Info.plist 文件中,原始 View 、高级选项卡、URL 类型,以这种方式添加您的 Facebook 应用程序 ID“fb1112222......”。将“fb”保留在开头。

Pic: Facebook app ID in Info.plist

  1. 在 AppDelegate.cs 中,覆盖这些方法:

        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
        {
            // Override point for customization after application launch.
            // If not required for your application you can safely delete this method
    
            Profile.EnableUpdatesOnAccessTokenChange(true);
            Settings.AppID = "fb app id";
            Settings.DisplayName = "fb app name";
    
            // This method verifies if you have been logged into the app before, and keep you logged in after you reopen or kill your app.
            return ApplicationDelegate.SharedInstance.FinishedLaunching(application, launchOptions);
    
            //return true;
        }
    
        public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
        {
            // We need to handle URLs by passing them to their own OpenUrl in order to make the SSO authentication works.
            return ApplicationDelegate.SharedInstance.OpenUrl(application, url, sourceApplication, annotation);
        }
    
  2. 最后,这是Facebook的功能,你可以使用他们自己的按钮,也可以使用你的按钮。以我的方式,我使用了名称为 (BtnFacebookLogin) 的按钮。

    //这里是facebook函数

    私有(private)无效SetupFacebookLoginButton() { List readPermissions = new List { "public_profile", "email"};

            ////Set Up Button Design
            var fbBtnText = new NSAttributedString("login with facebook", new
                UIStringAttributes()
            {
                ForegroundColor = UIColor.White
            });
    
    
            BtnFacebookLogin.SetAttributedTitle(fbBtnText, UIControlState.Normal);
            BtnFacebookLogin.SetBackgroundImage(
                UIImage.FromBundle("btn_long_blue.png"), UIControlState.Normal);
    
            //Strat Login Functions
            Profile.Notifications.ObserveDidChange((sender, e) =>
            {
                if (e.NewProfile == null)
                    return;
    
                if (AccessToken.CurrentAccessToken != null)
                {
                    var request = new GraphRequest("/me?fields=name,email", null, AccessToken.CurrentAccessToken.TokenString, null, "GET");
                    request.Start((connection, result, error) =>
                    {
                        // Handle if something went wrong with the request
                        if (error != null)
                        {
                            showAlert("Error", error.Description);
                            return;
                        }
    
                        fbReponseFromSDK facebookSDKLoginItem = new fbReponseFromSDK();
                        // Get your profile name
                        var userInfo = result as NSDictionary;
                        if(userInfo["id"] != null)
                        { 
                            Console.WriteLine("id is: " + userInfo["id"].ToString());
                        }
                        if (userInfo["name"] != null)
                        { 
                            Console.WriteLine("name is: " + userInfo["name"].ToString());
                        }
                        if (userInfo["email"] != null)
                        { 
                            Console.WriteLine("email is: " + userInfo["email"].ToString());
                        }
                       //(Success) Do what you want next :
                        doneFacbookLogin();
                    });
                }
            });
    
            // Handle actions once the user is logged in
            BtnFacebookLogin.ReadPermissions = readPermissions.ToArray();
            BtnFacebookLogin.Completed += (sender, e) =>
            {
                if (e.Error != null)
                {
                    // Handle if there was an error
                    showAlert("Facebook Login", e.Error.Description);
                    return;
                }
    
                if (e.Result.IsCancelled)
                {
                    // Handle if the user cancelled the login request
                    //showAlert("Facebook Login", "Login Cancelled");
                    return;
                }
    
                showAlert("Facebook Login", "Login Successfull");
            };
    
            // Handle actions once the user is logged out
            BtnFacebookLogin.LoggedOut += (sender, e) =>
            {
                // Handle your logout
            };
    
            // If you have been logged into the app before, ask for the your profile name
            if (AccessToken.CurrentAccessToken != null)
            {
                var request = new GraphRequest("/me?fields=name,email", null, AccessToken.CurrentAccessToken.TokenString, null, "GET");
                request.Start((connection, result, error) =>
                {
                    // Handle if something went wrong with the request
                    if (error != null)
                    {
                        showAlert("Error", error.Description);
                        return;
                    }
    
                    // Get your profile name
    
                });
            }
        }
    

有关更多信息,请参阅他们在 GitHub 中的示例 (Link)

关于ios - 如何使用 webview 在 Xamarin.iOS 中实现手动 Facebook 登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47975785/

相关文章:

ios - 核心数据中的多次插入

ruby-on-rails - 使用 devise + omniauth + rails 3 时如何清除 facebook session 和 cookie?

c# - 使用存储的访问 token 自动登录

c# - 在 Xamarin Forms 中通过 App.xaml.cs 动画打开 MainPage

c# - 解码 JSON Web token (Xamarin.Android)

android - 将监听器添加到 Google map

javascript - 每次我单击自动填充按钮时,它都会在字段中返回 "nil",而不是保存的字符串

ios - Swift 2 - 使用 UIAlertController 将 3 个 Action 按钮放在同一行

ios - 应用内购买 - 最后阶段的帮助 - 下载内容

ios - swift spritekit Facebook 分享按钮