Авторизация и использование VK.com API в Xamarin.Android

    Xamarin — очень многообещающей продукт, который помогает вести кроссплатформенную разработку на Android и iOS на языке C#. На мой взгляд, незаслуженно упускаемый из виду сообществом мобильных разработчиков. Язык C# можно легко заменить на F#, а в качестве платформ взять еще и OSX, и Windows Phone. В общем, возможностей и перспектив масса, самых интересных.



    Это уже третья моя статья на хабре, посвященная Xamarin. В ней мы разработаем простое, но наглядное приложение (в жанре Hello Word) с использованием VK.com API. Как обычно, исходники выложены в репозитарий GitHub и приведены в конце статьи.

    Итак, в чем, собственно, принципиальная разница задач, с которыми придется столкнуться разработчику, создающему native-приложение Android, поддерживающее VK.com, и разработчику, решающему ту же самую задачу с Xamarin?

    Вступление


    В случае с native-разработкой Android, есть официальное SDK VK.com, прекрасно документированное и с достаточным числом примеров. Есть даже альтернативное SDK, на котором построен проект Kate Mobile, тоже с хорошей документацией.

    В случае же с Xamarin.Android, все далеко не так радостно. Конечно, можно использовать native-библиотеки, написанные на Java, и Xamarin предоставляет такую возможность, однако этот путь не лишен подводных камней. Такие попытки уже были, в частности, не так давно наткнулся на многообещающий проект на codeplex: автор использовал официальное Android Java SDK VK.com и пересобрал его в *.dll, которую можно использовать в Xamarin. Однако, дела снова не пошли (у меня эта библиотека, в частности, не заработала), и теперь он уже собирается все переписать, основываясь на .NET SDK для Windows Phone.

    Кстати, по поводу VK.com .NET SDK, что под Windows Phone и Windows. Казалось бы, что там C#, что в Xamarin C#, да только разница в платформах все равно очень существенная, и просто так «скопировать *.dll», подлючить ее к проекту в Xamarin и запустить, не получится.

    Отсюда возникает вопрос: как, все-таки, написать приложение для Android в Xamarin с возможностями доступа к социальной сети VK.com? Выход есть, будем использовать OAuth 2.0 авторизацию и стандартные запросы к API. Рассмотрим все это в подробностях.

    Подготовка


    Первый шаг — сообщаем VK.com, о том, что мы собираемся разработать приложение с использованием его API. В приложении придется логиниться по защищенному соединению, поэтому VK.com требует постоянного информирования, кто пользуется его API. В принципе, это вполне логичное решение, исходяшее из соображений безопасности, протокол OAuth 2.0 подразумевает выдачу token-а доступа (но об этом чуть позднее).

    Этот шаг обязателен, вне зависимости от платформы и метода разработки приложения с использованием VK.com API.

    На странице управления приложений создадим новое:



    Не забываем переключить состояние в «Приложение включено и видно всем»:



    Здесь нам понадобится «Id приложения». Скопируем его, в дальнейшем пригодится. На этом раздел управления приложениями можно закрыть, больше он нам не понадобится. Разве что, в дальнейшем можете зайти в «статистику», там есть интересные для разработчика вещи, позволяющие отслеживать, сколько пользователей и как работают с приложением.

    Азы OAuth 2.0 и Xamarin.Android


    Теперь можно приступать к самой интересной части — непосредственной разработке! Нам понадобится замечательный бесплатный плагин Xamarin.Auth, позволяющий использовать протокол OAuth 2.0 (поддерживаемый, кстати, API большинства социальных сетей, в том числе Facebook, Twitter, Instagram, и многих других). Помимо поддержки Android, есть, конечно, и iOS, но пока нам нужна только первая платформа. Для загрузки с сайта Xamarin-а придется создать аккаунт.

    Также должна быть установлена Xamarin Studio. Я использую версию 5.5.4, это не имеет особого значения, можете использовать и более старые/новые версии (последняя на данный момент: 5.7.0). При желании можете использовать и Visual Studio, но тут дело вкуса. Единственный нюанс, насколько помню, Starter и Indie версии Xamarin-а не поддерживают VS, а вот Business и Enterprise (в том числе trial-ы, совсем не укрезающие, кстати, функционал) — поддерживают.

    Загрузив архив Xamarin.Auth, перейдем в папку Samples/Xamarin.Auth.Sample.Android:



    Разработчики плагина Xamarin.Auth привели очень удобный пример работы с плагином, осуществляющий логин в Facebook. Нам он пригодится, на его примере и разберем азы работы с протоколом OAuth 2.0. Загружаю проект Xamarin.Auth.Sample.Android.sln в Xamarin Studio:



    Обратите внимание, что плагин Xamarin.Auth должен быть подключен и корректно отображаться в «References». Если его там по каким-то причинам нет, то щелкните по правой кнопкой по «References» и перейдите в «Edit references». Откроется меню, как в правой части скриншота. Там в разделе ".NET Assembly" вручную выберете путь к библиотеке Xamarin.Auth.Android.dll, находящейся в: «папка Xamarin.Auth\lib\android».

    Итак, можно приступать к правке кода.

    Оригинальный фрагмент объекта типа OAuth2Authenticator, отвечающего за авторизацию:
    var auth = new OAuth2Authenticator (
    				clientId: "App ID from https://developers.facebook.com/apps",
    				scope: "",
    				authorizeUrl: new Uri ("https://m.facebook.com/dialog/oauth/"),
    				redirectUrl: new Uri ("http://www.facebook.com/connect/login_success.html"));

    Отредактируем:
    var auth = new OAuth2Authenticator (
    				clientId: "Id клиента, который запомнили на прошлом шаге",
    				scope: "friends,video,groups",
    				authorizeUrl: new Uri ("https://oauth.vk.com/authorize"),
    				redirectUrl: new Uri ("https://oauth.vk.com/blank.html"));

    Разберемся по порядку со всеми параметрами:
    • clientId — наш Id, который мы запомнили из панели администрирования приложений на самом сайте vk.com
    • scope — перечень разрешений, которые мы даем приложению (в данном случае: друзья, видел, группы; полный список смотрим в документации к API).
    • authorizeUrl — url авторизации по OAuth 2.0, для VK.com это oauth.vk.com/authorize (из обычного браузера открывать не стоит)
    • redirectUrl — url перенаправления, для VK.com это oauth.vk.com/blank.html (из обычного браузера также открывать не стоит)

    На этом можно запустить первый тест — проверить, как приложение подключается к серверу и логинится. Для порядка зайдем в «Strings.xml» (внутри папки values) и заменим надпись «Login to Facebook» на «Login to VK.com», и вообще все упоминания fb на vk :). Не забываем про Main.axml в папке layout. Удалим вторую кнопку «Login to Facebook (no cancel)», это осталось от оригинального примера.



    Полный код MainActivity (отсюда убрано все лишнее, что нам на данный момент не нужно):

    	[Activity (Label = "Xamarin.Auth Sample (Android)", MainLauncher = true)]
    	public class MainActivity : Activity
    	{
    		public string token;
    		public string userId;
    
    		void LoginToVk ()
    		{
    			var auth = new OAuth2Authenticator (
    				clientId: "Id клиента, который запомнили на прошлом шаге",
    				scope: "friends,video,groups",
    				authorizeUrl: new Uri ("https://oauth.vk.com/authorize"),
    				redirectUrl: new Uri ("https://oauth.vk.com/blank.html"));
    			auth.AllowCancel = true;
    			auth.Completed += (s, ee) => {
    				if (!ee.IsAuthenticated) {
    					var builder = new AlertDialog.Builder (this);
    					builder.SetMessage ("Not Authenticated");
    					builder.SetPositiveButton ("Ok", (o, e) => { });
    					builder.Create().Show();
    					return;
    				}
    				else
    				{
    					token = ee.Account.Properties ["access_token"].ToString ();
    					userId = ee.Account.Properties ["user_id"].ToString ();				
    				}
    			};
    			var intent = auth.GetUI (this);
    			StartActivity (intent);
    		}
    
    		private static readonly TaskScheduler UIScheduler = TaskScheduler.FromCurrentSynchronizationContext();
    
    		protected override void OnCreate (Bundle bundle)
    		{
    			base.OnCreate (bundle);
    			SetContentView (Resource.Layout.Main);
    			var vk = FindViewById<Button> (Resource.Id.VkButton);			
    			vk.Click += delegate { LoginToVk();};
    		}
    	}

    Обратите внимание, как лаконично можно «навешивать» действия на кнопки через += delegate. Мне такая возможность очень нравится: сначала ищем кнопку по Id, а затем добавляем к ней действие.

    На чем тестировать приложение? Раньше я использовал смартфон, подключенный по usb-шнуру, категорически не приемля стандартного Android эмулятора. Увы, скорость его работы оставляла желать лучшего, а возиться с виртуальной машиной и x86 Android не хотелось.

    Все изменилось, когда Xamarin выпустилии эмулятор под названием Android Player, в основе которого лежит все та же виртуальная машина (встроенная VM VirtualBox — работает очень быстро) и присутствует удобный интерфейс настройки виртуальных устройств с массой имеющихся шаблонов (почти как в стандартном Android-эмуляторе, только гораздо удобнее).



    Версия еще временами подглючивает, но для бытовых тестов ее хватает. Приятно удивила идеальная поддержка Monogame, никаких вылетов. Стоит отметить, что в Visual Studio 2015 в рамках интеграции с Xamarin, реализуется новый эмулятор Android, что тоже дает очень хорошие перспективы.

    В общем, при нажатии кнопки «Login to VK.com» должна появиться страница, как на скриншоте выше. Схема работы предельно проста:



    Vk.com при успешной авторизации возвращает access token — специальный идентификатор, ключ доступа. С помощью этого ключа можно выполнять другие запросы к API в рамках предоставленных привилегий. Сами привилегии мы указали в поле scope — доступ к перечню друзей, видео, группам пользователя (кстати, при авторизации VK.com обязательно спросит разрешение на их использование). Ключ доступа выдается на сутки.

    Выполняем запросы


    Получив access token, можно надолго уйти в изучение методов VK.com API, благо, прекрасно документированных. Подробнее с ними мы познакомимся в следующей статье, а пока, сделаем несколько приятных вещей, похожих на «Hello Word» в сфере использования VK.com API.

    Допустим, мы залогинились, и после этого приложение приглашает нас вступить в группу. Сперва реализуется вежливое приветствие (а нужно обязательно обратиться по имени!) через users.get, затем осуществляется проверка, присутствует ли пользователь в группе через groups.isMember, и в самом конце — функция вступления в группу groups.join.

    Во фрагмент кода, где происходит получение token-а и userId, добавим вызов нового метода GetInfo():

    					token = ee.Account.Properties ["access_token"].ToString ();
    					userId = ee.Account.Properties ["user_id"].ToString ();	
    					GetInfo();

    И проработаем сам метод (описание чуть ниже):

    		void GetInfo()
    		{
    			// создаем xml-документ
    			XmlDocument xmlDocument = new XmlDocument ();
    			// делаем запрос на получение имени пользователя
    			WebRequest webRequest = WebRequest.Create ("https://api.vk.com/method/users.get.xml?&access_token=" + token);
    			WebResponse webResponse = webRequest.GetResponse ();
    			Stream stream = webResponse.GetResponseStream ();
    			xmlDocument.Load (stream);
    			string name =  xmlDocument.SelectSingleNode ("response/user/first_name").InnerText;
    
    			// делаем запрос на проверку, 
    			webRequest = WebRequest.Create ("https://api.vk.com/method/groups.isMember.xml?group_id=20629724&access_token=" + token);
    			webResponse = webRequest.GetResponse ();
    			stream = webResponse.GetResponseStream ();
    			xmlDocument.Load (stream);
    			bool habrvk = (xmlDocument.SelectSingleNode ("response").InnerText =="1");
    
    			// выводим диалоговое окно
    			var builder = new AlertDialog.Builder (this);
    			// пользователь состоит в группе "хабрахабр"?
    			if (!habrvk) {
    				builder.SetMessage ("Привет, "+name+"!\r\n\r\nТы не состоишь в группе habrahabr.Не хочешь вступить?");
    				builder.SetPositiveButton ("Да", (o, e) => {
    					// уточнив, что пользователь желает вступить, отправим запрос
    					webRequest = WebRequest.Create ("https://api.vk.com/method/groups.join.xml?group_id=20629724&access_token=" + token);
    					 webResponse = webRequest.GetResponse ();
    				});
    				builder.SetNegativeButton ("Нет", (o, e) => {
    				});
    			} else {
    				builder.SetMessage ("Привет, "+name+"!\r\n\r\nОтлично! Ты состоишь в группе habrahabr.");
    				builder.SetPositiveButton ("Ок", (o, e) => {
    				});
    			}
    			builder.Create().Show();
    		}

    Здесь я использую режим работы в xml и обрабатываю все результаты запроса как XmlDocument. Никто не мешает использовать формат JSON (он тоже вполне удобен), достаточно лишь убрать ".xml" в запросе, дело вкуса.

    Итак, три команды:
    Интереса ради, попробуйте ввести эту строчку в адресную строку браузера :). Дописав token, конечно (его можно получить, поставив в программе breakpoint на строку присваивания соответствующей переменной). Увидите, что работать с VK.com API (да и большинством других) — просто! В общем случае задача сводится к элементарному парсингу xml или JSON.

    Результат выполнения команды «api.vk.com/method/groups.getById.xml?group_id=20629724&access_token=» + token:



    Диалоговые окна приложения:



    С уважением, Dageron.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 2

      +1
      Читаем и ждем ещё.
        0
        «Многообещающий проект на codeplex» имеет одну главную проблему — автор не находит времени им заниматься (сюда вот я тоже только что заглянул). А что не сработало, прошу написать в ЛС, мне интересно, ибо мне тогда запустить удавалось.

        В той идее мне не понравилось лишь одно — отсутствие portable-части, т. е. для iOS уже был б полностью отдельный модуль, но создал я его, когда официального SDK на .Net вообще не было. Идея «переписать, основываясь на .NET SDK для Windows Phone» у меня возникла, когда я увидел, что таковой стали делать. В последнее время я мало следил за его развитием, а основной моей идеей было выделить PCL с профилем 111 (или 259). За проект уровня этой статьи мне с моими темпами, понятное дело, браться было бессмысленно.

        Only users with full accounts can post comments. Log in, please.