From c23b1e0e3810c14822ebbbf5f285abb92f356518 Mon Sep 17 00:00:00 2001 From: Giuseppe Nucifora Date: Wed, 3 Feb 2016 02:21:44 +0100 Subject: [PATCH] - Fix AccessToken Save, SharedInstance - Fix crash in removeObserver PNObject --- Example/PNObject/PNObjectAppDelegate.m | 18 ++-- Pod/Classes/PNClasses/PNAccessToken.h | 9 +- Pod/Classes/PNClasses/PNAccessToken.m | 93 +++++++++++++--- Pod/Classes/PNObject+PNObjectConnection.m | 126 +++++++++++----------- Pod/Classes/PNObject+Protected.m | 4 +- Pod/Classes/PNObject.h | 2 +- Pod/Classes/PNObject.m | 36 ++++--- Pod/Classes/PNObjectModel.m | 6 +- 8 files changed, 187 insertions(+), 107 deletions(-) diff --git a/Example/PNObject/PNObjectAppDelegate.m b/Example/PNObject/PNObjectAppDelegate.m index 3cfa1e2..15cbf2c 100644 --- a/Example/PNObject/PNObjectAppDelegate.m +++ b/Example/PNObject/PNObjectAppDelegate.m @@ -51,22 +51,28 @@ [user getJSONObject];*/ + PNAccessToken *accessToken = [PNAccessToken currentAccessToken]; + NSLog(@"%@",[accessToken JSONObject]); - [[[PNObjectConfig sharedInstance] manager] GET:[[[PNObjectConfig sharedInstance] PNObjEndpoint] stringByAppendingString:[PNAccessToken PNObjClassName]] parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) { + /*[[[PNObjectConfig sharedInstance] manager] GET:[[[PNObjectConfig sharedInstance] PNObjEndpoint] stringByAppendingString:[PNAccessToken PNObjClassName]] parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) { - } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { + } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { PNAccessToken *accessToken = [[PNAccessToken alloc] initWithJSON:responseObject]; - NSLog(@"%@",[accessToken getJSONObject]); - [accessToken saveLocally]; + NSLog(@"%@",[accessToken JSONObject]); - } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [accessToken saveLocally]; + }); + //[accessToken saveLocally]; + + } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"%@",error); - }]; + }];*/ //NSLog(@"%@",userDictionary); /* diff --git a/Pod/Classes/PNClasses/PNAccessToken.h b/Pod/Classes/PNClasses/PNAccessToken.h index 4f5d51b..5250dde 100644 --- a/Pod/Classes/PNClasses/PNAccessToken.h +++ b/Pod/Classes/PNClasses/PNAccessToken.h @@ -20,9 +20,16 @@ typedef NS_ENUM(NSInteger, TokenType) { * * @return singleton */ -+ (instancetype _Nonnull) currentUser; ++ (instancetype _Nonnull) currentAccessToken; +/** + * gets singleton object of current user session. + * + * @return singleton + */ ++ (instancetype _Nonnull) currentAccessTokenWithJSON:(NSDictionary *)JSON; + ///-------------------------------------- #pragma mark - PNAccessToken Properties ///-------------------------------------- diff --git a/Pod/Classes/PNClasses/PNAccessToken.m b/Pod/Classes/PNClasses/PNAccessToken.m index 68a097e..8426244 100644 --- a/Pod/Classes/PNClasses/PNAccessToken.m +++ b/Pod/Classes/PNClasses/PNAccessToken.m @@ -15,6 +15,81 @@ @implementation PNAccessToken +static PNAccessToken *SINGLETON = nil; + +static bool isFirstAccess = YES; + +#pragma mark - Public Method + ++ (instancetype) currentAccessToken { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + isFirstAccess = NO; + + SINGLETON = [[super allocWithZone:NULL] initForCurrentAccessTokenWithJSON:nil]; + }); + + return SINGLETON; +} + ++ (instancetype _Nonnull) currentAccessTokenWithJSON:(NSDictionary *)JSON { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + isFirstAccess = NO; + + SINGLETON = [[super allocWithZone:NULL] initForCurrentAccessTokenWithJSON:JSON]; + }); + + return SINGLETON; +} + + +- (instancetype) initForCurrentAccessTokenWithJSON:(NSDictionary *)JSON { + if(SINGLETON){ + return SINGLETON; + } + if (isFirstAccess) { + [self doesNotRecognizeSelector:_cmd]; + } + NSDictionary *savedAccessToken; + + if (JSON) { + savedAccessToken = JSON; + } + else { + savedAccessToken = [[PNObjectModel sharedInstance] fetchObjectsWithClass:[self class]]; + } + + if (savedAccessToken) { + self = [super initWithJSON:savedAccessToken]; + } + else { + self = [super init]; + } + + if (self) { + if (_tokenTypeString) { + ((void (^)())@{ + @"beaer" : ^{ + _tokenType = TokenTypeBearer; + }, + @"basic" : ^{ + _tokenType = TokenTypeBasic; + } + }[_tokenTypeString] ?: ^{ + + })(); + } + + if (_expiresIn) { + _expirationDate = [[NSDate date] dateByAddingHours:[_expiresIn integerValue]]; + } + } + + return self; +} + + #pragma mark PNObjectSubclassing Protocol + (NSDictionary *)objcetMapping { @@ -30,23 +105,7 @@ } - (instancetype) initWithJSON:(NSDictionary *)JSON { - self = [super initWithJSON:JSON]; - - if (self) { - ((void (^)())@{ - @"beaer" : ^{ - _tokenType = TokenTypeBearer; - }, - @"basic" : ^{ - _tokenType = TokenTypeBasic; - } - }[_tokenTypeString] ?: ^{ - - })(); - - _expirationDate = [[NSDate date] dateByAddingHours:[_expiresIn integerValue]]; - } - return self; + return [[self class] currentAccessTokenWithJSON:JSON]; } + (NSString *)objectClassName { diff --git a/Pod/Classes/PNObject+PNObjectConnection.m b/Pod/Classes/PNObject+PNObjectConnection.m index 2b21658..677b20c 100644 --- a/Pod/Classes/PNObject+PNObjectConnection.m +++ b/Pod/Classes/PNObject+PNObjectConnection.m @@ -19,79 +19,79 @@ - (NSURLSessionDataTask * _Nonnull)GETWithProgress:(void (^ _Nullable)(NSProgress * _Nonnull))downloadProgress - success:(void (^ _Nullable)(NSURLSessionDataTask * _Nonnull, id _Nullable))success - failure:(void (^ _Nullable)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure { - - return [[[PNObjectConfig sharedInstance] manager] GET:[[[PNObjectConfig sharedInstance] PNObjEndpoint] stringByAppendingFormat:@"%@",[[self class] objectClassName]] parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) { - - - NSLogDebug(@"JSON: %@", responseObject); - NSLogDebug(@"JSON: %@", [responseObject class]); - - self.JSON = [[NSDictionary alloc] initWithDictionary:responseObject]; - - [self populateObjectFromJSON:responseObject]; - - - } failure:^(NSURLSessionTask *operation, NSError *error) { - - NSLogDebug(@"Error: %@", error); - - }]; + success:(void (^ _Nullable)(NSURLSessionDataTask * _Nonnull, id _Nullable))success + failure:(void (^ _Nullable)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure { + + return [[[PNObjectConfig sharedInstance] manager] GET:[[[PNObjectConfig sharedInstance] PNObjEndpoint] stringByAppendingFormat:@"%@",[[self class] objectClassName]] parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) { + + + NSLogDebug(@"JSON: %@", responseObject); + NSLogDebug(@"JSON: %@", [responseObject class]); + + self.JSON = [[NSDictionary alloc] initWithDictionary:responseObject]; + + [self populateObjectFromJSON:responseObject]; + + + } failure:^(NSURLSessionTask *operation, NSError *error) { + + NSLogDebug(@"Error: %@", error); + + }]; } - (NSURLSessionDataTask *)POSTWithProgress:(nullable void (^)(NSProgress * _Nonnull)) uploadProgress - success:(void (^)(NSURLSessionDataTask *task, id responseObject))success - failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { - - return [[[PNObjectConfig sharedInstance] manager] POST:[[[PNObjectConfig sharedInstance] PNObjEndpoint] stringByAppendingFormat:@"%@",[[self class] objectClassName]] - parameters:[self getJSONObject] constructingBodyWithBlock:^(id _Nonnull formData) { - - } progress:^(NSProgress * _Nonnull _uploadProgress) { - if (uploadProgress) { - uploadProgress(_uploadProgress); - } - } success:^(NSURLSessionDataTask * _Nonnull _task, id _Nullable _responseObject) { - if (success) { - success(_task,_responseObject); - } - } failure:^(NSURLSessionDataTask * _Nullable _task, NSError * _Nonnull _error) { - if (failure) { - failure(_task,_error); - } - }]; + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { + + return [[[PNObjectConfig sharedInstance] manager] POST:[[[PNObjectConfig sharedInstance] PNObjEndpoint] stringByAppendingFormat:@"%@",[[self class] objectClassName]] + parameters:[self JSONObject] constructingBodyWithBlock:^(id _Nonnull formData) { + + } progress:^(NSProgress * _Nonnull _uploadProgress) { + if (uploadProgress) { + uploadProgress(_uploadProgress); + } + } success:^(NSURLSessionDataTask * _Nonnull _task, id _Nullable _responseObject) { + if (success) { + success(_task,_responseObject); + } + } failure:^(NSURLSessionDataTask * _Nullable _task, NSError * _Nonnull _error) { + if (failure) { + failure(_task,_error); + } + }]; } - (NSURLSessionDataTask *)PUTWithSuccess:(void (^)(NSURLSessionDataTask *task, id responseObject))success - failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { - - return [[[PNObjectConfig sharedInstance] manager] PUT:[[[PNObjectConfig sharedInstance] PNObjEndpoint] stringByAppendingFormat:@"%@",[[self class] objectClassName]] - parameters:[self getJSONObject] - success:^(NSURLSessionDataTask * _Nonnull _task, id _Nullable _responseObject) { - if (success) { - success(_task,_responseObject); - } - } failure:^(NSURLSessionDataTask * _Nullable _task, NSError * _Nonnull _error) { - if (failure) { - failure(_task,_error); - } - }]; + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { + + return [[[PNObjectConfig sharedInstance] manager] PUT:[[[PNObjectConfig sharedInstance] PNObjEndpoint] stringByAppendingFormat:@"%@",[[self class] objectClassName]] + parameters:[self JSONObject] + success:^(NSURLSessionDataTask * _Nonnull _task, id _Nullable _responseObject) { + if (success) { + success(_task,_responseObject); + } + } failure:^(NSURLSessionDataTask * _Nullable _task, NSError * _Nonnull _error) { + if (failure) { + failure(_task,_error); + } + }]; } - (NSURLSessionDataTask *)DELETEWithSuccess:(void (^)(NSURLSessionDataTask *task, id responseObject))success - failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { - return [[[PNObjectConfig sharedInstance] manager] DELETE:[[[PNObjectConfig sharedInstance] PNObjEndpoint] stringByAppendingFormat:@"%@",[[self class] objectClassName]] - parameters:[self getJSONObject] - success:^(NSURLSessionDataTask * _Nonnull _task, id _Nullable _responseObject) { - if (success) { - success(_task,_responseObject); - } - } failure:^(NSURLSessionDataTask * _Nullable _task, NSError * _Nonnull _error) { - if (failure) { - failure(_task,_error); - } - }]; + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { + return [[[PNObjectConfig sharedInstance] manager] DELETE:[[[PNObjectConfig sharedInstance] PNObjEndpoint] stringByAppendingFormat:@"%@",[[self class] objectClassName]] + parameters:[self JSONObject] + success:^(NSURLSessionDataTask * _Nonnull _task, id _Nullable _responseObject) { + if (success) { + success(_task,_responseObject); + } + } failure:^(NSURLSessionDataTask * _Nullable _task, NSError * _Nonnull _error) { + if (failure) { + failure(_task,_error); + } + }]; } @end diff --git a/Pod/Classes/PNObject+Protected.m b/Pod/Classes/PNObject+Protected.m index 4bc7c8d..83ee3e3 100644 --- a/Pod/Classes/PNObject+Protected.m +++ b/Pod/Classes/PNObject+Protected.m @@ -42,7 +42,7 @@ NSString *mappedJSONType; NSString *propertyType = [properties valueForKey:propertyName]; - NSLogDebug(@"%@",self.objectMapping); + NSLogDebug(@"%@",self.JSONObject); NSLogDebug(@"%@",[[self class] objcetMapping]); @@ -156,7 +156,7 @@ NSString *propertyType = [properties valueForKey:propertyName]; - id mappingValue = [self.objectMapping valueForKey:propertyName]; + id mappingValue = [self.JSONObject valueForKey:propertyName]; if([mappingValue isKindOfClass:NSDictionary.class]) { mappedJSONKey = [mappingValue valueForKey:@"key"]; diff --git a/Pod/Classes/PNObject.h b/Pod/Classes/PNObject.h index 0ca80f8..538a03f 100644 --- a/Pod/Classes/PNObject.h +++ b/Pod/Classes/PNObject.h @@ -50,7 +50,7 @@ /** * <#Description#> */ -@property (nonatomic, strong, getter=getJSONObject, nonnull) NSDictionary * objectMapping; +@property (nonatomic, strong, nonnull) NSDictionary * JSONObject; @end diff --git a/Pod/Classes/PNObject.m b/Pod/Classes/PNObject.m index f6392dd..1cf63d5 100644 --- a/Pod/Classes/PNObject.m +++ b/Pod/Classes/PNObject.m @@ -75,9 +75,9 @@ NSMutableDictionary * objectDict = [[NSMutableDictionary alloc] initWithDictionary:[[self class] objcetMapping]]; [objectDict addEntriesFromDictionary:[PNObject objcetMapping]]; - _objectMapping = objectDict; + _JSONObject = objectDict; - NSAssert(_objectMapping, @"You must create objectMapping"); + NSAssert(_JSONObject, @"You must create objectMapping"); _singleInstance = [[self class] singleInstance]; @@ -102,9 +102,9 @@ NSMutableDictionary * objectDict = [[NSMutableDictionary alloc] initWithDictionary:[[self class] objcetMapping]]; [objectDict addEntriesFromDictionary:[PNObject objcetMapping]]; - _objectMapping = objectDict; + _JSONObject = objectDict; - NSAssert(_objectMapping, @"You must create objectMapping"); + NSAssert(_JSONObject, @"You must create objectMapping"); _singleInstance = [[self class] singleInstance]; @@ -112,7 +112,7 @@ } - NSAssert(_objectMapping, @"You must create objectMapping"); + NSAssert(_JSONObject, @"You must create objectMapping"); _JSON = [[NSMutableDictionary alloc] initWithDictionary:JSON]; [self populateObjectFromJSON:_JSON]; @@ -129,8 +129,8 @@ NSDictionary *properties = [PNObject propertiesForClass:self.class]; - for (NSString* propertyName in _objectMapping) { - id mappingValue = [_objectMapping objectForKey:propertyName]; + for (NSString* propertyName in _JSONObject) { + id mappingValue = [_JSONObject objectForKey:propertyName]; if([mappingValue isKindOfClass:NSDictionary.class]) { mappedJSONKey = [mappingValue valueForKey:@"key"]; @@ -205,7 +205,7 @@ @"NSArray" : ^{ NSMutableArray *arr = [NSMutableArray array]; for(id PNObject in value) { - SEL selector = NSSelectorFromString(@"getJSONObject"); + SEL selector = NSSelectorFromString(@"JSONObject"); NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: [[PNObject class] instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:PNObject]; @@ -224,7 +224,7 @@ PNObject *val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject]; [arr addObject:val]; - SEL selector = NSSelectorFromString(@"getJSONObject"); + SEL selector = NSSelectorFromString(@"JSONObject"); NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:value]; @@ -238,7 +238,7 @@ }[propertyType] ?: ^{ BOOL isPNObjectSubclass = [NSClassFromString(propertyType) isSubclassOfClass:[PNObject class]]; if(isPNObjectSubclass) { - SEL selector = NSSelectorFromString(@"getJSONObject"); + SEL selector = NSSelectorFromString(@"JSONObject"); NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:value]; @@ -260,7 +260,7 @@ } -- (NSDictionary* _Nonnull) getJSONObject { +- (NSDictionary* _Nonnull) JSONObject { if (!_JSON) { return [self reverseMapping]; } @@ -321,7 +321,6 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - NSLogDebug(@"%@",[[[self class] objcetMapping] objectForKey:keyPath]); [_JSON setObject:[change objectForKey:@"new"] forKey:[[[self class] objcetMapping] objectForKey:keyPath]]; } @@ -333,10 +332,19 @@ if ([propertyName isEqualToString:@"description"] || [propertyName isEqualToString:@"debugDescription"]) { continue; } - [self removeObserver:self forKeyPath:propertyName]; + + @try { + [self removeObserver:self forKeyPath:propertyName]; + } + @catch (NSException *exception) { + + } + @finally { + + } } _JSON = nil; - _objectMapping = nil; + _JSONObject = nil; _objID = nil; _createdAt = nil; diff --git a/Pod/Classes/PNObjectModel.m b/Pod/Classes/PNObjectModel.m index 41e7f7c..1fa78b7 100644 --- a/Pod/Classes/PNObjectModel.m +++ b/Pod/Classes/PNObjectModel.m @@ -161,7 +161,7 @@ static bool isFirstAccess = YES; if ([(PNObject*) object singleInstance]) { - SEL selector = NSSelectorFromString(@"getJSONObject"); + SEL selector = NSSelectorFromString(@"JSONObject"); NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:object]; @@ -197,7 +197,7 @@ static bool isFirstAccess = YES; NSMutableArray *objects = [[NSMutableArray alloc] initWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:data]]; - SEL selector = NSSelectorFromString(@"getJSONObject"); + SEL selector = NSSelectorFromString(@"JSONObject"); NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:object]; @@ -225,7 +225,7 @@ static bool isFirstAccess = YES; NSMutableArray *objects = [[NSMutableArray alloc] init]; - SEL selector = NSSelectorFromString(@"getJSONObject"); + SEL selector = NSSelectorFromString(@"JSONObject"); NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:object];