Xamarin.FormsのVK SDKを接続します

前回の記事では、便利なユーザー認証のために、Xamarin.FormsアプリケーションでFacebookからネイティブSDKを接続する問題を調べました。 今日、約束どおり、ソーシャルネットワークVKontakteにネイティブSDKを接続することを検討します。 新しいSDKは、 前回の記事で説明したプロジェクトに接続します







VKでアプリケーションを作成する



一般的に、VKontakteの統合プロセスはFacebookとの連携に非常に似ているため、アプリケーション管理ページに進んでください



[アプリケーションの作成]をクリックし、[スタンドアロンアプリケーション]を選択します。







次に、設定に移動し、アプリケーションに関するデータを入力します。 「証明書の指紋」は、前の記事で受け取ったキーハッシュです。







これで準備部分が完了します。



VK SDKをiOSおよびAndroidプロジェクトに接続する



Xamarinでは多くの既製のバインディングが利用できますが、最近では本格的なVK SDKが登場しました。 このライブラリはしばらくの間ベータ版でしたが、現在使用可能です。 マシュー・レイボウィッツに感謝します!







iOSで接続する



Info.plist



変更を加えInfo.plist



CFBundleURLTypes



VKの値でCFBundleURLTypes



ます。



 <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLName</key> <string>vk5874073</string> <key>CFBundleURLSchemes</key> <array> <string>fb1102463466549096</string> <string>vk5874073</string> </array> </dict> </array>
      
      





新しいLSApplicationQueriesSchemes



追加しLSApplicationQueriesSchemes







  <string>vk</string> <string>vk-share</string> <string>vkauthorize</string>
      
      





また、 NSAppTransportSecurity



の新しいドメイン:



 <key>vk.com</key> <dict> <key>NSExceptionRequiresForwardSecrecy</key> <false/> <key>NSIncludesSubdomains</key> <true/> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> </dict>
      
      





その後、 AppDelegate.cs



変更をAppDelegate.cs



ます。



  public override bool FinishedLaunching(UIApplication app, NSDictionary options) { Xamarin.Forms.Forms.Init(); LoadApplication(new App()); Facebook.CoreKit.Profile.EnableUpdatesOnAccessTokenChange(true); Facebook.CoreKit.ApplicationDelegate.SharedInstance.FinishedLaunching(app, options); VKSdk.Initialize("5874073"); return base.FinishedLaunching(app, options); } public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation) { return VKSdk.ProcessOpenUrl(url, sourceApplication) || Facebook.CoreKit.ApplicationDelegate.SharedInstance.OpenUrl(application, url, sourceApplication, annotation) || base.OpenUrl(application, url, sourceApplication, annotation); }
      
      





これで、iOSの初期初期化が完了しました。



Androidで接続する



ただし、Androidの場合は、SDKを正しく初期化するためにApplication



クラスを再定義する必要があります。



  [Application] public class MainApplication : Application { public MainApplication(IntPtr handle, JniHandleOwnership transer) :base(handle, transer) { } public override void OnCreate() { base.OnCreate(); VKSdk.Initialize(this).WithPayments(); } }
      
      





次に、アプリケーションIDをstrings.xml



追加します。



  <integer name="com_vk_sdk_AppId">5874073</integer> <string name="vk_data_theme">vk5874073</string>
      
      







<application ..> …



間にAndroidManifest.xml



コードを追加し<application ..> …







  <activity android:name="com.binwell.login.MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="@string/vk_data_theme" /> </intent-filter> </activity>
      
      





そして、 MainActivity



拡張機能で終了します。



 protected override async void OnActivityResult(int requestCode, Result resultCode, Intent data) { bool vkResult; var task = VKSdk.OnActivityResultAsync(requestCode, resultCode, data, out vkResult); if (!vkResult) { base.OnActivityResult(requestCode, resultCode, data); AndroidFacebookService.Instance.OnActivityResult(requestCode, (int)resultCode, data); return; } try { var token = await task; // Get token } catch (Exception e) { // Handle exception } }
      
      





Xamarin.Formsと統合する



Facebookとの類推により、新しいSDKを使用するためのPCLプロジェクトに独自のインターフェイスを作成します。



  public interface IVkService { Task<LoginResult> Login(); void Logout(); }
      
      





IOSの実装



iOSの場合、実装は次のようになります。



 [assembly: Dependency(typeof(AppleVkService))] namespace Login.iOS { public class AppleVkService : NSObject, IVkService, IVKSdkDelegate, IVKSdkUIDelegate { readonly string[] _permissions = { VKPermissions.Email, VKPermissions.Offline }; LoginResult _loginResult; TaskCompletionSource<LoginResult> _completionSource; public AppleVkService() { VKSdk.Instance.RegisterDelegate(this); VKSdk.Instance.UiDelegate = this; } public Task<LoginResult> Login() { _completionSource = new TaskCompletionSource<LoginResult>(); VKSdk.Authorize(_permissions); return _completionSource.Task; } public void Logout() { _loginResult = null; _completionSource = null; } [Export("vkSdkTokenHasExpired:")] public void TokenHasExpired(VKAccessToken expiredToken) { VKSdk.Authorize(_permissions); } public new void Dispose() { VKSdk.Instance.UnregisterDelegate(this); VKSdk.Instance.UiDelegate = null; SetCancelledResult(); } public void AccessAuthorizationFinished(VKAuthorizationResult result) { if (result?.Token == null) SetErrorResult(result?.Error?.LocalizedDescription ?? @"VK authorization unknown error"); else { _loginResult = new LoginResult { Token = result.Token.AccessToken, UserId = result.Token.UserId, Email = result.Token.Email, ExpireAt = Utils.FromMsDateTime(result.Token.ExpiresIn), }; Task.Run(GetUserInfo); } } async Task GetUserInfo() { var request = VKApi.Users.Get(NSDictionary.FromObjectAndKey((NSString)@"photo_400_orig", VKApiConst.Fields)); var response = await request.ExecuteAsync(); var users = response.ParsedModel as VKUsersArray; var account = users?.FirstObject as VKUser; if (account != null && _loginResult != null) { _loginResult.FirstName = account.first_name; _loginResult.LastName = account.last_name; _loginResult.ImageUrl = account.photo_400_orig; _loginResult.LoginState = LoginState.Success; SetResult(_loginResult); } else SetErrorResult(@"Unable to complete the request of user info"); } public void UserAuthorizationFailed() { SetErrorResult(@"VK authorization unknown error"); } public void ShouldPresentViewController(UIViewController controller) { Device.BeginInvokeOnMainThread(() => Utils.GetCurrentViewController().PresentViewController(controller, true, null)); } public void NeedCaptchaEnter(VKError captchaError) { Device.BeginInvokeOnMainThread(() => VKCaptchaViewController.Create(csaptchaError).PresentIn(Utils.GetCurrentViewController())); } void SetCancelledResult() { SetResult(new LoginResult { LoginState = LoginState.Canceled }); } void SetErrorResult(string errorString) { SetResult(new LoginResult { LoginState = LoginState.Failed, ErrorString = errorString }); } void SetResult(LoginResult result) { _completionSource?.TrySetResult(result); _loginResult = null; _completionSource = null; } }
      
      





Androidの実装



Androidでも珍しいことはありません。



 [assembly: Dependency(typeof(AndroidVkService))] namespace Login.Droid { public class AndroidVkService : Java.Lang.Object, IVkService { public static AndroidVkService Instance => DependencyService.Get<IVkService>() as AndroidVkService; readonly string[] _permissions = { VKScope.Email, VKScope.Offline }; TaskCompletionSource<LoginResult> _completionSource; LoginResult _loginResult; public Task<LoginResult> Login() { _completionSource = new TaskCompletionSource<LoginResult>(); VKSdk.Login(Forms.Context as Activity, _permissions); return _completionSource.Task; } public void Logout() { _loginResult = null; _completionSource = null; VKSdk.Logout(); } public void SetUserToken(VKAccessToken token) { _loginResult = new LoginResult { Email = token.Email, Token = token.AccessToken, UserId = token.UserId, ExpireAt = Utils.FromMsDateTime(token.ExpiresIn) }; Task.Run(GetUserInfo); } async Task GetUserInfo() { var request = VKApi.Users.Get(VKParameters.From(VKApiConst.Fields, @"photo_400_orig,")); var response = await request.ExecuteAsync(); var jsonArray = response.Json.OptJSONArray(@"response"); var account = jsonArray?.GetJSONObject(0); if (account != null && _loginResult != null) { _loginResult.FirstName = account.OptString(@"first_name"); _loginResult.LastName = account.OptString(@"last_name"); _loginResult.ImageUrl = account.OptString(@"photo_400_orig"); _loginResult.LoginState = LoginState.Success; SetResult(_loginResult); } else SetErrorResult(@"Unable to complete the request of user info"); } public void SetErrorResult(string errorMessage) { SetResult(new LoginResult { LoginState = LoginState.Failed, ErrorString = errorMessage }); } public void SetCanceledResult() { SetResult(new LoginResult { LoginState = LoginState.Canceled }); } void SetResult(LoginResult result) { _completionSource?.TrySetResult(result); _loginResult = null; _completionSource = null; } } }
      
      





Xanarin.Formsで接続します



それだけです VKontakteは動作します!







アプリケーションを公開するには(あなた以外がログインできるように)、ソーシャルネットワークごとに追加の手順を実行する必要があります。



使用する



今日、ネイティブVK SDKを使用してユーザーを認証する方法を学びました。 このソーシャルネットワークで作業するために幅広い機能が必要な場合は、マシュー自身の例を学習することをお勧めします。



FacebookとVKontakteのネイティブSDKが接続された完全なプロジェクトコードは、にあります。



次の記事では、Xamarin.FormsアプリケーションでOAuthを使用してユーザーを認証する普遍的な方法について説明します。 連絡を取り合い、コメントで質問をして、 TelegramのXamarin Developersグループ参加してください。



著者について



ヴャチェスラフ・チェルニコフ -開発部長、 ビンウェル 過去には、Nokia ChampionおよびQt認定スペシャリストの1人で、現在はXamarinおよびAzureプラットフォームのスペシャリストです。 彼は2005年にモバイル分野に参入し、2008年からモバイルアプリケーションを開発しています。Symbian、Maemo、Meego、Windows Mobileから始め、その後iOS、Android、Windows Phoneに切り替えました。



Mediumブログで Vyacheslavの記事読むこともできます。



著者の他の記事:





Xamarin Meetup:Xamarin.Formsの洗練されたインターフェイス



Xamarin Developersコミュニティや個人的にVyacheslavとチャットしたい場合は、3月9日にモスクワで「Xamarin Formsの複雑なインターフェース」に関する会議が開催されます。



Mitapプログラム:



18:00-18:30登録

18:30-19:30 Vyacheslav Chernikov //複雑なインターフェースのレイアウトのためにRecyclerView / UICollectionViewを接続する

19:30-19:40コーヒーブレイク

19:40-20:40 Yuri Nevalenny // Xamarin Formsのコレクションとリスト、仮想化パターン、高速セル(Android、iOS、Windows)



参加は無料で、 登録が必要です



All Articles