Pull to refresh

Flash + вКонтакте API

Reading time12 min
Views1.6K

По шагам описаны регистрация и создание flash приложения под социальную сеть вКонтакте, использующего вызовы вКонтакте API. Написан AS3 класс-обёртка для вКонтакте API.
Приложение, процесс создания под катом.

В конце поста архив с кодом проекта.

Пункт 1. Регистрация приложения vKontakte


Для этого понадобится регистрация вас в контакте, процедура тривиальна, описывать смысла не имеет. После регистрации переходим по адресу http://vkontakte.ru/gsearch.php?from=apps, это общий список приложений. Вверху выбираем «создать приложение»


Заполняем название, описание, тип и переходим к загрузке приложения.



На данном этапе ваше приложение уже создано и зарегистрировано в базе. Следующий экран доступен для каждого созданного вами приложения. Описание важных элементов после картинки.



Синим выделена форма загрузки приложения. В отличие от facebook'a здесь надо загрузить приложение на сервер, а не указать внешний CanvasURL где оно лежит. Фиолетовым выделен так называемый «sandbox mode», — если приложение «выключено», то его смогут загрузить либо вы, либо ваши друзья, и все запросы к нему должны содержать параметр «test_mode=1» (про параметры запроса см. ниже). Зелёным выделены поля, уникально идентифицирующие ваше приложение, они используются в запросах vKontakteAPI (см. ниже).

Пункт 2. ТЗ приложения под vKontakte API


Сверху написать «Привет, %username%», под приветствием показать список друзей.
Пара слов о вКонтакте API:
— вся документация доступна по адресу http://vkontakte.ru/pages.php?id=2369267 (для чтения надо иметь аккаунт вКонтакте)
— линейные размеры flash приложения не должны превышать 607x590
— больше трёх запросов в секунду от одного приложения обрубается.

Пункт 3. Написание приложения под vKontakte API


Написано под flex, класс-обёртка API не тянет за собой flex-компонентов, так что может быть использована в чистом flash.
Итак (описание класса VKontakteAPI в следующем пункте).

main.mxml

После старта приложения вызывает получение информации о текущем пользователе и список его друзей, далее получает информацию по друзьям и выводит их списком.

Здесь есть небольшая проблема. Информацию о текущем пользователе можно получить всегда, но вот список друзей приложение не получит, пока пользователь специально не укажет что этому приложению это делать можно. По-этому, полученные данные проверяются на наличие этой ошибки и пользователю предлагается разрешить доступ приложения к своим друзьям (state «enable_friends»). Коды ошибок для каждой функции описаны на странице документации.

код:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
  layout="absolute"
  width="607" height="590"
  applicationComplete="onAppStart()">

  <mx:Style>
    Text,Label
    {
      color: "0xFFFFFF";
      font-size: 24;
    }
  </mx:Style>
  
  <mx:states>
    <mx:State name="enable_friends">
      <mx:RemoveChild target="{mainContainer}"/>
      <mx:AddChild position="lastChild">
        <mx:Text
          text="Приложение не может получить доступ к вашим друзьям. Вверху нажмите на 'Настройки' и в меню выберите 'Разрешить приложению доступ к друзьям'. После чего перегрузите страницу."
          selectable="false"
          horizontalCenter="0" verticalCenter="0"
          width="570" height="200"/>
      </mx:AddChild>
    </mx:State>
  </mx:states>
  
  <mx:VBox
    id="mainContainer"
    horizontalCenter="0" verticalCenter="0"
    width="590"
    maxHeight="570"
    horizontalAlign="center">
    <mx:Label
      id="userNameLabel"
      text="Привет, %username%"/>
    <mx:Label id="friendsCaptionLabel" text="Ваши друзья:"/>
  </mx:VBox>
  
  <mx:Script>
    <![CDATA[
    
      import vkontakte.VKontakteAPI;
      
      private function onAppStart() : void
      {
        // pass flashvars to the vKontakte init
        VKontakteAPI.init(this.parameters);
        // request user info for current user
        VKontakteAPI.getProfiles([VKontakteAPI.uid], onGetUserInfo);
        // request friends
        VKontakteAPI.getFriends(onGetFriends);
      }
      
      private function onGetUserInfo(result : Object) : void
      {
        // set user label text to the user first_name + last_name
        userNameLabel.text =
          "Привет, " +
          result.response[0].first_name +
          " " +
          result.response[0].last_name;
      }
      
      private function onGetFriends(result : Object) : void
      {
        if(result.error)
        {
          // if app have not access to friends
          if(result.error.error_code == 7)
          {
            // tell user to allow access
            currentState = "enable_friends";
            return;
          }
          return;
        }
        
        // no error
        
        // have not friends
        if(result.response.length <= 0)
        {
          var no_friends_label : Label = new Label();
          no_friends_label.text = "их нет (";
          mainContainer.addChild(no_friends_label);
          return;
        }
        
        // have friends, get info
        VKontakteAPI.getProfiles(result.response, onGetFriendsInfo);
      }
      
      private function onGetFriendsInfo(result : Object) : void
      {
        for(var i : int = 0; i < result.response.length; i++)
        {
          var friend_label : Label = new Label();
          friend_label.text = result.response[i].first_name + " " + result.response[i].last_name;
          mainContainer.addChild(friend_label);
        }
      }
      
    ]]>
  </mx:Script>
</mx:Application>

* This source code was highlighted with Source Code Highlighter.


Пункт 4. vKontakte as3 API


