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.plistCFBundleURLTypes 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)

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

Source: https://habr.com/ru/post/J323296/


All Articles