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.Authlibandroid».
Итак, можно приступать к правке кода.
Оригинальный фрагмент объекта типа 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+"!rnrnТы не состоишь в группе 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+"!rnrnОтлично! Ты состоишь в группе habrahabr.");
builder.SetPositiveButton ("Ок", (o, e) => {
});
}
builder.Create().Show();
}
Здесь я использую режим работы в xml и обрабатываю все результаты запроса как XmlDocument. Никто не мешает использовать формат JSON (он тоже вполне удобен), достаточно лишь убрать ".xml" в запросе, дело вкуса.
Итак, три команды:
- «api.vk.com/method/users.get.xml?&access_token=» + token
- «api.vk.com/method/groups.isMember.xml?group_id=20629724&access_token=» + token
- «api.vk.com/method/groups.join.xml?group_id=20629724&access_token=» + token
Интереса ради, попробуйте ввести эту строчку в адресную строку браузера :). Дописав token, конечно (его можно получить, поставив в программе breakpoint на строку присваивания соответствующей переменной). Увидите, что работать с VK.com API (да и большинством других) — просто! В общем случае задача сводится к элементарному парсингу xml или JSON.
Результат выполнения команды «api.vk.com/method/groups.getById.xml?group_id=20629724&access_token=» + token:
Диалоговые окна приложения:
Исходники проекта приведены на GitHub. Возможно, скоро там появится еще что-нибудь интересно на тему VK.com API и Xamarin. Об этом обязательно напишу в новой статье.
С уважением, Dageron.
Автор: Dageron