15 VK

В этой небольшой статье я хотел бы поделиться способами интеграции Вконтакте API в проект IOS.
По этой теме сейчас в интернете мало информации и возможно мои советы кому-то помогут. Я покажу как можно не только получить данные пользователя, но и разместить на стене фотографию, текст и ссылку, а так же случай с вводом капчи.
Проект с примером лежит на github.com – https://github.com/maiorov/VKAPI
Документацию по методам API ВКонтакте можно почитать
Статьи из других источников на эту тему:
1. appleinsider.ru
2. imaladec.net
Итак, несколько этапов в работе с VK API:
1. Авторизация пользователя через UIWebView и получение accessToken’a и идентификатора пользователя.
2. Использование VK API, запросы и получение данных:
2.1 Отправка текста на стену пользователя
2.1.1
2.2 Отправка изображения на стену
2.2.1 Получение url сервера ВКонтакте для загрузги изображения
2.2.2 Формируем POST запрос
2.2.3 Создаем запрос на сохранение фото на сервере ВКонтакте
2.2.4 Размещаем фото на стене
3. Logout пользователя
Часть 0. Регистрация приложения
Как выяснилось, не самая тривиальная часть операции, из-за того, что ВКонтакте несколько форм создания mobile-приложений! Для правильной регистрации нужно воспользоваться ссылкой , выбрать тип приложения Standalone-приложение. Параметры в настройках можно не указывать. Нужно лишь скопировать ID приложения. В моем примере для этого параметра используется appID.
Часть 1. Авторизация
Для работы по протоколу Oauth 2.0 с VK API нам понадобится accessToken и user_id. Мы можем получить его отправив запрос на сервер VK через веб-браузер UIWebView, в ответ на запрос сервер ВКонтакте выдаст форму авторизации пользователя, после прохождения авторизации мы получим accessToken, user_id (id пользователя, который ввел свои данные), expires_in (время действия токена). Для этого в новом проекте создадим view-controller, назовем его например vkLoginViewController. Это будет контроллер отвечающий за авторизацию пользователя, при успешной авторизации, он сохраняет полученные параметры в NSUserDefaults и вызывает метод делегата authComplete.
Подробный код вы можете посмотреть в примере. Здесь я разберу только основные моменты.
Добавив в контроллер UIWebView *vkWebView, мы делаем запрос:

