Создание кастомного UIActivity для публикации фото и текста в социальной сети ВКонтакте

от автора

Во время работы над очередной версией приложения возникла задача сделать публикацию фото в социальной сети ВКонтакте через стандартный контроллер UIActivityViewController.

image

Поиск в сети дал следующие результаты:

  1. Готовой реализации нет
  2. Есть официальное sdk ВКонтакте: содержит механизмы авторизации, работы с картинками, но не имеет готового класса для загрузки через UIActivityViewController
  3. Есть документация Apple для создания кастомного UIActivity

 

Подготовка к использованию VK SDK

Перед началом работы с VK SDK необходимо создать Standalone-приложение на странице создания приложения. Сохранить ID приложения и заполнить поле «App Bundle для iOS».
Для настройки авторизации через VK App, необходимо настроить URL-протокол приложения:

  • Откройте настройки проекта, выберите раздел «Info».
  • В секции «URL Types» нажмите на +.
  • Введите vk+APP_ID (например, vk1234567) в поля «Indentifier» и «URL Schemes».

 

Работа с SDK

Необходимо инициализировать SDK при запуске приложения методом

[VKSdk initialize:delegate andAppId:APP_ID];

Для авторизации можно использовать метод:

[VKSdk authorize:scope];

В случае успеха у делегата будет вызван метод

-(void) vkSdkDidReceiveNewToken:(VKAccessToken*) newToken;

В случае ошибки (например, пользователь запретил авторизацию)

-(void) vkSdkUserDeniedAccess:(VKError*) authorizationError;

 

UIActivity для ВКонтакте

Следуя документации Apple, создаём наследник UIActivity:

#import <UIKit/UIKit.h>   @interface VKontakteActivity : UIActivity   - (id)initWithParent:(UIViewController*)parent;   @end 

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

Далее переопределяем методы для отображения элемента UIActivity (тип, название и иконку)

- (NSString *)activityType {     return @"VKActivityTypeVKontakte"; }   - (NSString *)activityTitle {     return @"ВКонтакте"; }   - (UIImage *)activityImage {     return [UIImage imageNamed:@"vk_activity"]; } 

Проверяем поддерживает ли наш класс шаринг передаваемых ему activityItems:

- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems {     for (UIActivityItemProvider *item in activityItems) {         if ([item isKindOfClass:[UIImage class]]) {             return YES;         }         else if ([item isKindOfClass:[NSString class]])         {             return YES;         }     }     return NO; } 

Запоминаем  поддерживаемые нами activityItems:

- (void)prepareWithActivityItems:(NSArray *)activityItems {     for (id item in activityItems) {         if ([item isKindOfClass:[NSString class]]) {             self.string = item;         }         else if([item isKindOfClass:[UIImage class]]) {             self.image = item;         }         else if([item isKindOfClass:[NSURL class]]) {             self.URL = item;         }     } } 

Непосредственно при выборе нашего UIActivity проверяем авторизован ли пользователь:

- (void)performActivity{     [VKSdk initializeWithDelegate:self andAppId:@"3974615"];     if ([VKSdk wakeUpSession])     {         [self postToWall];     }     else{         [VKSdk authorize:@[VK_PER_WALL, VK_PER_PHOTOS]];     } }  

При успешной авторизации публикуем пост.

-(void)postToWall{     [self begin];     if (self.image) {         [self uploadPhoto];     }     else{         [self uploadText];     } }   //публикация текста на стене -(void)uploadText{ 	 [self postParameters:@{ VK_API_FRIENDS_ONLY : @(0),                             VK_API_OWNER_ID : [VKSdk getAccessToken].userId,                             VK_API_MESSAGE : self.string}]; }   //публикация поста на стене -(void)postParameters:(NSDictionary *)params{     VKRequest *post = [[VKApi wall] post:params];     [post executeWithResultBlock: ^(VKResponse *response) {         NSNumber * postId = response.json[@"post_id"];         [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://vk.com/wall%@_%@", [VKSdk getAccessToken].userId, postId]]];         [self end];     } errorBlock: ^(NSError *error) {         NSLog(@"Error: %@", error);         [self end];     }]; } 

При этом если пост содержит картинку, то предварительно загружаем её на сервер.

- (void)uploadPhoto {     NSString *userId = [VKSdk getAccessToken].userId;     //предварительная загрузка фото на сервер     VKRequest *request = [VKApi uploadWallPhotoRequest:self.image parameters:[VKImageParameters jpegImageWithQuality:1.f] userId:[userId integerValue] groupId:0]; 	[request executeWithResultBlock: ^(VKResponse *response) { 	    VKPhoto *photoInfo = [(VKPhotoArray*)response.parsedModel objectAtIndex:0]; 	    NSString *photoAttachment = [NSString stringWithFormat:@"photo%@_%@", photoInfo.owner_id, photoInfo.id];        	//публикация текста на стене 	[self postParameters:@{ VK_API_ATTACHMENTS : photoAttachment,                                 VK_API_FRIENDS_ONLY : @(0),                                 VK_API_OWNER_ID : userId,                                 VK_API_MESSAGE : [NSString stringWithFormat:@"%@ %@",self.string, [self.URL absoluteString]]}];     } errorBlock: ^(NSError *error) { 	    NSLog(@"Error: %@", error);         [self end]; 	}]; }  

Пример публикации фото с помощью VKontakteActivity:

  NSArray *items = @[[UIImage imageNamed:@"example.jpg"], @"Холодная война?" , [NSURL URLWithString:@"https://www.youtube.com/watch?v=S59fDUZIuKY"]];     VKontakteActivity *vkontakteActivity = [[VKontakteActivity alloc] initWithParent:self];          UIActivityViewController *activityViewController = [[UIActivityViewController alloc]                                                         initWithActivityItems:items                                                         applicationActivities:@[vkontakteActivity]];          [self presentViewController:activityViewController animated:YES completion:nil];  

Исходный код проекта можно скачать здесь.

ссылка на оригинал статьи http://habrahabr.ru/post/214637/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *