VKontakte iOS SDK

Good evening!

It all started with the fact that a more or less convenient tool was needed to work with the API of the social network VKontakte for iOS. However, Google quickly upset me with the search results:

Everything seems to be fine, the most important thing is, but the use does not cause pleasant sensations.

Under the cut, I’ll tell you how the new version of VKontakte iOS SDK works, how it all began and where it came to.


Predesign


It all started with the fact that at work they got the task to connect social networks to the application. We wanted the user to not notice any difference when interacting with different social networks (posting photos to the wall, sending messages, uploading photos, etc.).
It was decided to look for ready-made solutions that would contain several social networks like VKontakte, Odnoklassniki, Twitter and Facebook, but could not find anything. Using ready-made solutions separately did not produce the desired results, so we decided to write our bikes, after having studied Facebook iOS SDK, MGTwitterEngine and several other notable libraries.

As a result, we got ASASocialServices (GitHub).
The project turned out to be easy to use and install, more attention was paid to working with Twitter and Vkontakte, it was decided not to concentrate on Facebook.

In ASASocialServices, work with three social networks (hereinafter we will talk about only two) was carried out according to a single principle: the programmer creates a UIWebView, positions it and displays it, then starts the authorization process of the application user and, depending on the decision made by the user, one of three blocks is called -handlers (success, error, cancel).

Viewed in context, ViewController.h looks something like this:
#import <UIKit/UIKit.h>#import "ASASocialServices.h"@interfaceViewController : UIViewController@propertyUIWebView *webView;
@property ASATwitterCommunicator *tw;
@end


ViewController.m
#import "ViewController.h"NSString *const kTWITTER_CONSUMER_KEY = @"v8146mdwpo05uEroMnhozg";
NSString *const kTWITTER_CONSUMER_SECRET = @"5AFkvjCKxqGBRId2fpSQFLClJLKtGcPGS1DzK7o";
@implementationViewController
- (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


It was enough to replace ASATwitterCommunicator with ASAVkontakteCommunicator or ASAFacebookCommunicator to connect and start working with another social network.
In the last block - success, the user account of the corresponding network was transferred (access token, user ID, expiration of the access token, etc.).

Further requests on behalf of the current user could be made in this way:
[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);
                              }];


Here's what Twitter status updates look like:
[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);
                              }];


Everything would be fine, but in the course of use, we realized that leaving the token to the programmer, the subsequent loading was not quite right because our main goal was to simplify the library so much that we did not have to think about trifles like this (the library on this stage died and it was necessary to deal with its development / support alone, as with all subsequent developments).

Minuses:
  • The programmer needed to remember that the access token can be saved and used in subsequent requests, rather than hanging requests in a success block
  • Leaving the programmer to configure and work with UIWebView was also a mistake
  • The library seemed too complicated and incomprehensible, most did not want to think about whether to use POST or GET for requests


VKontakte iOS SDK v1.0


With ASASocialServices, I no longer wanted to mess around, so I decided that I would start writing SDK for VKontakte in my free time. I sketched a diagram of the interaction of classes on a piece of paper, “hung” over it for two days, in the end I decided that it looks like the first version - I started implementation.

I love Ruby and I like Rails and, for some reason, it always and still seems that it was they who, to some extent, influenced the look of the Vkontakte iOS SDK.

The user is associated with such objects as:
  • Groups
  • Wall
  • Friends
  • Audio albums
  • Video albums
  • Photo albums
  • Posts
  • Documents
  • td


Each object has a list of actions that the user can carry out on his behalf:
  • Create photo album
  • Join the group
  • Set / Change Status
  • Get a list of friends who are now online
  • etc


Here is how the above actions will look in VKontakte iOS SDK v1.0:

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

image

Join the group:
    VKUser *me = [VKUser currentUser];
    [[me groups] joinGroupID:100500];


Set Status:
    VKUser *me = [VKUser currentUser];
    [[me status] setStatus:@"Привет, Хабр!"];


Get a list of friends who are now online:
id result = [[[VKUser currentUser] friends] online];


Where to begin?

Suppose that you have already added the Vkontakte IOS SDK v1.0 to your project and do not know what to do next with this.

We will work with the VKConnector class, which will allow us to receive + save + use the received access token once, and at the right time it will notify us that it is necessary to update the token and will call the corresponding delegate method, which may or may not follow VKConnectorProtocol.

Here's what the simplest connection method in ASAAppDelegate.m will look like:
////  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"staticNSString *const kVKAppID = @"3541027";
staticNSString *const kVKPermissionsArray = @"photos,friends,wall,audio,video,docs,notes,pages,status,groups,messages";
@implementationASAAppDelegate
- (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];
    returnYES;
}
- (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


After starting up, the user gets about such a modal window (KGModal was used) for authorizing the application:
image

If you have questions or you don’t know what this method is for (what it is responsible for), then refer to the documentation. The documentation is generated using AppleDoc and as a whole looks like this:
image

VKConnectorProtocol:
image

XCode will help with this:
image

In conclusion


The article, it seems to me, turned out to be quite long, so I will stop here for now, although unfortunately I didn’t mention much of what I planned (downloading files, updating the token, error handling, etc.)

I want to note that the project is actively developing and supported. The current status of the project is “Ready”, so in v1.0 only errors will be fixed and minor adjustments will be made. All global changes are migrated to v2.0.

You can find the most current version at this link: GitHub ( https://github.com/AndrewShmig/Vkontakte-iOS-SDK )

Some information on the Vkontakte iOS SDK v2.0 can be found here: GitHub ( https://github.com /AndrewShmig/Vkontakte-iOS-SDK-v2.0/issues?labels=Future+features&state=open )

Thank you for your attention.

Also popular now: