Vkontakte iOS SDK LV

More Power and Flexibility

View project onGitHub

How to install?

There are two ways to install Vkontakte iOS SDK: CocoaPods and manually.

Installing Vkontakte iOS SDK using CocoaPods is just simple as creating Podfile and running a command in terminal.

1. Create Podfile in your project's directory and enter following line:


pod 'Vkontakte-iOS-SDK-LV'

2. Now you can install the dependencies in your project:


$ pod install

Make sure to always open the Xcode workspace instead of the project file when building your project:


$ open App.xcworkspace

Now you can import your dependencies e.g.:


#import "VkontakteSDK.h"

To install manually you need to follow these steps:

1. Open your XCode project 2. Add Vkontakte iOS SDK to your project by draging&dropping Vkontakte-iOS-SDK-LV directory. 3. Build & Run

How to authorize user?

Lets assume we have created a new project (Single View Application) and added VK iOS SDK, as it was described in previous section. We should have something like this: After adding VK iOS SDK: Make your ViewController.h file look like:


	#import <UIKit/UIKit.h>
	#import "VkontakteSDK.h"

	@interface ViewController : UIViewController < VKConnectorDelegate >

	@end

and ViewController.m file:

	#import "ViewController.h"


	@implementation ViewController
	{
	    UIWebView *_webView;
	}

	- (void)viewDidLoad
	{
	    [super viewDidLoad];
		// Do any additional setup after loading the view, typically from a nib.

	    CGRect frame = [[UIScreen mainScreen] bounds];
	    _webView = [[UIWebView alloc] initWithFrame:frame];
	    [self.view addSubview:_webView];

	    self.webView.hidden = NO;

	    [[VKConnector sharedInstance] startWithAppID:@"3899649"
	                                      permissons:@[@"wall"]
	                                         webView:_webView
	                                        delegate:self];
	}

	#pragma mark - VKConnectorDelegate

	- (void)        VKConnector:(VKConnector *)connector
	accessTokenRenewalSucceeded:(VKAccessToken *)accessToken
	{
	    NSLog(@"OK: %@", accessToken);
	}

	- (void)     VKConnector:(VKConnector *)connector
	accessTokenRenewalFailed:(VKAccessToken *)accessToken
	{
	    NSLog(@"User denied to authorize app.");
	}

	@end     

Now, you can Build & Run your application. It should work just fine and after some time you should see this: After entering login and password and tapping "Log in" button you should receive access token information in console, it should look something like:

 2013-11-22 20:45:53.732 VKUserAuthorization[7591:80b] OK: {  	
	 "Creation time" = 1385138753;   
	 "Expiration time" = 1385225153;   
	  Permissions =     ( wall );
	  Token = 15f9365721d7d09099c2dca98407e92798c750b79cce7dac066aa803d633b4507cf93aeeaeb3aabfe45a3;
	  "User ID" = 58487857;
 }

from now on you can make requests from user's behalf.

How to work with several users?

There are four methods you should know how to use. 3 of these methods are VKUser's and one VKConnector's.

Lets start from basic example: your app should allow two or more users to log in, perform some action (like, repost, send private message etc) and log out. When first user logs in, a record is made in VKStorage and his access token is saved + UIWebView saves cookies (thats what exactly prevents user to enter his login and password each time he enters your app). To remove cookies which were stored by UIWebView after first user has logged in you should call VKConnector's clearCookies method. After removing these cookies second user can log in and use your app (while first user's access token is still stored in VKStorage and can be activated at any time). And so on and so forth.

VKUser class has 3 useful method. Lets talk about them. First one is "+ (NSArray *)localUsers" which will return a list of all user IDs, users who authorized your app. Currently there is no way to remove saved access tokens (it may change sometime, but there is no point in it: don't need - don't use).

Second one is "+ (BOOL)activateUserWithID:", which will return YES/NO if passed ID is valid and belongs to a valid (existing) user. You can easily switch between active users and perform requests from their behalf.

Third one is "+ (instancetype)currentUser" which returns currently active user. To understand this method lets describe two examples (these situations are also described in documentation, so its just a copy-paste):


// user A authorized
// user B authorized
// user C authorized
[VKUser currentUser] // random user will be activated - A or B or C

Second example:


// user A authorized
[VKUser currentUser] // user A becomes active user
// user B authorized, but A is still active
// user C authorized, but A is still active
// so on.

So its really important to understand when to call "+ (instancetype)currentUser" method.

How to make requests?

Please, before making requests see this table.

There are two ways of making a request:
1. Using VKRequestManager
2. Using VKRequest

Lets start from first one.

We need to create an instance of VKRequestManager class, and thats how we do it:


    VKRequestManager *rm = [[VKRequestManager alloc]
                                              initWithDelegate:self
                                                          user:[VKUser currentUser]];

Self must conform to VKRequestDelegate protocol. After creating VKRequestManager instance variable, we can perform predefined requests as showed here:

[rm info];	

or here:

	[rm friendsGet:@{
	            @"limit": @(10),
	            @"offset": @(10),
	            @"fields": @"nickname,email,photo_big"
	    }];

or here:

[rm friendsGet:nil];

and so on. To obtain a response (server respons) we need to add (implement) an additional method:

	- (void)VKRequest:(VKRequest *)request response:(id)response
	{
		// code here
	}

So your bare code (we are getting a list of friends of currently logged user) could look something like this:

	#import "ViewController.h"


	@implementation ViewController
	{
	    UIWebView *_webView;
	}

	- (void)viewDidLoad
	{
	    [super viewDidLoad];
		// Do any additional setup after loading the view, typically from a nib.

	    CGRect frame = [[UIScreen mainScreen] bounds];
	    _webView = [[UIWebView alloc] initWithFrame:frame];
	    [self.view addSubview:_webView];

	    [[VKConnector sharedInstance] startWithAppID:@"3899649"
	                                      permissons:@[@"wall"]
	                                         webView:_webView
	                                        delegate:self];
	}

	#pragma mark - VKConnectorDelegate

	- (void)        VKConnector:(VKConnector *)connector
	accessTokenRenewalSucceeded:(VKAccessToken *)accessToken
	{
	    NSLog(@"OK: %@", accessToken);

	    VKRequestManager *rm = [[VKRequestManager alloc]
	                                              initWithDelegate:self
	                                                          user:[VKUser currentUser]];

	    [rm friendsGet:nil];
	}

	- (void)VKRequest:(VKRequest *)request response:(id)response
	{
	    NSLog(@"response: %@", response);
	}

	- (void)     VKConnector:(VKConnector *)connector
	accessTokenRenewalFailed:(VKAccessToken *)accessToken
	{
	    NSLog(@"User denied to authorize app.");
	}

	- (void)   VKConnector:(VKConnector *)connector
	connectionErrorOccured:(NSError *)error
	{
	    NSLog(@"Connection error!");
	}

	@end

And after building and running your application you should receive something like this in console window:

	2013-11-28 20:43:48.720 VKUserAuthorization[33459:80b] +[VKConnector sharedInstance]
	2013-11-28 20:43:48.723 VKUserAuthorization[33459:80b] -[VKConnector startWithAppID:permissons:webView:delegate:]
	2013-11-28 20:43:48.874 VKUserAuthorization[33459:80b] -[VKConnector webView:shouldStartLoadWithRequest:navigationType:]
	2013-11-28 20:43:48.877 VKUserAuthorization[33459:80b] -[VKConnector webViewDidStartLoad:]
	2013-11-28 20:43:49.707 VKUserAuthorization[33459:80b] -[VKConnector webViewDidFinishLoad:]
	2013-11-28 20:43:49.707 VKUserAuthorization[33459:80b] -[VKConnector showVKModalViewForWebView:]
	2013-11-28 20:43:49.712 VKUserAuthorization[33459:80b] -[VKConnector webView:shouldStartLoadWithRequest:navigationType:]
	2013-11-28 20:43:49.713 VKUserAuthorization[33459:80b] -[VKConnector webViewDidStartLoad:]
	2013-11-28 20:43:50.331 VKUserAuthorization[33459:80b] -[VKConnector webViewDidFinishLoad:]
	2013-11-28 20:43:50.332 VKUserAuthorization[33459:80b] -[VKConnector showVKModalViewForWebView:]
	2013-11-28 20:44:09.832 VKUserAuthorization[33459:80b] -[VKConnector webView:shouldStartLoadWithRequest:navigationType:]
	2013-11-28 20:44:09.840 VKUserAuthorization[33459:80b] -[VKConnector webViewDidStartLoad:]
	2013-11-28 20:44:11.547 VKUserAuthorization[33459:80b] -[VKConnector webView:shouldStartLoadWithRequest:navigationType:]
	2013-11-28 20:44:12.467 VKUserAuthorization[33459:80b] -[VKConnector webView:shouldStartLoadWithRequest:navigationType:]
	2013-11-28 20:44:13.343 VKUserAuthorization[33459:80b] -[VKConnector webView:shouldStartLoadWithRequest:navigationType:]
	2013-11-28 20:44:13.389 VKUserAuthorization[33459:80b] -[VKConnector webViewDidFinishLoad:]
	2013-11-28 20:44:13.391 VKUserAuthorization[33459:80b] -[VKAccessToken initWithUserID:accessToken:liveTime:permissions:]
	2013-11-28 20:44:13.391 VKUserAuthorization[33459:80b] +[VKStorage sharedStorage]
	2013-11-28 20:44:13.391 VKUserAuthorization[33459:80b] -[VKStorage init]
	2013-11-28 20:44:13.392 VKUserAuthorization[33459:80b] -[VKStorage loadStorage]
	2013-11-28 20:44:13.392 VKUserAuthorization[33459:80b] -[VKStorage fullCacheStoragePath]
	2013-11-28 20:44:13.393 VKUserAuthorization[33459:80b] -[VKStorage createStorageItemForAccessToken:]
	2013-11-28 20:44:13.393 VKUserAuthorization[33459:80b] -[VKStorage fullCacheStoragePath]
	2013-11-28 20:44:13.393 VKUserAuthorization[33459:80b] -[VKStorageItem initWithAccessToken:mainCacheStoragePath:]
	2013-11-28 20:44:13.394 VKUserAuthorization[33459:80b] -[VKAccessToken copyWithZone:]
	2013-11-28 20:44:13.394 VKUserAuthorization[33459:80b] -[VKAccessToken init]
	2013-11-28 20:44:13.394 VKUserAuthorization[33459:80b] -[VKAccessToken initWithUserID:accessToken:liveTime:permissions:]
	2013-11-28 20:44:13.394 VKUserAuthorization[33459:80b] -[VKCache initWithCacheDirectory:]
	2013-11-28 20:44:13.395 VKUserAuthorization[33459:80b] -[VKCache createDirectoryIfNotExists:]
	2013-11-28 20:44:13.395 VKUserAuthorization[33459:80b] +[VKStorage sharedStorage]
	2013-11-28 20:44:13.395 VKUserAuthorization[33459:80b] -[VKStorage storeItem:]
	2013-11-28 20:44:13.396 VKUserAuthorization[33459:80b] -[VKStorage saveStorage]
	2013-11-28 20:44:13.396 VKUserAuthorization[33459:80b] -[VKAccessToken encodeWithCoder:]
	2013-11-28 20:44:13.396 VKUserAuthorization[33459:80b] -[VKAccessToken description]
	2013-11-28 20:44:13.397 VKUserAuthorization[33459:80b] OK: {
	    "Creation time" = 1385657053;
	    "Expiration time" = 1385743453;
	    Permissions =     (
	        wall
	    );
	    Token = fe3cbb2d27a3acf0be326bfe5557bdc8bd1d94d7bb723454c9a94ef83e19254f1ed80766c281ac0059d1f;
	    "User ID" = 58487857;
	}
	2013-11-28 20:44:13.398 VKUserAuthorization[33459:80b] +[VKUser currentUser]
	2013-11-28 20:44:13.398 VKUserAuthorization[33459:80b] +[VKStorage sharedStorage]
	2013-11-28 20:44:13.399 VKUserAuthorization[33459:80b] -[VKStorage isEmpty]
	2013-11-28 20:44:13.399 VKUserAuthorization[33459:80b] +[VKStorage sharedStorage]
	2013-11-28 20:44:13.399 VKUserAuthorization[33459:80b] -[VKStorage storageItems]
	2013-11-28 20:44:13.399 VKUserAuthorization[33459:80b] -[VKUser initWithStorageItem:]
	2013-11-28 20:44:13.401 VKUserAuthorization[33459:80b] -[VKUser accessToken]
	2013-11-28 20:44:13.401 VKUserAuthorization[33459:80b] +[VKRequest requestMethod:options:delegate:]
	2013-11-28 20:44:13.402 VKUserAuthorization[33459:80b] -[VKRequest initWithMethod:options:]
	2013-11-28 20:44:13.402 VKUserAuthorization[33459:80b] -[VKRequest initWithRequest:]
	2013-11-28 20:44:13.402 VKUserAuthorization[33459:80b] -[VKRequest start]
	2013-11-28 20:44:13.402 VKUserAuthorization[33459:80b] +[VKUser currentUser]
	2013-11-28 20:44:13.403 VKUserAuthorization[33459:80b] +[VKStorage sharedStorage]
	2013-11-28 20:44:13.403 VKUserAuthorization[33459:80b] -[VKUser accessToken]
	2013-11-28 20:44:13.403 VKUserAuthorization[33459:80b] -[VKStorage storageItemForUserID:]
	2013-11-28 20:44:13.404 VKUserAuthorization[33459:80b] -[VKUser accessToken]
	2013-11-28 20:44:13.404 VKUserAuthorization[33459:80b] +[VKStorage sharedStorage]
	2013-11-28 20:44:13.404 VKUserAuthorization[33459:80b] -[VKStorage storageItemForUserID:]
	2013-11-28 20:44:13.405 VKUserAuthorization[33459:80b] -[VKRequest removeAccessTokenFromURL:]
	2013-11-28 20:44:13.406 VKUserAuthorization[33459:80b] -[VKCache cacheForURL:offlineMode:]
	2013-11-28 20:44:13.406 VKUserAuthorization[33459:80b] -[VKConnector showVKModalViewForWebView:]
	2013-11-28 20:44:14.327 VKUserAuthorization[33459:80b] -[VKRequest connection:didReceiveResponse:]
	2013-11-28 20:44:14.328 VKUserAuthorization[33459:80b] -[VKRequest connection:didReceiveData:]
	2013-11-28 20:44:14.328 VKUserAuthorization[33459:80b] -[VKRequest connectionDidFinishLoading:]
	2013-11-28 20:44:14.329 VKUserAuthorization[33459:80b] +[VKUser currentUser]
	2013-11-28 20:44:14.329 VKUserAuthorization[33459:80b] +[VKStorage sharedStorage]
	2013-11-28 20:44:14.330 VKUserAuthorization[33459:80b] -[VKUser accessToken]
	2013-11-28 20:44:14.330 VKUserAuthorization[33459:80b] -[VKStorage storageItemForUserID:]
	2013-11-28 20:44:14.330 VKUserAuthorization[33459:80b] -[VKUser accessToken]
	2013-11-28 20:44:14.330 VKUserAuthorization[33459:80b] +[VKStorage sharedStorage]
	2013-11-28 20:44:14.331 VKUserAuthorization[33459:80b] -[VKStorage storageItemForUserID:]
	2013-11-28 20:44:14.331 VKUserAuthorization[33459:80b] -[VKRequest removeAccessTokenFromURL:]
	2013-11-28 20:44:14.331 VKUserAuthorization[33459:80b] -[VKCache addCache:forURL:liveTime:]
	2013-11-28 20:44:14.332 VKUserAuthorization[33459:80b] response: {
	    response =     (
	        322848,
	        376212,
	        507272,
	        2327520,
	        2548347,
	        2624137,
	        2750905,
	        2856088,
	        3164123,
	        3206773,
	        4010380,
	        4297107,
	        5084302,
	        7081866,
	        7577135,
	        8243206,
	        8920508,
	        9178255,
	        10031739,
	        10838645,
	        10911476,
	        11778800,
	        11947792,
	        15149272,
	        15573132,
	        15921003,
	        16792312,
	        16851968,
	        17184966,
	        17782253,
	        20532993,
	        21771478,
	        22173558,
	        22785589,
	        23609851,
	        23784153,
	        24143236,
	        24475069,
	        25430545,
	        27118751,
	        31346972,
	        31629215,
	        37274850,
	        48453399,
	        49281108,
	        50390804,
	        52147797,
	        56670089,
	        61571061,
	        63189055,
	        64326042,
	        67370461,
	        67751325,
	        67880040,
	        68315214,
	        69291907,
	        69506454,
	        69737976,
	        72789367,
	        75139819,
	        78713631,
	        81204560,
	        85885949,
	        91488429,
	        97016184,
	        97424793,
	        99572341,
	        100102831,
	        102780044,
	        104404576,
	        104785356,
	        121626998,
	        129106536,
	        129632702,
	        131750913,
	        132658283,
	        136505118,
	        136520130,
	        137183887,
	        139039565,
	        146236822,
	        146504369,
	        151785025,
	        154571733,
	        166317564,
	        176343194,
	        177420079,
	        186012269,
	        193168637,
	        193806348,
	        194385523,
	        198632468,
	        215372017,
	        227357584
	    );
	}

You can also set some request properties to have more control over your requests. For example you can set "startAllRequestsImmediately" property to NO and start a request when user presses a button or makes another action. Simple example:

	- (void)        VKConnector:(VKConnector *)connector
	accessTokenRenewalSucceeded:(VKAccessToken *)accessToken
	{
	    NSLog(@"OK: %@", accessToken);

	    VKRequestManager *rm = [[VKRequestManager alloc]
	                                              initWithDelegate:self
	                                                          user:[VKUser currentUser]];

	    rm.startAllRequestsImmediately = NO;

	    VKRequest *friends = [rm friendsGet:nil];
	    [friends start];
	}

If you need to control what requests should be cached more aggressivly you can write something like this:

	- (void)        VKConnector:(VKConnector *)connector
	accessTokenRenewalSucceeded:(VKAccessToken *)accessToken
	{
	    NSLog(@"OK: %@", accessToken);

	    VKRequestManager *rm = [[VKRequestManager alloc]
	                                              initWithDelegate:self
	                                                          user:[VKUser currentUser]];

	    rm.startAllRequestsImmediately = NO;

	    VKRequest *friends = [rm friendsGet:nil];
    
	    friends.cacheLiveTime = VKCacheLiveTimeOneDay;
	    friends.signature = @"blah-blah-blah";
	    friends.offlineMode = YES;

	    [friends start];
	}

