Всё началось с того, что необходим был более или менее удобный инструмент для работы с 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:@"Альбом с фотографиями для Хабра"];
Вступить в группу:
VKUser *me = [VKUser currentUser]; [[me groups] joinGroupID:100500];
Установить статус:
VKUser *me = [VKUser currentUser]; [[me status] setStatus:@"Привет, Хабр!"];
Получить список друзей, которые сейчас на сайте:
[[[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__); NSLog(@"%@", accessToken); } - (void)VKConnector:(VKConnector *)connector accessTokenRenewalFailed:(VKAccessToken *)accessToken { NSLog(@"%s", __FUNCTION__); } - (void)VKConnector:(VKConnector *)connector accessTokenRenewalSucceeded:(VKAccessToken *)accessToken { NSLog(@"%s", __FUNCTION__); VKUser *me = [VKUser currentUser]; [[me friends] online]; } - (void)VKConnector:(VKConnector *)connector connectionErrorOccured:(NSError *)error { NSLog(@"%s", __FUNCTION__); NSLog(@"error: %@", error); } - (void)VKConnector:(VKConnector *)connector parsingErrorOccured:(NSError *)error { NSLog(@"%s", __FUNCTION__); NSLog(@"error: %@", error); } @end
После запуска перед пользователем возникает примерно такое модальное окно (использовался KGModal) для авторизации приложения:
Если возникают вопросы или вы не знаете для чего нужен (за что отвечает) тот или иной метод, то обращайтесь смело к документации. Документация сгенерирована при помощи AppleDoc и выглядит в целом следующим образом:
XCode поможет в этом:
В завершение
Статья, как мне кажется, получилась достаточно длинной, так что на этом пока остановлюсь, хотя к сожалению многое не упомянул из того, что планировал (загрузка файлов, обновление токена, обработка ошибок и тд)
Хочу отметить, что проект активно развивается и поддерживается. Текущий статус проекта — «Готов», поэтому в v1.0 будут только исправляться ошибки и вноситься мелкие коррективы. Все глобальные изменения переносятся в v2.0.
Найти самую актуальную версию можно по этой ссылке: https://bitbucket.org/AndrewShmig/vkontakte-ios-sdk-v1.0
Некоторую информацию по Vkontakte iOS SDK v2.0, правда очень краткую, можно найти здесь: https://bitbucket.org/AndrewShmig/vkontakte-ios-sdk-v2.0/wiki/Home
Благодарю за внимание.
ссылка на оригинал статьи http://habrahabr.ru/post/184560/
Добавить комментарий