Pull to refresh

ВКонтакте iOS SDK

Reading time 6 min
Views 20K
Добрый вечер!

Всё началось с того, что необходим был более или менее удобный инструмент для работы с API социальной сети ВКонтакте под iOS. Однако Google меня достаточно быстро расстроил результатами поиска:

Вроде бы всё хорошо, самое главное есть, но вот использование не вызывает приятных ощущений.

Под катом я расскажу, как работает новая версия ВКонтакте iOS SDK, с чего всё начиналось и к чему в итоге пришли.


Предпроект


Началось всё с того, что на работе получили задание подключить к приложению социальные сети. Мы хотели, чтобы пользователь не заметил никакой разницы при взаимодействии с разными социальными сетями (постинг фотографии на стену, отправка сообщения, загрузка фотографий и т.п.).
Было решено поискать готовые решения, которые бы содержали в себе несколько социальных сетей вроде ВКонтакте, Одноклассники, Твиттер и Фэйсбук, но ничего не удалось найти. Использование готовых решений по отдельности не давало нужных результатов, поэтому решили писать свои велосипеды, предварительно изучив Facebook iOS SDK, MGTwitterEngine и несколько других приметных библиотек.

В итоге мы получили ASASocialServices (GitHub).
Проект получился простым в использовании и установке, большее внимание уделялось работе с Twitter и Vkontakte, на Facebook было решено не концентрироваться.

В ASASocialServices работа с тремя социальными сетями (далее речь будет идти только о двух) осуществлялась по единому принципу: программист создаёт UIWebView, позиционирует его и отображает, затем запускает процесс авторизации пользователем приложения и, в зависимости от принятого пользователем решения, вызывается один из трёх блоков-обработчиков (success, error, cancel).

Если рассматривать в контексте, то ViewController.h выглядит примерно так:
#import <UIKit/UIKit.h>
#import "ASASocialServices.h"

@interface ViewController : UIViewController

@property UIWebView *webView;
@property ASATwitterCommunicator *tw;

@end


ViewController.m
#import "ViewController.h"

NSString *const kTWITTER_CONSUMER_KEY = @"v8146mdwpo05uEroMnhozg";
NSString *const kTWITTER_CONSUMER_SECRET = @"5AFkvjCKxqGBRId2fpSQFLClJLKtGcPGS1DzK7o";

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // устанавливает WebView в нужной позиции и с нужными размерами
    CGRect frame = [[UIScreen mainScreen] bounds];
    _webView = [[UIWebView alloc] initWithFrame:frame];
    [self.view addSubview:_webView];

    // создаем TwitterCommunicator для получения токенов
    _tw = [[ASATwitterCommunicator alloc]
            initWithWebView:_webView];

    // инициируем запрос по получению доступа к пользовательскому аккаунту
    [_tw startOnCancelBlock:^{
        NSLog(@"User canceled app authorization...");
    } onErrorBlock:^(NSError *error) {
        NSLog(@"error during app authorization...%@", error);
    } onSuccessBlock:^(ASATwitterUserAccount *account) {
        NSLog(@"Account: %@", account);
    }];
}

@end


Достаточно было заменить ASATwitterCommunicator на ASAVkontakteCommunicator или ASAFacebookCommunicator, чтобы подключить и начать работать с другой социальной сетью.
В последний блок — success, происходила передача пользовательской учетной записи соответствующей сети (токен доступа, идентификатор пользователя, время истечения действия токена доступа и т.д.)

Последующие запросы от лица текущего пользователя можно было производить таким образом:
[account performTwitterMethod:kTWITTER_FOLLOWERS_LIST_URL
                           HTTPMethod:@"GET"
                              options:@{@"user_id" : account.twitterUserID,
                                        @"include_entities": @"true"}
                              success:^(id response) {
                                  NSLog(@"response: %@", response);
                              }
                              failure:^(NSError *error) {
                                  NSLog(@"error: %@", error);
                              }];


Вот как выглядит обновление статуса пользователя в Twitter:
[account performTwitterMethod:kTWITTER_STATUSES_UPDATE_URL
                           HTTPMethod:@"POST"
                              options:@{@"status": @"Hello from ASASocialServices Framework!"}
                              success:^(id response) {
                                  NSLog(@"response: %@", response);
                              } failure:^(NSError *error) {
                                  NSLog(@"error: %@", error);
                              }];


Всё бы хорошо, но в ходе использование, поняли, что оставлять за программистом сохранение токена, последующую загрузку было не совсем правильно потому, что наша-то основная цель настолько упростить работу с библиотекой, чтобы не приходилось думать о мелочах вроде этой (библиотека на данном этапе умерла и её разработкой/поддержкой пришлось заниматься одному, как и всеми последующими разработками).

Минусы:
  • Программисту необходимо было помнить, что токен доступа можно сохранить и использовать в последующих запросах, а не вешать запросы в success-блок
  • Оставлять на программиста настройку и работу с UIWebView было тоже ошибкой
  • Библиотека казалась слишком сложной и непонятной, большинству не хотелось думать о том POST или GET использовать при запросах


ВКонтакте iOS SDK v1.0


С  ASASocialServices мне больше не хотелось возиться, поэтому решил, что начну писать в свободное время SDK для ВКонтакта. Набросал на листке схему взаимодействия классов, дня два над ней «висел», в итоге решил, что на первую версию похоже — приступил к реализации.

Я люблю Ruby и мне нравятся Rails и, почему-то всегда и до сих пор кажется, что именно они в некоторой степени повлияли на вид Вконтакте iOS SDK.

Пользователь связан с такими объектами, как:
  • Группы
  • Стена
  • Друзья
  • Аудио альбомы
  • Видео альбомы
  • Фотоальбомы
  • Записи
  • Документы
  • тд


У каждого объекта есть список действий, который пользователь может осуществить от своего лица:
  • Создать фотоальбом
  • Вступить в группу
  • Установить/изменить статус
  • Получить список друзей, которые сейчас на сайте
  • и тд


Вот, как приведенные выше действия будут выглядеть во ВКонтакте iOS SDK v1.0:

Создание фотоальбома:
    VKUser *me = [VKUser currentUser];
    [[me photoAlbums] createTitle:@"Привет, Хабр!" description:@"Альбом с фотографиями для Хабра"];

image

Вступить в группу:
    VKUser *me = [VKUser currentUser];
    [[me groups] joinGroupID:100500];


Установить статус:
    VKUser *me = [VKUser currentUser];
    [[me status] setStatus:@"Привет, Хабр!"];


Получить список друзей, которые сейчас на сайте:
id result = [[[VKUser currentUser] friends] online];


С чего начать?

Предположим, что Вы уже добавили Vkontakte IOS SDK v1.0 к себе в проект и не знаете что делать дальше с этим.

Мы будем работать с классом VKConnector, который позволит нам получит+сохранить+использовать полученный токен доступа единожды, а в нужный момент он уведомит нас, что необходимо обновить токен и вызовет соответствующий метод делегата, который может следовать (а может и нет) VKConnectorProtocol.

Вот, как будет выглядеть самый простой способ подключения в ASAAppDelegate.m:
//
//  ASAAppDelegate.m
//  Vkontakte iOS SDK_Project
//
//  Created by AndrewShmig on 05/27/13.
//  Copyright (c) 2013 AndrewShmig. All rights reserved.
//

#import "ASAAppDelegate.h"
#import "ASAViewController.h"
#import "VKUser.h"


static NSString *const kVKAppID = @"3541027";
static NSString *const kVKPermissionsArray = @"photos,friends,wall,audio,video,docs,notes,pages,status,groups,messages";


@implementation ASAAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    [[VKConnector sharedInstance] setDelegate:self];
    [[VKConnector sharedInstance] startWithAppID:kVKAppID
                                      permissons:[kVKPermissionsArray componentsSeparatedByString:@","]];

    // Override point for customization after application launch.
    self.viewController = [[ASAViewController alloc] initWithNibName:@"ASAViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)VKConnector:(VKConnector *)connector willShowModalView:(KGModal *)view
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)VKConnector:(VKConnector *)connector willHideModalView:(KGModal *)view
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)VKConnector:(VKConnector *)connector accessTokenInvalidated:(VKAccessToken *)accessToken
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)VKConnector:(VKConnector *)connector accessTokenRenewalFailed:(VKAccessToken *)accessToken
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)VKConnector:(VKConnector *)connector accessTokenRenewalSucceeded:(VKAccessToken *)accessToken
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)VKConnector:(VKConnector *)connector connectionErrorOccured:(NSError *)error
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)VKConnector:(VKConnector *)connector parsingErrorOccured:(NSError *)error
{
    NSLog(@"%s", __FUNCTION__);
}

@end


После запуска перед пользователем возникает примерно такое модальное окно (использовался KGModal) для авторизации приложения:
image

Если возникают вопросы или вы не знаете для чего нужен (за что отвечает) тот или иной метод, то обращайтесь смело к документации. Документация сгенерирована при помощи AppleDoc и выглядит в целом следующим образом:
image

VKConnectorProtocol:
image

XCode поможет в этом:
image

В завершение


Статья, как мне кажется, получилась достаточно длинной, так что на этом пока остановлюсь, хотя к сожалению многое не упомянул из того, что планировал (загрузка файлов, обновление токена, обработка ошибок и тд)

Хочу отметить, что проект активно развивается и поддерживается. Текущий статус проекта — «Готов», поэтому в v1.0 будут только исправляться ошибки и вноситься мелкие коррективы. Все глобальные изменения переносятся в v2.0.

Найти самую актуальную версию можно по этой ссылке: GitHub ( https://github.com/AndrewShmig/Vkontakte-iOS-SDK )

Некоторую информацию по Vkontakte iOS SDK v2.0, можно найти здесь: GitHub (https://github.com/AndrewShmig/Vkontakte-iOS-SDK-v2.0/issues?labels=Future+features&state=open)

Благодарю за внимание.
Tags:
Hubs:
+18
Comments 15
Comments Comments 15

Articles