In code above I have demonstrated that its also possible to set a signature and offlineMode.

Important

Please, note that BEFORE actual request is made, SDK looks for early cached data for this request and if it finds it then this data is returned, and just AFTER that the request is performed to UPDATE cached data (if any error occures during update proccess then data is not updated, it remains still). Note also, that this only works if you DON'T use VKCacheLiveTimeNever option for cacheLiveTime property.

Lets now move on to our second method of making requests. Here is an example of using a VKRequest class:


	- (void)        VKConnector:(VKConnector *)connector
	accessTokenRenewalSucceeded:(VKAccessToken *)accessToken
	{
	    NSLog(@"OK: %@", accessToken);

	    VKRequest *request = [[VKRequest alloc]
	            initWithMethod:@"users.get"
	                   options:@{
	                           @"access_token": [VKUser currentUser].accessToken.token
	                   }];

	    request.delegate = self;
	    request.signature = @"blah-blah-blah";
	    request.cacheLiveTime = VKCacheLiveTimeNever;

	    [request start];
	}

After running your app you should receive something like this:

	2013-11-28 21:10:35.987 VKUserAuthorization[33910:80b] +[VKConnector sharedInstance]
	2013-11-28 21:10:36.005 VKUserAuthorization[33910:80b] -[VKConnector startWithAppID:permissons:webView:delegate:]
	2013-11-28 21:10:36.312 VKUserAuthorization[33910:80b] -[VKConnector webView:shouldStartLoadWithRequest:navigationType:]
	2013-11-28 21:10:36.314 VKUserAuthorization[33910:80b] -[VKConnector webViewDidStartLoad:]
	2013-11-28 21:10:36.849 VKUserAuthorization[33910:80b] -[VKConnector webView:shouldStartLoadWithRequest:navigationType:]
	2013-11-28 21:10:37.329 VKUserAuthorization[33910:80b] -[VKConnector webView:shouldStartLoadWithRequest:navigationType:]
	2013-11-28 21:10:38.192 VKUserAuthorization[33910:80b] -[VKConnector webViewDidFinishLoad:]
	2013-11-28 21:10:38.193 VKUserAuthorization[33910:80b] -[VKAccessToken initWithUserID:accessToken:liveTime:permissions:]
	2013-11-28 21:10:38.193 VKUserAuthorization[33910:80b] +[VKStorage sharedStorage]
	2013-11-28 21:10:38.194 VKUserAuthorization[33910:80b] -[VKStorage init]
	2013-11-28 21:10:38.194 VKUserAuthorization[33910:80b] -[VKStorage loadStorage]
	2013-11-28 21:10:38.194 VKUserAuthorization[33910:80b] -[VKAccessToken initWithCoder:]
	2013-11-28 21:10:38.195 VKUserAuthorization[33910:80b] -[VKStorage fullCacheStoragePath]
	2013-11-28 21:10:38.195 VKUserAuthorization[33910:80b] -[VKStorageItem initWithAccessToken:mainCacheStoragePath:]
	2013-11-28 21:10:38.195 VKUserAuthorization[33910:80b] -[VKAccessToken copyWithZone:]
	2013-11-28 21:10:38.196 VKUserAuthorization[33910:80b] -[VKAccessToken init]
	2013-11-28 21:10:38.196 VKUserAuthorization[33910:80b] -[VKAccessToken initWithUserID:accessToken:liveTime:permissions:]
	2013-11-28 21:10:38.196 VKUserAuthorization[33910:80b] -[VKCache initWithCacheDirectory:]
	2013-11-28 21:10:38.197 VKUserAuthorization[33910:80b] -[VKCache createDirectoryIfNotExists:]
	2013-11-28 21:10:38.197 VKUserAuthorization[33910:80b] -[VKStorage fullCacheStoragePath]
	2013-11-28 21:10:38.197 VKUserAuthorization[33910:80b] -[VKStorage createStorageItemForAccessToken:]
	2013-11-28 21:10:38.198 VKUserAuthorization[33910:80b] -[VKStorage fullCacheStoragePath]
	2013-11-28 21:10:38.198 VKUserAuthorization[33910:80b] -[VKStorageItem initWithAccessToken:mainCacheStoragePath:]
	2013-11-28 21:10:38.198 VKUserAuthorization[33910:80b] -[VKAccessToken copyWithZone:]
	2013-11-28 21:10:38.199 VKUserAuthorization[33910:80b] -[VKAccessToken init]
	2013-11-28 21:10:38.199 VKUserAuthorization[33910:80b] -[VKAccessToken initWithUserID:accessToken:liveTime:permissions:]
	2013-11-28 21:10:38.199 VKUserAuthorization[33910:80b] -[VKCache initWithCacheDirectory:]
	2013-11-28 21:10:38.199 VKUserAuthorization[33910:80b] -[VKCache createDirectoryIfNotExists:]
	2013-11-28 21:10:38.199 VKUserAuthorization[33910:80b] +[VKStorage sharedStorage]
	2013-11-28 21:10:38.200 VKUserAuthorization[33910:80b] -[VKStorage storeItem:]
	2013-11-28 21:10:38.200 VKUserAuthorization[33910:80b] -[VKStorage saveStorage]
	2013-11-28 21:10:38.200 VKUserAuthorization[33910:80b] -[VKAccessToken encodeWithCoder:]
	2013-11-28 21:10:38.201 VKUserAuthorization[33910:80b] -[VKAccessToken description]
	2013-11-28 21:10:38.201 VKUserAuthorization[33910:80b] OK: {
	    "Creation time" = 1385658638;
	    "Expiration time" = 1385745038;
	    Permissions =     (
	        wall
	    );
	    Token = 0ac7158dd3bdc65d4b003aa48b613ea900751523a74f4ba5f66be00bb584e043a9a1f4bf511e495ffd766;
	    "User ID" = 58487857;
	}
	2013-11-28 21:10:38.201 VKUserAuthorization[33910:80b] +[VKUser currentUser]
	2013-11-28 21:10:38.202 VKUserAuthorization[33910:80b] +[VKStorage sharedStorage]
	2013-11-28 21:10:38.202 VKUserAuthorization[33910:80b] -[VKStorage isEmpty]
	2013-11-28 21:10:38.202 VKUserAuthorization[33910:80b] +[VKStorage sharedStorage]
	2013-11-28 21:10:38.202 VKUserAuthorization[33910:80b] -[VKStorage storageItems]
	2013-11-28 21:10:38.202 VKUserAuthorization[33910:80b] -[VKUser initWithStorageItem:]
	2013-11-28 21:10:38.203 VKUserAuthorization[33910:80b] -[VKUser accessToken]
	2013-11-28 21:10:38.203 VKUserAuthorization[33910:80b] -[VKRequest initWithMethod:options:]
	2013-11-28 21:10:38.203 VKUserAuthorization[33910:80b] -[VKRequest initWithRequest:]
	2013-11-28 21:10:38.203 VKUserAuthorization[33910:80b] -[VKRequest start]
	2013-11-28 21:10:38.204 VKUserAuthorization[33910:80b] +[VKUser currentUser]
	2013-11-28 21:10:38.204 VKUserAuthorization[33910:80b] +[VKStorage sharedStorage]
	2013-11-28 21:10:38.204 VKUserAuthorization[33910:80b] -[VKUser accessToken]
	2013-11-28 21:10:38.204 VKUserAuthorization[33910:80b] -[VKStorage storageItemForUserID:]
	2013-11-28 21:10:38.205 VKUserAuthorization[33910:80b] -[VKUser accessToken]
	2013-11-28 21:10:38.205 VKUserAuthorization[33910:80b] +[VKStorage sharedStorage]
	2013-11-28 21:10:38.205 VKUserAuthorization[33910:80b] -[VKStorage storageItemForUserID:]
	2013-11-28 21:10:38.205 VKUserAuthorization[33910:80b] -[VKRequest removeAccessTokenFromURL:]
	2013-11-28 21:10:38.206 VKUserAuthorization[33910:80b] -[VKCache cacheForURL:offlineMode:]
	2013-11-28 21:10:38.206 VKUserAuthorization[33910:80b] -[VKConnector showVKModalViewForWebView:]
	2013-11-28 21:10:38.521 VKUserAuthorization[33910:80b] -[VKRequest connection:didReceiveResponse:]
	2013-11-28 21:10:38.521 VKUserAuthorization[33910:80b] -[VKRequest connection:didReceiveData:]
	2013-11-28 21:10:38.522 VKUserAuthorization[33910:80b] -[VKRequest connectionDidFinishLoading:]
	2013-11-28 21:10:38.522 VKUserAuthorization[33910:80b] response: {
	    response =     (
	                {
	            "first_name" = "\U0410\U043d\U0434\U0440\U0435\U0439";
	            "last_name" = "\U0428\U043c\U0438\U0433";
	            uid = 58487857;
	        }
	    );
	}

To learn more about VKRequests read documentation or check impelementation file.

How to cache data?

As we aready know all caching is done automatically, but you can manage it using three classes: VKStorage, VKStorageItem, VKCache. In this section we will not describe how to set cache lifetime or how disallow caching, we will show an example of adding an audio/video/document file to cache.


    NSUInteger currentUserID = [VKUser currentUser].accessToken.userID;
       VKStorageItem *item = [[VKStorage sharedStorage]
                                         storageItemForUserID:currentUserID];

       NSString *mp3Link = @"https://mp3.vk.com/music/pop/j-lo.mp3";
       NSURL *mp3URL = [NSURL URLWithString:mp3Link];
       NSData *mp3Data = //mp3 data from request

       [item.cache addCache:mp3Data
                               forURL:mp3URL
                             liveTime:VKCachedDataLiveTimeOneMonth];

Cached file will live until the system deletes it (if cache data folder is deleted) or until you delete it by your own.

Thats it! Nothing complicated.

How to upload files?

Here is an example. Lets create a simple empty project. Thats how should AppDelegate.h file look like:


	#import "UIKit/UIKit.h"
	#import "VKConnector.h"
	#import "VKRequest.h"

	@class ASAViewController;


	@interface ASAAppDelegate : UIResponder < UIApplicationDelegate, VKConnectorDelegate, VKRequestDelegate >

	@property (strong, nonatomic) UIWindow *window;
	@property (strong, nonatomic) ASAViewController *viewController;

	@end

