📜 ⬆️ ⬇️

Creating custom UIActivity for publishing photos and text on the social network VKontakte

While working on the next version of the application, the task arose of making the publication of photos on the social network VKontakte through the standard UIActivityViewController controller.

image

A web search gave the following results:
  1. No finished implementation found
  2. There is an official sdk VKontakte : contains authorization mechanisms, work with pictures, but does not have a ready-made class for loading via UIActivityViewController
  3. Apple documentation for creating custom UIActivity



Preparing to use VK SDK


Before you start working with the VK SDK, you need to create a Standalone application on the application creation page . Save the application ID and fill in the "App Bundle for iOS".
To set up authorization through VK App, you need to configure the URL protocol of the application:

')

Work with SDK


You must initialize the SDK when you start the application method
[VKSdk initialize: delegate andAppId: APP_ID];

For authorization, you can use the method:
[VKSdk authorize: scope];

If successful, the delegate will be called
- (void) vkSdkDidReceiveNewToken: (VKAccessToken *) newToken;

In case of an error (for example, the user denied authorization)
- (void) vkSdkUserDeniedAccess: (VKError *) authorizationError;


UIActivity for VK


Following the Apple documentation, we create a UIActivity inheritor:

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

The auxiliary controller parent is needed for captcha input, output of messages, etc.

Next, override the methods for displaying the UIActivity element (type, name and icon)
 - (NSString *)activityType { return @"VKActivityTypeVKontakte"; } - (NSString *)activityTitle { return @""; } - (UIImage *)activityImage { return [UIImage imageNamed:@"vk_activity"]; } 


Check if our class supports sharing of activityItems passed to it:
 - (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; } 


Remember the activity supported by us:
 - (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; } } } 


When choosing our UIActivity directly, we check whether the user is authorized:
 - (void)performActivity{ [VKSdk initializeWithDelegate:self andAppId:@"3974615"]; if ([VKSdk wakeUpSession]) { [self postToWall]; } else{ [VKSdk authorize:@[VK_PER_WALL, VK_PER_PHOTOS]]; } } 


With successful authorization publish the post.
 -(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]; }]; } 


Moreover, if the post contains a picture, then pre-upload it to the server.
 - (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]; }]; } 


Example of publishing a photo using VKontakteActivity:
  NSArray *items = @[[UIImage imageNamed:@"example.jpg"], @"Example" , [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]; 


The source code of the project can be downloaded here .

Source: https://habr.com/ru/post/214637/


All Articles