1
1
mirror of https://github.com/VKCOM/vk-ios-sdk.git synced 2024-11-04 13:51:42 +03:00

Make wakeUpSession asyncronious

This commit is contained in:
Roman Truba 2015-10-29 21:37:17 +03:00
parent 64cdf28437
commit c03eb3ab5e
9 changed files with 137 additions and 93 deletions

View File

@ -35,10 +35,13 @@ static NSArray * SCOPE = nil;
[super viewDidLoad];
[[VKSdk initializeWithAppId:@"3974615"] registerDelegate:self];
[[VKSdk instance] setUiDelegate:self];
if ([VKSdk wakeUpSession])
{
[self startWorking];
}
[VKSdk wakeUpSession:SCOPE completeBlock:^(VKAuthorizationState state, NSError *error) {
if (state == VKAuthorizationAuthorized) {
[self startWorking];
} else if (error) {
[[[UIAlertView alloc] initWithTitle:nil message:[error description] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil] show];
}
}];
}
- (void)startWorking {
[self performSegueWithIdentifier:NEXT_CONTROLLER_SEGUE_ID sender:self];
@ -80,12 +83,13 @@ static NSArray * SCOPE = nil;
}
}
-(void)vkSdkUserAuthorizationFailed:(VKError *)result {
[[[UIAlertView alloc] initWithTitle:nil message:@"Access denied" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil] show];
[self.navigationController popToRootViewControllerAnimated:YES];
}
- (void)vkSdkShouldPresentViewController:(UIViewController *)controller {
[self.navigationController.topViewController presentViewController:controller animated:YES completion:nil];
}
-(void)vkSdkUserAuthorizationFailed:(VKError *)result {
[[[UIAlertView alloc] initWithTitle:nil message:@"Access denied" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil] show];
}
@end

View File

@ -81,7 +81,8 @@ Class for execution API-requests
@property(nonatomic, readonly) VKRequestTiming *requestTiming;
/// Return YES if current request was started
@property(nonatomic, readonly) BOOL isExecuting;
/// Return YES if current request was started
@property(nonatomic, copy) NSArray *preventThisErrorsHandling;
///-------------------------------
/// @name Preparing requests

View File

@ -477,11 +477,14 @@ void vksdk_dispatch_on_main_queue_now(void(^block)(void)) {
- (BOOL)processCommonError:(VKError *)error {
if (error.errorCode == VK_API_ERROR) {
error.apiError.request = self;
if ([self.preventThisErrorsHandling containsObject:@(error.apiError.errorCode)]) {
return NO;
}
if (error.apiError.errorCode == 5) {
vksdk_dispatch_on_main_queue_now(^{
[error.apiError notiftAuthorizationFailed];
});
return YES;
return NO;
}
if (error.apiError.errorCode == 6) {
//Too many requests per second

View File

@ -25,5 +25,6 @@
@interface VKAuthorizationResult : VKObject
@property (nonatomic, strong) VKAccessToken *token;
@property (nonatomic, strong) VKError *error;
@property (nonatomic, strong) VKUser *user;
@property (nonatomic, strong) NSError *error;
@end

View File

@ -41,4 +41,4 @@ extern NSString *const VK_PER_OFFLINE;
extern NSString *const VK_PER_NOHTTPS;
extern NSString *const VK_PER_EMAIL;
extern NSArray *VKParseVkPermissionsFromInteger(int permissionsValue);
extern NSArray *VKParseVkPermissionsFromInteger(NSInteger permissionsValue);

View File

@ -41,7 +41,7 @@ NSString *const VK_PER_OFFLINE = @"offline";
NSString *const VK_PER_NOHTTPS = @"nohttps";
NSString *const VK_PER_EMAIL = @"email";
NSArray *VKParseVkPermissionsFromInteger(int permissionsValue) {
NSArray *VKParseVkPermissionsFromInteger(NSInteger permissionsValue) {
NSMutableArray *res = [NSMutableArray new];
if (permissionsValue & 1) [res addObject:VK_PER_NOTIFY];
if (permissionsValue & 2) [res addObject:VK_PER_FRIENDS];

View File

@ -46,6 +46,17 @@ typedef NS_OPTIONS(NSUInteger, VKAuthorizationOptions) {
VKAuthorizationOptionsDisableSafariController = 1 << 1,
};
typedef NS_ENUM(NSUInteger, VKAuthorizationState) {
VKAuthorizationUnknown, // Authorization state unknown, probably something went wrong
VKAuthorizationInitialized, // SDK initialized and ready to authorize
VKAuthorizationPending, // Authorization state pending, probably we're trying to load auth information
VKAuthorizationExternal, // Started external authorization process
VKAuthorizationSafariInApp, // Started in app authorization process, using SafariViewController
VKAuthorizationWebview, // Started in app authorization process, using webview
VKAuthorizationAuthorized, // User authorized
VKAuthorizationError, // An error occured, try to wake up session later
};
/**
SDK events delegate protocol.
You should implement it, typically as main view controller or as application delegate.
@ -200,20 +211,14 @@ Checks passed URL for access token
/**
* Checks if somebody logged in with SDK
*/
Checks if somebody logged in with SDK (call after wakeUpSession)
*/
+ (BOOL)isLoggedIn;
#warning Make async
/**
Make try to read token from defaults and start session again.
This method is trying to retrieve token from storage, and check application still permitted to use user access token
*/
+ (BOOL)wakeUpSession;
/**
Try to read token from defaults, then check for required permissions.
*/
+ (BOOL)wakeUpSession:(NSArray *)permissions;
+ (void)wakeUpSession:(NSArray *)permissions completeBlock:(void(^)(VKAuthorizationState, NSError *)) wakeUpBlock;
/**
Forces logout using OAuth (with VKAuthorizeController). Removes all cookies for *.vk.com.
@ -230,7 +235,7 @@ Has no effect for logout in VK app
Check existing permissions
@param permissions array of permissions you want to check
*/
+ (BOOL)hasPermissions:(NSArray *)permissions;
- (BOOL)hasPermissions:(NSArray *)permissions;
/**
Enables or disables scheduling for requests

View File

@ -42,14 +42,6 @@
#import "VKRequestsScheduler.h"
#import "VKUser.h"
typedef NS_ENUM(NSUInteger, VKAuthorizationState) {
VKAuthorizationInitialized,
VKAuthorizationExternal,
VKAuthorizationSafariInApp,
VKAuthorizationWebview,
VKAuthorizationAuthorized
};
@interface VKWeakDelegate : NSProxy <VKSdkDelegate>
@property (nonatomic, weak) id<VKSdkDelegate> weakTarget;
@ -198,10 +190,10 @@ static NSString *VK_AUTHORIZE_URL_STRING = @"vkauthorize://authorize";
+ (void)setAccessToken:(VKAccessToken *)token {
[token saveTokenToDefaults:VK_ACCESS_TOKEN_DEFAULTS_KEY];
id oldToken = vkSdkInstance.accessToken;
if (!token && oldToken) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:VK_ACCESS_TOKEN_DEFAULTS_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
[VKAccessToken delete:VK_ACCESS_TOKEN_DEFAULTS_KEY];
}
vkSdkInstance.authState = token ? VKAuthorizationAuthorized : VKAuthorizationInitialized;
@ -223,30 +215,26 @@ static NSString *VK_AUTHORIZE_URL_STRING = @"vkauthorize://authorize";
void (^notifyAuthorization)(VKAccessToken*, VKError*) = ^ (VKAccessToken *token, VKError *error){
VKAuthorizationResult *res = [VKAuthorizationResult new];
res.error = error;
res.error = error ? [NSError errorWithVkError:error] : nil;
res.token = token;
if (token) {
[instance trackVisitor:^(VKUser *visitor, NSInteger per, VKError *error) {
[instance requestSdkState:^(VKUser *visitor, NSInteger per, NSError *error) {
if (visitor) {
NSMutableArray *permissions = [VKParseVkPermissionsFromInteger(per) mutableCopy];
if ([instance.permissions containsObject:VK_PER_OFFLINE]) {
[permissions addObject:VK_PER_OFFLINE];
}
if ([instance.permissions containsObject:VK_PER_NOHTTPS]) {
[permissions addObject:VK_PER_NOHTTPS];
}
VKAccessTokenMutable * mToken = (VKAccessTokenMutable *) [token mutableCopy];
instance.permissions = mToken.permissions = [permissions copy];
instance.permissions = mToken.permissions = [instance updatePermissions:per];
mToken.localUser = visitor;
[self setAccessToken:mToken];
res.user = visitor;
res.token = mToken;
} else if (error) {
res.error = error;
}
[instance notifyDelegate:@selector(vkSdkAccessAuthorizationFinishedWithResult:) obj:res];
} token:token];
} trackVisitor:YES token:token];
} else {
[instance notifyDelegate:@selector(vkSdkAccessAuthorizationFinishedWithResult:) obj:res];
}
};
@ -357,37 +345,81 @@ static NSString *VK_AUTHORIZE_URL_STRING = @"vkauthorize://authorize";
return false;
}
+ (BOOL)wakeUpSession {
+ (void)wakeUpSession:(NSArray *)permissions completeBlock:(void(^)(VKAuthorizationState, NSError *error)) wakeUpBlock {
VKAccessToken *token = [VKAccessToken savedToken:VK_ACCESS_TOKEN_DEFAULTS_KEY];
if (!token || token.isExpired)
return NO;
BOOL firstCall = vkSdkInstance.accessToken == nil;
vkSdkInstance.accessToken = token;
if (token && firstCall) {
#warning here
// [vkSdkInstance trackVisitor];
}
return YES;
}
+ (BOOL)wakeUpSession:(NSArray *)permissions {
BOOL result = [self wakeUpSession];
if (!result) return result;
return [self hasPermissions:permissions];
}
+ (BOOL)hasPermissions:(NSArray *)permissions {
for (NSString *p in permissions) {
BOOL exists = NO;
for (NSString *existingPemission in vkSdkInstance.accessToken.permissions) {
if ([existingPemission isEqualToString:p]) {
exists = YES;
break;
VKSdk *instance = [self instance];
if (!token || token.isExpired) {
[instance resetSdkState];
wakeUpBlock(instance.authState, nil);
} else {
BOOL firstCall = instance.accessToken == nil;
instance.accessToken = token;
instance.authState = VKAuthorizationPending;
[[VKSdk instance] requestSdkState:^(VKUser *visitor, NSInteger per, NSError *error) {
instance.authState = VKAuthorizationUnknown;
if (visitor) {
VKAccessTokenMutable * mToken = (VKAccessTokenMutable *) [token mutableCopy];
instance.permissions = mToken.permissions = [instance updatePermissions:per];
mToken.localUser = visitor;
instance.accessToken = mToken;
if ([instance hasPermissions:permissions]) {
instance.authState = VKAuthorizationAuthorized;
} else {
[instance resetSdkState];
}
} else if (error) {
instance.authState = VKAuthorizationError;
instance.accessToken = nil;
VKError *vkError = error.vkError;
if (vkError.errorCode == 5) {
//Remove token from storage
[self setAccessToken:nil];
instance.authState = VKAuthorizationInitialized;
}
}
}
if (!exists) return NO;
wakeUpBlock(instance.authState, error);
} trackVisitor:firstCall token:token];
}
return YES;
}
- (BOOL)hasPermissions:(NSArray *)permissions {
NSMutableArray *mutablePermissions = permissions ? [permissions mutableCopy] : [NSMutableArray new];
[mutablePermissions removeObject:VK_PER_EMAIL];
[mutablePermissions removeObject:VK_PER_NOHTTPS];
[mutablePermissions removeObject:VK_PER_OFFLINE];
BOOL allExisted = YES;
NSSet *tokenPermission = [NSSet setWithArray:self.accessToken.permissions];
for (NSString *p in mutablePermissions) {
if (![tokenPermission containsObject:p]) {
allExisted = NO;
break;
}
}
return allExisted;
}
-(NSArray *)updatePermissions:(NSInteger)appPermissions {
NSMutableArray *permissions = [VKParseVkPermissionsFromInteger(appPermissions) mutableCopy];
if ([self.permissions containsObject:VK_PER_OFFLINE]) {
[permissions addObject:VK_PER_OFFLINE];
}
if ([self.permissions containsObject:VK_PER_NOHTTPS]) {
[permissions addObject:VK_PER_NOHTTPS];
}
if ([self.permissions containsObject:VK_PER_EMAIL]) {
[permissions addObject:VK_PER_EMAIL];
}
return permissions;
}
+ (void)setSchedulerEnabled:(BOOL)enabled {
@ -399,7 +431,7 @@ static NSString *VK_AUTHORIZE_URL_STRING = @"vkauthorize://authorize";
- (instancetype)initUniqueInstance {
self = [super init];
self.authState = VKAuthorizationInitialized;
[self resetSdkState];
_sdkDelegates = [NSMutableArray new];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
return self;
@ -419,30 +451,26 @@ static NSString *VK_AUTHORIZE_URL_STRING = @"vkauthorize://authorize";
return _currentAppId;
}
- (void)trackVisitor:(void (^)(VKUser *visitor, NSInteger permissions, VKError *error))infoCallback token:(VKAccessToken*)token {
VKRequest *req = [VKRequest requestWithMethod:@"execute" andParameters:@{@"code" : @"return {stats:API.stats.trackVisitor(), permissions:API.account.getAppPermissions(), user:API.users.get({fields : \"photo_50,photo_100,photo_200\"})[0]};"}];
- (void)requestSdkState:(void (^)(VKUser *visitor, NSInteger permissions, NSError *error))infoCallback trackVisitor:(BOOL)trackVisitor token:(VKAccessToken*)token {
NSString *code = [NSString stringWithFormat:@"return {permissions:API.account.getAppPermissions(),user:API.users.get({fields : \"photo_50,photo_100,photo_200\"})[0],%1$@};", trackVisitor ? @"stats:API.stats.trackVisitor()," : @""];
VKRequest *req = [VKRequest requestWithMethod:@"execute" andParameters:@{@"code" : code}];
req.specialToken = token;
req.preventThisErrorsHandling = @[@5];
[req executeWithResultBlock:^(VKResponse *response) {
VKUser *user = [[VKUser alloc] initWithDictionary:response.json[@"user"]];
if (infoCallback) {
infoCallback(user, [VK_ENSURE_NUM(response.json[@"permissions"]) integerValue], nil);
}
} errorBlock:^(NSError *error) {
VKError *vkError = error.vkError;
if (vkError.errorCode == 5) {
[self setAccessToken:nil];
self.authState = VKAuthorizationInitialized;
[self notifyDelegate:@selector(vkSdkUserAuthorizationFailed:) obj:vkError];
}
if (infoCallback) {
infoCallback(nil, 0, vkError);
infoCallback(nil, 0, error);
}
}];
}
- (void) notifyUserAuthorizationFailed:(VKError*) error {
[self notifyDelegate:@selector(vkSdkUserAuthorizationFailed:) obj:error];
[[self class] setAccessToken:nil];
[self resetSdkState];
}

View File

@ -861,19 +861,21 @@ static const CGFloat kAttachmentsViewSize = 100.0f;
[super viewWillAppear:animated];
if (self.prepared) return;
VKShareDialogView *view = (VKShareDialogView *) self.view;
if ([VKSdk wakeUpSession:self.parent.requestedScope]) {
[view.notAuthorizedView removeFromSuperview];
view.textView.text = self.parent.text;
[self prepare];
} else {
[self setNotAuthorized];
}
[VKSdk wakeUpSession:self.parent.requestedScope completeBlock:^(VKAuthorizationState state, NSError *error) {
if (state == VKAuthorizationAuthorized) {
[view.notAuthorizedView removeFromSuperview];
view.textView.text = self.parent.text;
[self prepare];
} else {
[self setNotAuthorized];
}
}];
}
- (void) setNotAuthorized {
VKShareDialogView *view = (VKShareDialogView *) self.view;
[view addSubview:view.notAuthorizedView];
if ([VKSdk wakeUpSession]) {
if ([VKSdk accessToken]) {
view.notAuthorizedLabel.text = VKLocalizedString(@"UserHasNoRequiredPermissions");
}
[view layoutSubviews];