And here is AppDelegate.m file:

	#import "ASAAppDelegate.h"
	#import "ASAViewController.h"
	#import "VKUser.h"


	@implementation ASAAppDelegate

	- (BOOL)application:(UIApplication *)application
	        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
	{
	    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
	    // Override point for customization after application launch.
	    self.viewController = [[ASAViewController alloc] initWithNibName:@"ASAViewController" bundle:nil];
	    self.window.rootViewController = self.viewController;
	    [self.window makeKeyAndVisible];


	    CGRect frame = [[UIScreen mainScreen] bounds];
	    _webView = [[UIWebView alloc] initWithFrame:frame];
	    [self.view addSubview:_webView];
		
	//    CODE BEGIN
    [[VKConnector sharedInstance] startWithAppID:@"3899649"
                                      permissons:@[@"audio"]
                                         webView:_webView
                                        delegate:self];
	//    CODE END


	    return YES;
	}

	#pragma mark - VKConnectorDelegate

	- (void)        VKConnector:(VKConnector *)connector
	accessTokenRenewalSucceeded:(VKAccessToken *)accessToken
	{

		VKRequestManager *rm = [[VKRequestManager alloc] initWithUser:[VKUser currentUser] delegate:self];
		rm.startAllRequestsImmediatly = NO;


	    VKRequest *firstStep = [rm audioGetUploadServer:@{}];
	    firstStep.signature = @"firstStep";
	    firstStep.cacheLiveTime = VKCachedDataLiveTimeNever;


	    [firstStep start];
	}

	#pragma mark - VKRequestDelegate

	- (void)VKRequest:(VKRequest *)request
	         response:(id)response
	{
	    if([request.signature isEqualToString:@"firstStep"]){

	        NSString* uploadURL = response[@"response"][@"upload_url"];


	        NSString *audioPath = [[NSBundle mainBundle]
	                                         pathForResource:@"Crashdiet - Armagedon"
	                                                  ofType:@"mp3"];


	        VKRequest *secondStep = [VKRequest requestHTTPMethod:@"POST"
	                                                         URL:[NSURL URLWithString:uploadURL]
	                                                     headers:@{}
	                                                        body:nil
	                                                    delegate:self];
	        [secondStep appendAudioFile:[NSData dataWithContentsOfFile:audioPath]
	                               name:@"Crashdiet - Armagedon.mp3"
	                              field:@"file"];
	        secondStep.signature = @"secondStep";
	        secondStep.cacheLiveTime = VKCachedDataLiveTimeNever;


	        [secondStep start];
	    }


	    if([request.signature isEqualToString:@"secondStep"]){
	        VKRequest *thirdStep = [[VKUser currentUser]
	                                        audioSave:@{
	                                                @"server": response[@"server"],
	                                                @"hash": response[@"hash"],
	                                                @"audio": response[@"audio"]
	                                        }];

	        thirdStep.signature = @"thirdStep";
	        thirdStep.delegate = self;


	        thirdStep.cacheLiveTime = VKCachedDataLiveTimeNever;

	        [thirdStep start];
	    }

	    if ([request.signature isEqualToString:@"thirdStep"]) {
	        NSLog(@"Audio file was uploaded successful!");
	    }
	}

	- (void)VKRequest:(VKRequest *)request
	       totalBytes:(NSUInteger)totalBytes
	    uploadedBytes:(NSUInteger)uploadedBytes
	{
	    NSLog(@"%zu [%zu]", (unsigned long)totalBytes, (unsigned long)uploadedBytes);
	}

	@end
	
What we are doing here is:
1. Obtaining upload URL
2. Uploading our audio file
3. Saving audio file

There is also another example how to upload images. All examples can be found here (dont worry that the version of SDK is 2.7.5, there are not so many changes not to understand how to do things).