Собственно, класс, который занимается формированием и отсылкой запросов к серверу вКонтакте
Обработка ошибок отсутствует, т.к. писался для проверки и неизвестно буду ли серьезно писать под вКонтакте.

APP_SECRET доступен на странице редактирования приложения. API_ID и USER_ID заполнены для того, чтобы можно было локально отлаживаться. TEST_MODE выставлен в 1, т.к. приложение пока в разработке и «выключено». В коде реального приложения это значение выставлено в 0.
  public class VKontakteAPI
  {
    // application secret key
    private static const APP_SECRET : String = "SuxPmMMxDj";

    // stored application id to use when running locally
    private static var API_ID  : String = "1643226";
    // stored user id to use when running locally
    private static var UID    : String = "52531344";
    // test mode for running in sandbox mode
    // replace by "0" after switching application to public access
    private static var TEST_MODE : String = "1";

* This source code was highlighted with Source Code Highlighter.


Имя функции говорит за себя, эти параметры включаются во все запросы. В качестве типа возвращаемых данных выбран json (по умолчанию xml)
Для работы с json используется библиотека JSWOOF
    // return array of values included in all requests
    private static function getBaseValues() : Array
    {
      return [
        "api_id=" + API_ID,
        "v=2.0",
        "format=json",
        "test_mode=" + TEST_MODE
      ];
    }

* This source code was highlighted with Source Code Highlighter.


Создание MD5 хеша запроса. По правилам вКонтакте он должен быть равен md5(UID+param1+...paramN+APP_SECRET), причём параметры должны конкатенироваться в алфавитном порядке. Класс MD5 нагуглен.
    // returns MD5 as required by vKontakte API
    private static function getMD5(values : Array) : String
    {
      // sort values alphabetically
      values.sort();
      
      var hash_str : String = "";      
      hash_str += UID;
      for(var i : int = 0; i < values.length; i++)
        hash_str += values[i];
      hash_str += APP_SECRET;
      
      return MD5.hex_md5(hash_str);
    }

* This source code was highlighted with Source Code Highlighter.


Создание URL запроса.
    // combine request string
    private static function getRequestString(values : Array) : String
    {
      var request : String = "http://api.vkontakte.ru/api.php";
      for(var i : int = 0; i < values.length; i++)
        request += (i == 0 ? "?" : "&") + values[i];
      return request;
    }

* This source code was highlighted with Source Code Highlighter.


Главная функция, отсылающая запрос на сервер vkontakte. В ней к базовым параметрам запроса добавляется имя метода, дополнительные параметры (если есть). К параметрам также добавляется md5 вычисленный от них же.
Далее запускается URLLoader, который по завершении запроса парсит json строку в объект и отсылает этот объект в callback.
    // main request function
    // method - vKontakteAPI method name (like "getUserInfo" or "getProfiles")
    // add_values - addition method parameters (ex. for "getProfiles"
    //   add_values must contain list of uids like "uids=123,3124,3123")
    // callback - function called after completing request
    private static function makeRequest(method : String, add_values : String, callback : Function) : void
    {
      // base values for all requests
      var values : Array = getBaseValues();
      // add method name
      values.push("method=" + method);
      // add additional values if have any
      if(add_values)
        values.push(add_values);
      // calculate md5 hash and add it to values array
      values.push("sig=" + getMD5(values));
      
      // request loader
      var loader : URLLoader = new URLLoader();
      // register listener for COMPLETE event
      loader.addEventListener(
        Event.COMPLETE,
        function (event : Event) : void 
        {
          // extract loader from event
          var loader : URLLoader = URLLoader(event.target);
          // parse json data and pass it
          // to callback function
          callback(JParser.decode(loader.data));
        });
      // fire request with url created from values
      loader.load(new URLRequest(getRequestString(values)));
    }

* This source code was highlighted with Source Code Highlighter.


Функция инициализации. Просто заполняет uid текущего пользователя из переданных flashvars.
     // must be called at application start
    // to init API variables (or left default values when running locally)
    public static function init(flashvars : Object) : void
    {
      // if have viewer_id in flashvars
      if(flashvars.viewer_id)
      {
        // then it means that application started in vKontakte framework
        // update userID for user whos started application
        UID = flashvars.viewer_id;
      }
    }

* This source code was highlighted with Source Code Highlighter.


Это всё что нужно для оборачивания функций vkontakte API.
Для примера, две функции, используемые в данном приложении.
    // get basic user(s) data (uid, first_name, last_name) for provided uids array
    public static function getProfiles(uids : Array, callback : Function) : void
    {
      var uids_str : String = "uids=" + uids[0];
      for(var i : int = 1; i < uids.length; i++)
        uids_str += "," + uids[i];
      makeRequest("getProfiles", uids_str, callback);
    }
    
    // returns friends of the current user
    public static function getFriends(callback : Function) : void
    {
      makeRequest("getFriends", null, callback);
    }

* This source code was highlighted with Source Code Highlighter.


Архив проекта под Eclipse+FlexBuilder доступен по ссылке, там же build.xml для сборки антом в консоли.

P.S.

На некоторых системах вместо своего имени и имен друзей выводятся кракозябры. Есть подозрение, что это из-за кодировки возвращаемого json объекта. Посему на vKontakte перезалито приложение, использующее «format=xml» в параметрах запроса. Соот-но данные приходят в XML формате, UTF-8 кодировка.
Линк на исходники XML версии — тырк.

Tags:
Hubs:
+27
Comments12

Articles