NSString *authLink = ; NSURL *url = ; ];
Тут client_id это id вашего приложения, scope=wall,photos – это права доступа, которые приложение запрашивает у пользователя (wall размещение на стене, photos нужно чтобы размещать изображения на стене)
В функции webViewDidFinishLoad получаем ответ от сервера ВКонтакте:
-(void)webViewDidFinishLoad:(UIWebView *)webView { // Если есть токен сохраняем его if (.location != NSNotFound) { NSString *accessToken = URL] absoluteString]]; // Получаем id пользователя, пригодится нам позднее NSArray *userAr = URL] absoluteString] componentsSeparatedByString:@»&user_id=»]; NSString *user_id = ; NSLog(@»User id: %@», user_id); if(user_id){ setObject:user_id forKey:@»VKAccessUserId»]; } if(accessToken){ setObject:accessToken forKey:@»VKAccessToken»]; // Сохраняем дату получения токена. Параметр expires_in=86400 в ответе ВКонтакта, говорит сколько будет действовать токен. // В данном случае, это для примера, мы можем проверять позднее истек ли токен или нет setObject: forKey:@»VKAccessTokenDate»]; synchronize]; } NSLog(@»vkWebView response: %@», URL] absoluteString]); ; ; } else if (.location != NSNotFound) { NSLog(@»Error: %@», vkWebView.request.URL.absoluteString); ; } }

После этого, мы получили все необходимое: accessToken, user_id. И передаем делегату, что авторизация успешно пройдена, больше нам этот контроллер не нужен и мы его убираем:
; ;
Часть 2. Запросы к API
Теперь начинается самое интересное! В примере в контроллере ViewController я подготовил несколько функций, по которым вы сможете понять как работать с API.
2.1 Отправка текста на стену пользователя
Возьмем, для примера, функцию отправки текста на стену:
— (void) sendText { NSString *user_id = objectForKey:@»VKAccessUserId»]; NSString *accessToken = objectForKey:@»VKAccessToken»]; NSString *text = @»Работать с ВКонтакте API легко!»; // Создаем запрос на размещение текста на стене NSString *sendTextMessage = ]; NSLog(@»sendTextMessage: %@», sendTextMessage); // Если запрос более сложный мы можем работать дальше с полученным ответом NSDictionary *result = ; // Если есть описание ошибки в ответе NSString *errorMsg = objectForKey:@»error_msg»]; if(errorMsg) { ; } else { ; } }
Для простоты примера, я храню данные в NSUserDefaults. Авторизация пройдена, значит у нас есть все необходимое чтобы составить запрос. Используя метод wall.post, передаем id пользователя (owner_id) и токен (access_token), сообщение text для параметра message мы предварительно прогоняем через функцию URLEncodedString:
// Функция преобразования текста в подходящий для передачи формат — (NSString *)URLEncodedString:(NSString *)str { NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)str, NULL, CFSTR(«!*'();:@&=+$,/?%#»), kCFStringEncodingUTF8); ; return result; }
После того, как мы подготовили запрос, нужно отправить его на сервер с помощью функции: ; Как вы можете заметить, фунцкция принимает параметр with:(BOOL) это понадобится нам в случае, если сервер затребует ввод капчи у пользователя для подтверждения действий. Так как пока что не требуется, мы передаем NO.
Собственно, сама функция отправки запроса:
— (NSDictionary *) sendRequest:(NSString *)reqURl with:(BOOL) { // Если это запрос после ввода капчи, то добавляем в запрос параметры _sid и _key if( == YES){ NSString *_sid = objectForKey:@»_sid»]; NSString *_user = objectForKey:@»_user»]; // Добавляем к запросу данные для капчи. Не забываем, что введенный пользователем текст нужно обработать. reqURl = ]; } NSLog(@»Sending request: %@», reqURl); NSMutableURLRequest *request = cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0]; // Для простоты используется обычный запрос NSURLConnection, ответ сервера сохраняем в NSData NSData *responseData = ; // Если ответ получен успешно, можем его посмотреть и заодно с помощью JSONKit получить NSDictionary if(responseData){ NSDictionary *dict = parseJSONData:responseData]; // Если есть описание ошибки в ответе NSString *errorMsg = objectForKey:@»error_msg»]; NSLog(@»Server response: %@ \nError: %@», dict, errorMsg); // Если требуется ввод капчи. Тут я проверяю на строку needed, хотя лучше использовать код ошибки. if(){ is = YES; // Сохраняем параметры для капчи NSString *_sid = objectForKey:@»_sid»]; NSString *_img = objectForKey:@»_img»]; setObject:_img forKey:@»_img»]; setObject:_sid forKey:@»_sid»]; // Сохраняем url запроса чтобы сделать его повторно после ввода капчи setObject:reqURl forKey:@»request»]; synchronize]; ; } return dict; } return nil; }

Функция возвращает NSDictionary ответ сервера, для его формирования используется JSONKit, так как по-умолчанию ВКонтакте отвечает в формате JSON.

Если вдруг сервер решил, что пользвателю нужно ввести , то он, в ответ на запрос, вернет ошибку с текстом: needed и параметрами – _sid (это id капчи), _img (ссылка на изображение капчи). Вооружившись этими параметрами и заодно сохранив запрос, по которому сервер нам так ответил, мы вызываем функцию ввода капчи: ;
Рассмотрим ее чуть подробнее:
— (void) get { NSString *_img = objectForKey:@»_img»]; UIAlertView *myAlertView = initWithTitle:@»Введите код:\n\n\n\n\n» message:@»\n» delegate:self cancelButtonTitle:@»Cancel» otherButtonTitles:@»OK», nil]; UIImageView *imageView = initWithFrame:CGRectMake(12.0, 45.0, 130.0, 50.0)] autorelease]; imageView.image = ]]; ; UITextField *myTextField = initWithFrame:CGRectMake(12.0, 110.0, 260.0, 25.0)] autorelease]; ]; // Отключаем автокорректировку myTextField.autocorrectionType = UITextAutocorrectionTypeNo; // Отключаем автокапитализацию myTextField.autocapitalizationType = UITextAutocapitalizationTypeNone; myTextField.tag = 33; ; ; ; } — (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { if(is && buttonIndex == 1){ is = NO; UITextField *myTextField = (UITextField *); setObject:myTextField.text forKey:@»_user»]; NSLog(@» entered: %@»,myTextField.text); // Вспоминаем какой был последний запрос и делаем его еще раз NSString *request = objectForKey:@»request»]; NSDictionary *newRequestDict =; NSString *errorMsg = objectForKey:@»error_msg»]; if(errorMsg) { ; } else { ; } } }
Используя стандартный UIAlertView, с добавлением UIImageView и UITextField, и параметр _img, мы даем пользователю возможность ввести . После того как введена, в функции делегата UIAlertView сохраняем то, что ввел пользователь в NSUserDefaults с ключем _user и используя ранее сохраненный url запроса, делаем его повторно, на этот раз указав в параметре with: YES. В итоге, перед отправкой запроса, к нему добавляюся параметы _sid и _key (то что ввел пользователь):
— (NSDictionary *) sendRequest:(NSString *)reqURl with:(BOOL) { // Если это запрос после ввода капчи, то добавляем в запрос параметры _sid и _key if( == YES){ NSString *_sid = objectForKey:@»_sid»]; NSString *_user = objectForKey:@»_user»]; // Добавляем к запросу данные для капчи. Не забываем, что введенный пользователем текст нужно обработать. reqURl = ]; } …
введена, запрос отправлен, текст должен быть успешно размещен на стене пользователя!
2.2 Отправка изображения на стену
Часто встречается необходимость разместить фото из приложения на стене пользователя. Чтобы решить эту задачу нужно пройти следующие этапы:

  1. Запрос url сервера ВКонтакте для загрузки нашего изображения (photos.getWallUploadServer)
  2. По полученной ссылке в ответе сервера отправляем изображение методом POST
  3. Получив в ответе hash, photo, server, отправлем команду на сохранение фото на стене (photos.saveWallPhoto)
  4. Получив в ответе photo id, делаем запрос на размещение на стене картинки с помощью wall.post, где в качестве attachment указываем photo id

2.2.1 Получение url сервера ВКонтакте для загрузки изображения
— (IBAction)sendImageAction:(id)sender { if(!isAuth) return; UIImage *image = ; NSString *user_id = objectForKey:@»VKAccessUserId»]; NSString *accessToken = objectForKey:@»VKAccessToken»]; // Этап 1 NSString *getWallUploadServer = ; NSDictionary *uploadServer = ; // Получаем ссылку для загрузки изображения NSString *upload_url = objectForKey:@»upload_url»]; …
Теперь, получив ссылку для загрузки изображения, нам нужно сделать POST запрос с вложенным изображением. Для этого изображение преобразуем в NSData и создаем запрос с помощью функции ;
2.2.2 Формируем POST запрос
… // Этап 2 // Преобразуем изображение в NSData NSData *imageData = UIImageJPEGRepresentation(image, 1.0f); NSDictionary *postDictionary = ; // Из полученного ответа берем hash, photo, server NSString *hash = ; NSString *photo = ; NSString *server = ; …
Функцию формирующую POST-запрос вы можете посмотреть в примере.
2.2.3 Создаем запрос на сохранение фото на сервере ВКонтакте
… // Этап 3 // Создаем запрос на сохранение фото на сервере вконтакте, в ответ получим id фото NSString *saveWallPhoto = ; NSDictionary *saveWallPhotoDict = ; NSDictionary *photoDict = lastObject]; NSString *photoId = ; …
В ответ получаем photo id загруженной фотографии, теперь осталось сделать обычный запрос wall.post, где в качестве параметра attachment указать photo id. Если нужно еще добавить ссылку, то достаточно после photo id, через запятую указать ее.
2.2.4 Размещаем фото на стене
… // Этап 4 // Постим изображение на стену пользователя NSString *postToWallLink = , photoId]; NSDictionary *postToWallDict = ; NSString *errorMsg = objectForKey:@»error_msg»]; if(errorMsg) { ; } else { ; } // Ура! Фото должно быть на стене!
Часть 3. Logout пользователя
Чтобы сделать logout достаточно отправить на сервер ВКонтакте запрос:
NSString *logout = @»http://api.vk.com/oauth/logout»;
Пример функции logout:
— (IBAction)logout:(id)sender { // Запрос на logout NSString *logout = @»http://api.vk.com/oauth/logout»; NSMutableURLRequest *request = cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0]; NSData *responseData = ; if(responseData){ NSDictionary *dict = parseJSONData:responseData]; NSLog(@»Logout: %@», dict); // Приложение больше не авторизовано, можно удалить данные isAuth = NO; removeObjectForKey:@»VKAccessUserId»]; removeObjectForKey:@»VKAccessToken»]; removeObjectForKey:@»VKAccessTokenDate»]; synchronize]; ; } }
Несмотря на то, что ВКонтакте отвечает ошибкой, выход пользователя все-таки происходит 🙂

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

С середины ноября в социальной сети «ВКонтакте» всё чаще можно увидеть, как привычные картинки в постах делят надвое. Выглядит это как-то так:

БРИТИШ ЮМОР

Оригинал

Оригинал

Овсянка, сэр!

Оригинал

Оригинал

FTP

Оригинал

Оригинал

Разумеется, вскоре шутки про «распополамленные» картинки заполнили соцсеть. Админы некоторых пабликов и сами не удержались от мемов на эту тему.

Орленок

Оригинал

Оригинал

Ну а простых пользователей VK и вовсе не остановить.

Вскоре администраторы групп, начавших публиковать разрезанные картинки, рассказали, в чём дело. Так, в фанатском паблике Гроб Дио // JoJo’s Bizarre Adventure появилось такое объяснение:

Дорогие подписчики! Мы режем мемы не потому, что нам скучно и нечего делать, а из-за того, что «ВК» не продвигает посты с одной картинкой в ленту. Нам приходится разрезать мемы. Извините, нам приходится это делать, иначе паблик не будет развиваться, а наоборот, уйдёт вниз.

В некоторых группах решили не разрезать картинки, а добавлять в каждый пост дополнительное изображение: чаще всего белый квадрат или полоску, сливающуюся с фоном социальной сети. Такой способ упоминается в скриншоте сообщения о происходящем, которое разошлось по «ВКонтакте».

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

«Картинки могут говорить»

Оригинал Ребята, что с фидбеком? Пять тысяч человек в группе, раньше на фотоэссе было 15 репостов, сейчас на некоторых ни одного. Вы там точно не выпилились?Оригинал

The Sufferer

Оригинал «ВК» урезал фидбек в группах, подробностей не знаю, но, короче, контент, который постят теперь художники, умная лента считает неинтересным и не предлагает пользователям…Оригинал

LIBRI 18+

Оригинал У всех художников буквально в начале ноября рухнули просмотры, и всё благодаря новым алгоритмам «умной» ленты. У меня так они вообще упали просто страшно, что меня даже вогнало в хандру, пока я не выяснил, в чём дело.Оригинал

На запрос Medialeaks представители VK ответили, что последнее крупное обновление умной ленты действительно было в начале ноября, и после изменений трафик действительно мог перераспределиться между авторами и типами контента.

Ранжирование форматов контента зависит от аудитории. В некоторых пабликах коллажи действительно могут набирать больше просмотров, чем пост с одной фотографией. Это значит, что такие записи вызывают больше интереса у подписчиков, чем публикации другого формата в их же лентах. Андрей Якушев, руководитель направления потребления контента и рекомендаций

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

Если какой-то формат контента используется для искусственного повышения охвата, мы реагируем на это и вносим изменения в работу алгоритма.

Последние обновления социальной сети представители VK показали на VK Content Day 13 ноября. И тогда главной новостью для всех стало введение дизлайков. Кнопка «не нравится» должна помочь фильтровать контент, но пользователи интернета в ужасе объяснили, почему это очень плохая идея.

Ну а если вы уже устали от разрезанных картинок и хотите посмотреть на что-то цельное (и милое), то мем про маленького Йоду — то, что вам нужно. Кажется, малыш из сериала «Мандалорец» по-настоящему покорил землян.