- Refactoring classes

- Add Installation Class
- Add AccessToken Class (not yet complete)
- Remove PNObjectProperty
- Move PNObjectProperty methods to "PNObject+Protected.h"
This commit is contained in:
giuseppenuc committed 2016-01-27 15:14:04 +01:00
1 parent 1efd26a133
commit fad171373e
24 files changed
+1358 -945

No files matched your search

+30
View File
@@ -0,0 +1,30 @@
//
// PNAccessToken.h
// Pods
//
// Created by Giuseppe Nucifora on 27/01/16.
//
//
#import <PNObject/PNObject.h>
@interface PNAccessToken : PNObject
typedef NS_ENUM(NSInteger, TokenType) {
TokenTypeBasic = 1,
TokenTypeBearer = 2
};
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSString *accessToken;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSDate *expirationDate;
/**
* <#Description#>
*/
@property (nonatomic) TokenType tokenType;
@end
+44
View File
@@ -0,0 +1,44 @@
//
// PNAccessToken.m
// Pods
//
// Created by Giuseppe Nucifora on 27/01/16.
//
//
#import "PNAccessToken.h"
@interface PNAccessToken() <PNObjectSubclassing>
@end
@implementation PNAccessToken
#pragma mark PNObjectSubclassing Protocol
+ (NSDictionary *)objcetMapping {
NSDictionary *mapping = @{
@"accessToken":@"accessToken",
@"expirationDate":@"expirationDate",
@"tokenType":@"tokenType",
};
return mapping;
}
+ (NSString *)objectClassName {
return @"AccessToken";
}
+ (BOOL) singleInstance {
return YES;
}
#pragma mark -
@end
+51
View File
@@ -0,0 +1,51 @@
//
// PNAddress.h
// Pods
//
// Created by Giuseppe Nucifora on 13/01/16.
//
//
#import "PNObject.h"
#import "PNLocation.h"
@interface PNAddress : PNObject <PNObjectSubclassing>
///--------------------------------------
#pragma mark - PNAddress Properties
///--------------------------------------
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSString * country;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSString * province;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSString * city;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSString * street;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSNumber * number;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSString * zip;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSString * istruction;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) PNLocation * location;
@end
File renamed without changes.
+59
View File
@@ -0,0 +1,59 @@
//
// PNInstallation.h
// Pods
//
// Created by Giuseppe Nucifora on 27/01/16.
//
//
#import <PNObject/PNObject.h>
@interface PNInstallation : PNObject
/**
Gets the currently-running installation from disk and returns an instance of it.
If this installation is not stored on disk, returns a `PFInstallation`
with `deviceType` and `installationId` fields set to those of the
current installation.
@result Returns a `Installation` that represents the currently-running installation.
*/
+ (instancetype _Nonnull)currentInstallation;
- (void)setDeviceTokenFromData:(nullable NSData *)deviceTokenData;
///--------------------------------------
#pragma mark - PNInstallation Properties
///--------------------------------------
/**
* <#Description#>
*/
@property (nonatomic, strong, readonly, nonnull) NSString *deviceType;
/**
* <#Description#>
*/
@property (nonatomic, strong, readonly, nonnull) NSString *deviceModel;
/**
* <#Description#>
*/
@property (nonatomic, strong, readonly, nonnull) NSString *deviceName;
/**
* <#Description#>
*/
@property (nonatomic, strong, readonly, nonnull) NSString *osVersion;
/**
* <#Description#>
*/
@property (nonatomic, strong, readonly, nonnull) NSString *localeIdentifier;
/**
* <#Description#>
*/
@property (nonatomic, strong, readonly, nullable) NSString *deviceToken;
/**
* <#Description#>
*/
@property (nonatomic, assign) NSInteger badge;
@end
+111
View File
@@ -0,0 +1,111 @@
//
// PNInstallation.m
// Pods
//
// Created by Giuseppe Nucifora on 27/01/16.
//
//
#import "PNInstallation.h"
@interface PNInstallation() <PNObjectSubclassing>
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSData *deviceTokenData;
@end
@implementation PNInstallation
static PNInstallation *SINGLETON = nil;
static bool isFirstAccess = YES;
#pragma mark PNObjectSubclassing Protocol
+ (NSDictionary *)objcetMapping {
NSDictionary *mapping = @{
@"deviceType":@"deviceType",
@"deviceModel":@"deviceModel",
@"deviceName":@"deviceName",
@"osVersion":@"osVersion",
@"deviceToken":@"deviceToken",
@"badge":@"badge",
@"localeIdentifier":@"localeIdentifier",
};
return mapping;
}
+ (NSString *)objectClassName {
return @"AccessToken";
}
+ (BOOL) singleInstance {
return YES;
}
#pragma mark -
#pragma mark Public Methods
+ (instancetype) currentInstallation {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
isFirstAccess = NO;
SINGLETON = [[super allocWithZone:NULL] init];
});
return SINGLETON;
}
- (void)setDeviceTokenFromData:(NSData *)deviceTokenData {
_deviceTokenData = deviceTokenData;
NSString *ptoken = [[[[deviceTokenData description]
stringByReplacingOccurrencesOfString:@"<"withString:@""]
stringByReplacingOccurrencesOfString:@">" withString:@""]
stringByReplacingOccurrencesOfString: @" " withString: @""];
_deviceToken = ptoken;
}
#pragma mark -
#pragma mark Private Methods
- (id) init
{
if(SINGLETON){
return SINGLETON;
}
if (isFirstAccess) {
[self doesNotRecognizeSelector:_cmd];
}
NSDictionary *savedInstallation = [[PNObjectModel sharedInstance] fetchObjectsWithClass:[self class]];
if (savedInstallation) {
self = [super initWithJSON:savedInstallation];
}
else {
self = [super init];
}
if (self) {
_deviceModel = [[UIDevice currentDevice] model];
_osVersion = [[UIDevice currentDevice] systemVersion];;
_deviceName = [[UIDevice currentDevice] name];;
}
return self;
}
#pragma mark -
@end
@@ -10,7 +10,17 @@
@interface PNLocation : PNObject <PNObjectSubclassing>
///--------------------------------------
#pragma mark - PNLocation Properties
///--------------------------------------
/**
* <#Description#>
*/
@property (nonatomic) CGFloat lat;
/**
* <#Description#>
*/
@property (nonatomic) CGFloat lng;
@end
File renamed without changes.
+103
View File
@@ -0,0 +1,103 @@
//
// PNUser.h
// Pods
//
// Created by Giuseppe Nucifora on 15/01/16.
//
//
#import "PNObject.h"
@interface PNUser : PNObject
/**
* gets singleton object of current user session.
*
* @return singleton
*/
+ (instancetype _Nonnull) currentUser;
- (BOOL) isValidPassword:(NSString* _Nonnull) password;
//- (void) setPassword:(NSString * _Nonnull)password inBackGroundWithBlock:(nullable void (^)(BOOL saveStatus, id responseObject, NSError * error)) responseBlock;
///--------------------------------------
#pragma mark - PNLocation Properties
///--------------------------------------
/**
* <#Description#>
*/
@property (strong, nonatomic, nonnull) NSString * userId;
/**
* <#Description#>
*/
@property (strong, nonatomic, nonnull) NSString * firstName;
/**
* <#Description#>
*/
@property (strong, nonatomic, nonnull) NSString * lastName;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) UIImage * profileImage;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSString * sex;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSDate * birthDate;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSString * phone;
/**
* <#Description#>
*/
@property (nonatomic) BOOL hasAcceptedPrivacy;
/**
* <#Description#>
*/
@property (nonatomic) BOOL hasAcceptedNewsletter;
/**
* <#Description#>
*/
@property (nonatomic) BOOL hasVerifiedEmail;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSDate * emailVerifiedDate;
/**
* <#Description#>
*/
@property (nonatomic, strong, nonnull) NSString * email;
/**
* <#Description#>
*/
@property (nonatomic, strong, nonnull) NSString * username;
/**
* <#Description#>
*/
@property (nonatomic, strong, nonnull) NSString * password;
/**
* <#Description#>
*/
@property (nonatomic) BOOL publicProfile;
/**
* <#Description#>
*/
@property (nonatomic, strong, nonnull) NSNumber * loginCount;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSString * facebookId;
/**
* <#Description#>
*/
@property (nonatomic, strong, nullable) NSString * facebookAccessToken;
@end
+156
View File
@@ -0,0 +1,156 @@
//
// PNUser.m
// Pods
//
// Created by Giuseppe Nucifora on 15/01/16.
//
//
#import "PNUser.h"
#import "NSString+Helper.h"
#import "PNObjectConstants.h"
#import "PNObject+Protected.h"
@interface PNUser() <PNObjectSubclassing>
@end
@implementation PNUser
@synthesize password = _password;
static PNUser *SINGLETON = nil;
static bool isFirstAccess = YES;
#pragma mark - Public Method
+ (instancetype) currentUser {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
isFirstAccess = NO;
SINGLETON = [[super allocWithZone:NULL] init];
});
return SINGLETON;
}
#pragma mark - Life Cycle
+ (instancetype) allocWithZone:(NSZone *)zone
{
return [self currentUser];
}
+ (instancetype)copyWithZone:(struct _NSZone *)zone
{
return [self currentUser];
}
+ (instancetype)mutableCopyWithZone:(struct _NSZone *)zone
{
return [self currentUser];
}
- (instancetype)copy
{
return [[PNUser alloc] init];
}
- (instancetype)mutableCopy
{
return [[PNUser alloc] init];
}
- (id) init
{
if(SINGLETON){
return SINGLETON;
}
if (isFirstAccess) {
[self doesNotRecognizeSelector:_cmd];
}
NSDictionary *savedUser = [[PNObjectModel sharedInstance] fetchObjectsWithClass:[self class]];
if (savedUser) {
self = [super initWithJSON:savedUser];
}
else {
self = [super init];
}
if (self) {
}
return self;
}
- (void) setEmail:(NSString *)email {
if ([email isValidEmail]) {
_email = email;
}
NSLogDebug(@"insertedEmail is not valid.");
}
- (void) setPassword:(NSString *)password {
if ([self isValidPassword:password]) {
_password = password;
}
else {
NSLogDebug(@"Inserted Passord is not valid.Lenght must be >= %ld",(long)[[PNObjectConfig sharedInstance] minPasswordLenght]);
}
}
- (BOOL) isValidPassword:(NSString* _Nonnull) password {
if ([password length] >= [[PNObjectConfig sharedInstance] minPasswordLenght]) {
return YES;
}
return NO;
}
- (NSString *) password {
return @"password is not readble";
}
#pragma mark PNObjectSubclassing Protocol
+ (NSDictionary *)objcetMapping {
NSDictionary *mapping = @{
@"userId":@"id",
@"firstName":@"firstName",
@"lastName":@"lastName",
@"profileImage":@"profileImage",
@"sex":@"sex",
@"birthDate":@"birthDate",
@"phone":@"phone",
@"password":@"password",
@"hasAcceptedPrivacy":@"hasAcceptedPrivacy",
@"hasAcceptedNewsletter":@"hasAcceptedNewsletter",
@"hasVerifiedEmail":@"hasVerifiedEmail",
@"emailVerifiedDate":@"emailVerifiedDate",
@"email":@"email",
@"username":@"username",
@"publicProfile":@"public_profile",
@"loginCount":@"login_count",
@"facebookId":@"facebookId",
@"facebookAccessToken":@"facebookAccessToken",
};
return mapping;
}
+ (NSString *)objectClassName {
return @"User";
}
+ (BOOL) singleInstance {
return YES;
}
#pragma mark -
@end
+46 -13
View File
@@ -7,24 +7,57 @@
//
#import <PNObject/PNObject.h>
#import <objc/runtime.h>
@interface PNObject (Protected)
/**
* <#Description#>
*
* @param JSON <#JSON description#>
*/
- (void)populateObjectFromJSON:(id _Nullable)JSON;
/**
* <#Description#>
*
* @param obj <#obj description#>
*
* @return <#return value description#>
*/
- (BOOL)isObjNull:(id _Nullable)obj;
/**
* <#Description#>
*
* @return <#return value description#>
*/
+ (NSArray * _Nonnull) protectedProperties;
/**
* <#Description#>
*
* @param PNObjClass <#PNObjClass description#>
*
* @return <#return value description#>
*/
+ (NSDictionary * _Nullable)propertiesForClass:(Class _Nonnull)PNObjClass;
@property (nonatomic, strong) PNObjectModel * _Nonnull objectModel;
@property (nonatomic, strong) NSDictionary * _Nonnull JSON;
@property (nonatomic, strong) NSString * _Nonnull endPoint;
///--------------------------------------
#pragma mark - PNObject (Protected) Properties
///--------------------------------------
/**
* <#Description#>
*/
@property (nonatomic, strong, nonnull) PNObjectModel * objectModel;
/**
* <#Description#>
*/
@property (nonatomic, strong, nonnull) NSDictionary * JSON;
/**
* <#Description#>
*/
@property (nonatomic, strong, nonnull) NSString * endPoint;
/**
* <#Description#>
*/
@property (nonatomic) BOOL singleInstance;
- (void)populateObjectFromJSON:(id _Nullable)JSON;
- (BOOL)isStringNull:(NSString * _Nullable)str;
- (BOOL)isObjNull:(id _Nullable)obj;
+ (NSArray * _Nonnull) protectedProperties;
@end
+180 -116
View File
@@ -7,9 +7,9 @@
//
#import "PNObject+Protected.h"
#import <PNObjectProperty.h>
#import "PNObjectConstants.h"
#import <NSDate_Utils/NSDate+NSDate_Util.h>
#import "objc/runtime.h"
@implementation PNObject (Protected)
@@ -18,130 +18,194 @@
@dynamic JSON;
@dynamic singleInstance;
+ (PNObjectModel* _Nonnull) objectModel {
}
+ (NSArray * _Nonnull) protectedProperties {
return @[@"JSON",@"subClassDelegate",@"objectModel",@"objectMapping",@"singleInstance"];
return @[@"JSON",@"objectModel",@"objectMapping",@"singleInstance"];
}
- (void)populateObjectFromJSON:(id _Nullable)JSON
{
NSDictionary *properties = [PNObjectProperty propertiesForClass:self.class];
for(NSString *propertyName in properties) {
if([propertyName isEqualToString:@"mappingError"])
continue;
NSString *mappedJSONKey;
NSString *mappedJSONType;
NSString *propertyType = [properties valueForKey:propertyName];
id mappingValue = [self.objectMapping valueForKey:propertyName];
if([mappingValue isKindOfClass:NSDictionary.class]) {
mappedJSONKey = [mappingValue valueForKey:@"key"];
mappedJSONType = [mappingValue valueForKey:@"type"];
} else {
mappedJSONKey = mappingValue;
}
if ([[PNObject protectedProperties] containsObject:propertyName]) {
continue;
}
// Get JSON value for the mapped key
id value = [JSON valueForKeyPath:propertyName];
((void (^)())@{
@"c" : ^{
char val = [value charValue];
[self setValue:@(val) forKey:propertyName];
},
@"d" : ^{
double val = [value doubleValue];
[self setValue:@(val) forKey:propertyName];
},
@"f" : ^{
float val = [value floatValue];
[self setValue:@(val) forKey:propertyName];
},
@"i" : ^{
int val = [value intValue];
[self setValue:@(val) forKey:propertyName];
},
@"l" : ^{
long val = [value longValue];
[self setValue:@(val) forKey:propertyName];
},
@"s" : ^{
short val = [value shortValue];
[self setValue:@(val) forKey:propertyName];
},
@"B" : ^{
BOOL val = [value boolValue];
[self setValue:@(val) forKey:propertyName];
},
@"NSString" : ^{
if (![self isObjNull:value]) {
[self setValue:value forKey:propertyName];
}
},
@"NSNumber" : ^{
NSInteger val = [value integerValue];
[self setValue:@(val) forKey:propertyName];
},
@"NSDate" : ^{
NSString *str = [NSString stringWithFormat:@"%@", value];
NSDate *val = [[NSDate dateFromString:str withFormat:kNSDateHelperFormatSQLDateWithTime] toLocalTime];
if (![self isObjNull:val]) {
[self setValue:val forKey:propertyName];
}
},
@"NSArray" : ^{
NSMutableArray *arr = [NSMutableArray array];
for(id JSONObject in value) {
PNObject *val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject];
[arr addObject:val];
}
[self setValue:arr forKey:propertyName];
},
@"NSMutableArray" : ^{
NSMutableArray *arr = [NSMutableArray array];
for(id JSONObject in value) {
PNObject *val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject];
[arr addObject:val];
}
[self setValue:arr forKey:propertyName];
}
}[propertyType] ?: ^{
BOOL isPNObjectSubclass = [NSClassFromString(propertyType) isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
PNObject *val = [[NSClassFromString(propertyType) alloc] initWithJSON:value];
[self setValue:val forKey:propertyName];
}
else {
NSString *errorStr = [NSString stringWithFormat:@"Property '%@' could not be assigned any value.", propertyName];
NSLogDebug(@"%@",errorStr);
}
})();
}
NSDictionary *properties = [PNObject propertiesForClass:self.class];
for(NSString *propertyName in properties) {
if([propertyName isEqualToString:@"mappingError"])
continue;
NSString *mappedJSONKey;
NSString *mappedJSONType;
NSString *propertyType = [properties valueForKey:propertyName];
id mappingValue = [self.objectMapping valueForKey:propertyName];
if([mappingValue isKindOfClass:NSDictionary.class]) {
mappedJSONKey = [mappingValue valueForKey:@"key"];
mappedJSONType = [mappingValue valueForKey:@"type"];
} else {
mappedJSONKey = mappingValue;
}
if ([[PNObject protectedProperties] containsObject:propertyName]) {
continue;
}
// Get JSON value for the mapped key
id value = [JSON valueForKeyPath:propertyName];
((void (^)())@{
@"c" : ^{
char val = [value charValue];
[self setValue:@(val) forKey:propertyName];
},
@"d" : ^{
double val = [value doubleValue];
[self setValue:@(val) forKey:propertyName];
},
@"f" : ^{
float val = [value floatValue];
[self setValue:@(val) forKey:propertyName];
},
@"i" : ^{
int val = [value intValue];
[self setValue:@(val) forKey:propertyName];
},
@"l" : ^{
long val = [value longValue];
[self setValue:@(val) forKey:propertyName];
},
@"s" : ^{
short val = [value shortValue];
[self setValue:@(val) forKey:propertyName];
},
@"B" : ^{
BOOL val = [value boolValue];
[self setValue:@(val) forKey:propertyName];
},
@"NSString" : ^{
if (![self isObjNull:value]) {
[self setValue:value forKey:propertyName];
}
},
@"NSNumber" : ^{
NSInteger val = [value integerValue];
[self setValue:@(val) forKey:propertyName];
},
@"NSDate" : ^{
NSString *str = [NSString stringWithFormat:@"%@", value];
NSDate *val = [[NSDate dateFromString:str withFormat:kNSDateHelperFormatSQLDateWithTime] toLocalTime];
if (![self isObjNull:val]) {
[self setValue:val forKey:propertyName];
}
},
@"NSArray" : ^{
NSMutableArray *arr = [NSMutableArray array];
for(id JSONObject in value) {
PNObject *val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject];
[arr addObject:val];
}
[self setValue:arr forKey:propertyName];
},
@"NSMutableArray" : ^{
NSMutableArray *arr = [NSMutableArray array];
for(id JSONObject in value) {
PNObject *val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject];
[arr addObject:val];
}
[self setValue:arr forKey:propertyName];
}
}[propertyType] ?: ^{
BOOL isPNObjectSubclass = [NSClassFromString(propertyType) isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
PNObject *val = [[NSClassFromString(propertyType) alloc] initWithJSON:value];
[self setValue:val forKey:propertyName];
}
else {
NSString *errorStr = [NSString stringWithFormat:@"Property '%@' could not be assigned any value.", propertyName];
NSLogDebug(@"%@",errorStr);
}
})();
}
}
- (BOOL)isObjNull:(id _Nullable)obj
{
if(!obj || nil == obj || NSNull.null == obj || ([obj isKindOfClass:[NSString class]] && [obj isEqualToString:@"(null)"]) || [obj isEqual:[NSNull null]])
return YES;
else
return NO;
if(!obj || nil == obj || NSNull.null == obj || ([obj isKindOfClass:[NSString class]] && [obj isEqualToString:@"(null)"]) || [obj isEqual:[NSNull null]])
return YES;
else
return NO;
}
static BOOL property_getTypeString( objc_property_t property, char *buffer )
{
const char * attrs = property_getAttributes( property );
if ( attrs == NULL )
return NO;
const char * e = strchr( attrs, ',' );
if ( e == NULL )
return NO;
int len = (int)(e - attrs);
memcpy( buffer, attrs, len );
buffer[len] = '\0';
return YES;
}
+ (NSDictionary *)propertiesForClass:(Class)PNObjClass
{
if (PNObjClass == NULL) {
return nil;
}
NSMutableDictionary *results = [NSMutableDictionary dictionary];
if ([PNObjClass isSubclassOfClass:[PNObject class]] && PNObjClass != [PNObject class]) {
[results addEntriesFromDictionary:[self propertiesForClass:[PNObject class]]];
}
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(PNObjClass, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
//const char *propType = getPropertyType(property);
char propType[256];
if (!property_getTypeString(property, propType)) {
continue;
}
NSString *propertyName = [NSString stringWithUTF8String:propName];
NSString *propertyType = [NSString stringWithUTF8String:propType];
NSRange range = [propertyType rangeOfString:@"T@\""];
NSRange range2 = [propertyType rangeOfString:@"T"];
if (range.location != NSNotFound) {
NSRange subStrRange = NSMakeRange(range.length, propertyType.length - (range.length + 1));
propertyType = [propertyType substringWithRange:subStrRange];
}
else if (range2.location != NSNotFound) {
NSRange subStrRange = NSMakeRange(range2.length, propertyType.length - (range2.length));
propertyType = [propertyType substringWithRange:subStrRange];
}
//NSLogDebug(@"Prop type & name: %@ -- %@", propertyType, propertyName);
if (![[PNObject protectedProperties] containsObject:propertyName]) {
[results setObject:propertyType forKey:propertyName];
}
}
}
free(properties);
// returning a copy here to make sure the dictionary is immutable
return [NSDictionary dictionaryWithDictionary:results];
}
@end
+18 -5
View File
@@ -26,15 +26,28 @@
@interface PNObject : NSObject
@property (nonatomic, strong) NSString * _Nonnull objID;
@property (nonatomic, strong) NSDate * _Nonnull createdAt;
@property (nonatomic, strong, getter=getJSONObject) NSDictionary * _Nonnull objectMapping;
@property (nonatomic, assign) id<PNObjectSubclassing> _Nonnull subClassDelegate;
- (_Nullable instancetype) initWithJSON:( NSDictionary * _Nonnull) JSON;
- (id _Nonnull) saveLocally;
- (BOOL) autoRemoveLocally;
///--------------------------------------
#pragma mark - PNObject Properties
///--------------------------------------
/**
* <#Description#>
*/
@property (nonatomic, strong, nonnull) NSString * objID;
/**
* <#Description#>
*/
@property (nonatomic, strong, nonnull) NSDate * createdAt;
/**
* <#Description#>
*/
@property (nonatomic, strong, getter=getJSONObject, nonnull) NSDictionary * objectMapping;
@end
+238 -227
View File
@@ -7,7 +7,6 @@
//
#import "PNObject.h"
#import <PNObjectProperty.h>
#import <NSDate_Utils/NSDate+NSDate_Util.h>
#import <AFNetworking/AFNetworking.h>
#import "PNObject/PNUser.h"
@@ -17,7 +16,7 @@
#define PNOBJECT_DIR @"PNObjects"
@interface PNObject() <PNObjectPersistency>
@interface PNObject() <PNObjectPersistency,PNObjectSubclassing>
@property (nonatomic, strong) PNObjectModel * _Nonnull objectModel;
@@ -31,265 +30,277 @@
@implementation PNObject
- (NSDictionary *) PNObjectMapping {
NSDictionary *mapping = @{@"objID":@"objID",
@"createdAt":@"created_at",
};
return mapping;
#pragma mark PNObjectSubclassing
+ (NSDictionary *) objcetMapping {
NSDictionary *mapping = @{@"objID":@"objID",
@"createdAt":@"created_at",
};
return mapping;
}
+ (BOOL) singleInstance {
return NO;
}
+ (NSString*) objectClassName {
return @"PNObject";
}
#pragma mark -
- (_Nullable instancetype) init {
self = [super init];
if (self) {
if ([[self class] isSubclassOfClass:[PNObject class]]) {
NSAssert([[self class] conformsToProtocol:@protocol(PNObjectSubclassing)], @"Subclass object must conform to PNObjectSubclassing");
_objID = [[NSProcessInfo processInfo] globallyUniqueString];
_objectModel = [PNObjectModel sharedInstance];
[_objectModel setPersistencyDelegate:self];
NSMutableDictionary * objectDict = [[NSMutableDictionary alloc] initWithDictionary:[[self class] objcetMapping]];
[objectDict addEntriesFromDictionary:[self PNObjectMapping]];
_objectMapping = objectDict;
NSAssert(_objectMapping, @"You must create objectMapping");
_singleInstance = [[self class] singleInstance];
_createdAt = [[NSDate date] toLocalTime];
}
}
return self;
self = [super init];
if (self) {
if ([[self class] isSubclassOfClass:[PNObject class]]) {
NSAssert([[self class] conformsToProtocol:@protocol(PNObjectSubclassing)], @"Subclass object must conform to PNObjectSubclassing");
_objID = [[NSProcessInfo processInfo] globallyUniqueString];
_objectModel = [PNObjectModel sharedInstance];
[_objectModel setPersistencyDelegate:self];
NSMutableDictionary * objectDict = [[NSMutableDictionary alloc] initWithDictionary:[[self class] objcetMapping]];
[objectDict addEntriesFromDictionary:[PNObject objcetMapping]];
_objectMapping = objectDict;
NSAssert(_objectMapping, @"You must create objectMapping");
_singleInstance = [[self class] singleInstance];
_createdAt = [[NSDate date] toLocalTime];
}
}
return self;
}
- (_Nullable instancetype) initWithJSON:( NSDictionary * _Nonnull) JSON {
self = [super init];
if (self) {
if ([[self class] isSubclassOfClass:[PNObject class]]) {
NSAssert([[self class] conformsToProtocol:@protocol(PNObjectSubclassing)], @"Subclass object must conform to PNObjectSubclassing");
_objID = [[NSProcessInfo processInfo] globallyUniqueString];
_objectModel = [PNObjectModel sharedInstance];
[_objectModel setPersistencyDelegate:self];
NSMutableDictionary * objectDict = [[NSMutableDictionary alloc] initWithDictionary:[[self class] objcetMapping]];
[objectDict addEntriesFromDictionary:[self PNObjectMapping]];
_objectMapping = objectDict;
NSAssert(_objectMapping, @"You must create objectMapping");
_singleInstance = [[self class] singleInstance];
_createdAt = [[NSDate date] toLocalTime];
}
NSAssert(_objectMapping, @"You must create objectMapping");
_JSON = [[NSMutableDictionary alloc] initWithDictionary:JSON];
[self populateObjectFromJSON:_JSON];
}
return self;
self = [super init];
if (self) {
if ([[self class] isSubclassOfClass:[PNObject class]]) {
NSAssert([[self class] conformsToProtocol:@protocol(PNObjectSubclassing)], @"Subclass object must conform to PNObjectSubclassing");
_objID = [[NSProcessInfo processInfo] globallyUniqueString];
_objectModel = [PNObjectModel sharedInstance];
[_objectModel setPersistencyDelegate:self];
NSMutableDictionary * objectDict = [[NSMutableDictionary alloc] initWithDictionary:[[self class] objcetMapping]];
[objectDict addEntriesFromDictionary:[PNObject objcetMapping]];
_objectMapping = objectDict;
NSAssert(_objectMapping, @"You must create objectMapping");
_singleInstance = [[self class] singleInstance];
_createdAt = [[NSDate date] toLocalTime];
}
NSAssert(_objectMapping, @"You must create objectMapping");
_JSON = [[NSMutableDictionary alloc] initWithDictionary:JSON];
[self populateObjectFromJSON:_JSON];
}
return self;
}
- (NSDictionary * _Nonnull)reverseMapping
{
NSMutableDictionary *JSON = [NSMutableDictionary dictionary];
NSString *mappedJSONKey;
NSString *mappedJSONType;
NSDictionary *properties = [PNObjectProperty propertiesForClass:self.class];
for (NSString* propertyName in _objectMapping) {
id mappingValue = [_objectMapping objectForKey:propertyName];
if([mappingValue isKindOfClass:NSDictionary.class]) {
mappedJSONKey = [mappingValue valueForKey:@"key"];
mappedJSONType = [mappingValue valueForKey:@"type"];
} else {
mappedJSONKey = mappingValue;
}
NSString *propertyType = [properties valueForKey:propertyName];
id value = [self valueForKey:propertyName];
NSLog(@"PropertyName PropertyType Value: %@ - %@ - %@",propertyName,propertyType,value);
((void (^)())@{
@"c" : ^{
char val = [value charValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"d" : ^{
double val = [value doubleValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"f" : ^{
float val = [value floatValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"i" : ^{
int val = [value intValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"l" : ^{
long val = [value longValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"s" : ^{
short val = [value shortValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"B" : ^{
BOOL val = [value boolValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"UIImage" : ^{
UIImage *image = [UIImage imageWithData:value];
[JSON setValue:image forKey:propertyName];
},
@"NSURL" : ^{
NSURL *url = value;
if (![self isObjNull:url]) {
[JSON setValue:[url absoluteString] forKey:propertyName];
}
},
@"NSString" : ^{
NSString *val = [NSString stringWithFormat:@"%@", value];
if (![self isObjNull:val]) {
[JSON setValue:val forKey:propertyName];
}
},
@"NSNumber" : ^{
NSInteger val = [value integerValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"NSDate" : ^{
NSDate *val = [value toLocalTime];
if (![self isObjNull:val]) {
[JSON setValue:val forKey:propertyName];
}
},
@"NSArray" : ^{
NSMutableArray *arr = [NSMutableArray array];
for(id PNObject in value) {
SEL selector = NSSelectorFromString(@"getJSONObject");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: [[PNObject class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:PNObject];
[invocation invoke];
NSDictionary *returnValue;
[invocation getReturnValue:&returnValue];
[arr addObject:returnValue];
}
[JSON setValue:arr forKey:propertyName];
},
@"NSMutableArray" : ^{
NSMutableArray *arr = [NSMutableArray array];
for(id JSONObject in value) {
PNObject *val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject];
[arr addObject:val];
SEL selector = NSSelectorFromString(@"getJSONObject");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:value];
[invocation invoke];
NSDictionary *returnValue;
[invocation getReturnValue:&returnValue];
}
[JSON setValue:arr forKey:propertyName];
}
}[propertyType] ?: ^{
BOOL isPNObjectSubclass = [NSClassFromString(propertyType) isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
SEL selector = NSSelectorFromString(@"getJSONObject");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:value];
[invocation invoke];
NSDictionary *returnValue;
[invocation getReturnValue:&returnValue];
[JSON setValue:returnValue forKey:propertyName];
}
else {
// do nothing
}
})();
}
_JSON = JSON;
return _JSON;
NSMutableDictionary *JSON = [NSMutableDictionary dictionary];
NSString *mappedJSONKey;
NSString *mappedJSONType;
NSDictionary *properties = [PNObject propertiesForClass:self.class];
for (NSString* propertyName in _objectMapping) {
id mappingValue = [_objectMapping objectForKey:propertyName];
if([mappingValue isKindOfClass:NSDictionary.class]) {
mappedJSONKey = [mappingValue valueForKey:@"key"];
mappedJSONType = [mappingValue valueForKey:@"type"];
} else {
mappedJSONKey = mappingValue;
}
NSString *propertyType = [properties valueForKey:propertyName];
id value = [self valueForKey:propertyName];
NSLog(@"PropertyName PropertyType Value: %@ - %@ - %@",propertyName,propertyType,value);
((void (^)())@{
@"c" : ^{
char val = [value charValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"d" : ^{
double val = [value doubleValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"f" : ^{
float val = [value floatValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"i" : ^{
int val = [value intValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"l" : ^{
long val = [value longValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"s" : ^{
short val = [value shortValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"B" : ^{
BOOL val = [value boolValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"UIImage" : ^{
UIImage *image = [UIImage imageWithData:value];
[JSON setValue:image forKey:propertyName];
},
@"NSURL" : ^{
NSURL *url = value;
if (![self isObjNull:url]) {
[JSON setValue:[url absoluteString] forKey:propertyName];
}
},
@"NSString" : ^{
NSString *val = [NSString stringWithFormat:@"%@", value];
if (![self isObjNull:val]) {
[JSON setValue:val forKey:propertyName];
}
},
@"NSNumber" : ^{
NSInteger val = [value integerValue];
[JSON setValue:@(val) forKey:propertyName];
},
@"NSDate" : ^{
NSDate *val = [value toLocalTime];
if (![self isObjNull:val]) {
[JSON setValue:val forKey:propertyName];
}
},
@"NSArray" : ^{
NSMutableArray *arr = [NSMutableArray array];
for(id PNObject in value) {
SEL selector = NSSelectorFromString(@"getJSONObject");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: [[PNObject class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:PNObject];
[invocation invoke];
NSDictionary *returnValue;
[invocation getReturnValue:&returnValue];
[arr addObject:returnValue];
}
[JSON setValue:arr forKey:propertyName];
},
@"NSMutableArray" : ^{
NSMutableArray *arr = [NSMutableArray array];
for(id JSONObject in value) {
PNObject *val = [[NSClassFromString(mappedJSONType) alloc] initWithJSON:JSONObject];
[arr addObject:val];
SEL selector = NSSelectorFromString(@"getJSONObject");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:value];
[invocation invoke];
NSDictionary *returnValue;
[invocation getReturnValue:&returnValue];
}
[JSON setValue:arr forKey:propertyName];
}
}[propertyType] ?: ^{
BOOL isPNObjectSubclass = [NSClassFromString(propertyType) isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
SEL selector = NSSelectorFromString(@"getJSONObject");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:value];
[invocation invoke];
NSDictionary *returnValue;
[invocation getReturnValue:&returnValue];
[JSON setValue:returnValue forKey:propertyName];
}
else {
// do nothing
}
})();
}
_JSON = JSON;
return _JSON;
}
- (NSDictionary* _Nonnull) getJSONObject {
return [self reverseMapping];
return [self reverseMapping];
}
- (NSString* _Nonnull) description {
if (!_JSON) {
return [[self reverseMapping] description];
}
return [_JSON description];
if (!_JSON) {
return [[self reverseMapping] description];
}
return [_JSON description];
}
- (void) setSingleInstance:(BOOL)singleInstance {
_singleInstance = singleInstance;
_singleInstance = singleInstance;
}
#pragma mark PNObjectPersistency protocol
- (BOOL) initObjectPersistency {
BOOL isDir=YES;
NSError *error;
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSFileManager *fileManager= [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:[docDir stringByAppendingFormat:@"/%@",PNOBJECT_DIR] isDirectory:&isDir]) {
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docDir stringByAppendingFormat:@"/%@",PNOBJECT_DIR] withIntermediateDirectories:NO attributes:nil error:&error]) {
BOOL isDir=YES;
NSError *error;
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSFileManager *fileManager= [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:[docDir stringByAppendingFormat:@"/%@",PNOBJECT_DIR] isDirectory:&isDir]) {
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docDir stringByAppendingFormat:@"/%@",PNOBJECT_DIR] withIntermediateDirectories:NO attributes:nil error:&error]) {
#ifdef DEBUG
NSLogDebug(@"Create directory error: %@", error);
NSLogDebug(@"Create directory error: %@", error);
#endif
return NO;
}
}
return NO;
}
}
#ifdef DEBUG
NSLogDebug(@"%@",[docDir stringByAppendingFormat:@"/%@",PNOBJECT_DIR]);
NSLogDebug(@"%@",[docDir stringByAppendingFormat:@"/%@",PNOBJECT_DIR]);
#endif
return YES;
return YES;
}
- (id _Nonnull) saveLocally {
return [_objectModel saveLocally:self];
return [_objectModel saveLocally:self];
}
- (BOOL) autoRemoveLocally {
return [_objectModel removeObjectLocally:self];
return [_objectModel removeObjectLocally:self];
}
#pragma mark -
+32 -6
View File
@@ -10,19 +10,17 @@
#import <AFNetworking/AFNetworking.h>
typedef NS_ENUM(NSInteger, Environment) {
Development,
Stage,
Production
Development,
Stage,
Production
};
extern NSString* const EnvironmentProduction;
extern NSString* const EnvironmentStage;
extern NSString* const EnvironmentDevelopment;
@interface PNObjectConfig : NSObject
@property (nonatomic, strong) AFHTTPSessionManager *manager;
@property (nonatomic) NSInteger minPasswordLenght;
@interface PNObjectConfig : NSObject
/**
* gets singleton object.
@@ -44,10 +42,38 @@ extern NSString* const EnvironmentDevelopment;
*/
+ (instancetype) initSharedInstanceForEnvironments:(NSDictionary *) endpointUrlsForEnvironments;
/**
* <#Description#>
*
* @param env <#env description#>
*/
- (void) setEnvironment:(Environment) env;
/**
* <#Description#>
*
* @return <#return value description#>
*/
- (NSString *) PNObjEndpoint;
/**
* <#Description#>
*
* @param passLenght <#passLenght description#>
*/
- (void) setAcceptablePasswordLenght:(NSUInteger) passLenght;
///--------------------------------------
#pragma mark - PNObjectConfig Properties
///--------------------------------------
/**
* <#Description#>
*/
@property (nonatomic, strong) AFHTTPSessionManager *manager;
/**
* <#Description#>
*/
@property (nonatomic) NSInteger minPasswordLenght;
@end
+20 -2
View File
@@ -18,10 +18,19 @@
@interface PNObjectModel : NSObject
@property (nonatomic, assign) id<PNObjectPersistency> _Nonnull persistencyDelegate;
@property (nonatomic, assign, nonnull) id<PNObjectPersistency> persistencyDelegate;
+ (_Nonnull instancetype) sharedInstance;
/**
* <#Description#>
*
* @param class <#class description#>
*
* @return <#return value description#>
*/
- (id _Nonnull) fetchObjectsWithClass:(Class _Nonnull) class;
/**
* <#Description#>
*
@@ -32,6 +41,15 @@
*/
- (id _Nonnull) saveLocally:(id _Nonnull) object;
/**
* <#Description#>
*
* @param object <#object description#>
*
* @return <#return value description#>
*/
- (id _Nonnull) saveNSUSerDefautls:(id _Nonnull) object;
/**
* <#Description#>
*
@@ -41,6 +59,6 @@
*/
- (BOOL) removeObjectLocally:(id _Nonnull) object;
- (id _Nonnull) fetchObjectsWithClass:(Class _Nonnull) class;
@end
+209 -204
View File
@@ -27,251 +27,256 @@ static bool isFirstAccess = YES;
+ (instancetype) sharedInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
isFirstAccess = NO;
SINGLETON = [[super allocWithZone:NULL] init];
});
return SINGLETON;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
isFirstAccess = NO;
SINGLETON = [[super allocWithZone:NULL] init];
});
return SINGLETON;
}
- (NSString * _Nullable) objectName:(id _Nonnull) object {
BOOL isPNObjectSubclass = [[object class] isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
if ([[object class] conformsToProtocol:@protocol(PNObjectSubclassing)]) {
NSString *className;
//if ([[object subClassDelegate] respondsToSelector:@selector(objectClassName)]) {
@try {
className = (NSString *)[[object class] performSelector:@selector(objectClassName)];
}
@catch (NSException *exception) {
return nil;
}
@finally {
return className;
}
//}
}
}
return nil;
BOOL isPNObjectSubclass = [[object class] isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
if ([[object class] conformsToProtocol:@protocol(PNObjectSubclassing)]) {
NSString *className;
//if ([[object subClassDelegate] respondsToSelector:@selector(objectClassName)]) {
@try {
className = (NSString *)[[object class] performSelector:@selector(objectClassName)];
}
@catch (NSException *exception) {
return nil;
}
@finally {
return className;
}
//}
}
}
return nil;
}
- (BOOL) issetPNObjectModelForObject:(id _Nonnull) object {
NSString *className = [self objectName:object];
if (!className) {
return NO;
}
return [_fileManager checkPath:className];
NSString *className = [self objectName:object];
if (!className) {
return NO;
}
return [_fileManager checkPath:className];
}
#pragma mark -
+ (id) allocWithZone:(NSZone *)zone
{
return [self sharedInstance];
return [self sharedInstance];
}
+ (id)copyWithZone:(struct _NSZone *)zone
{
return [self sharedInstance];
return [self sharedInstance];
}
+ (id)mutableCopyWithZone:(struct _NSZone *)zone
{
return [self sharedInstance];
return [self sharedInstance];
}
- (id)copy
{
return [[PNObjectModel alloc] init];
return [[PNObjectModel alloc] init];
}
- (id)mutableCopy
{
return [[PNObjectModel alloc] init];
return [[PNObjectModel alloc] init];
}
- (id) init
{
if(SINGLETON){
return SINGLETON;
}
if (isFirstAccess) {
[self doesNotRecognizeSelector:_cmd];
}
self = [super init];
if (self) {
_fileManager = [PEARFileManager sharedInstatnce];
[_fileManager setRootDirectory:k_ROOT_DIR_DOCUMENTS];
NSLogDebug(@"%@",[_fileManager getRootDirectoryPath]);
}
return self;
if(SINGLETON){
return SINGLETON;
}
if (isFirstAccess) {
[self doesNotRecognizeSelector:_cmd];
}
self = [super init];
if (self) {
_fileManager = [PEARFileManager sharedInstatnce];
[_fileManager setRootDirectory:k_ROOT_DIR_DOCUMENTS];
NSLogDebug(@"%@",[_fileManager getRootDirectoryPath]);
}
return self;
}
#pragma mark Public Methods
- (id _Nonnull) fetchObjectsWithClass:(Class _Nonnull) class {
BOOL isPNObjectSubclass = [class isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
NSString *className;
@try {
className = (NSString *)[class performSelector:@selector(objectClassName)];
}
@catch (NSException *exception) {
}
@finally {
if ([_fileManager checkPath:className]) {
return [NSKeyedUnarchiver unarchiveObjectWithData:[_fileManager fetchFileDataWithPath:className]];
}
else
return nil;
}
}
BOOL isPNObjectSubclass = [class isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
NSString *className;
@try {
className = (NSString *)[class performSelector:@selector(objectClassName)];
}
@catch (NSException *exception) {
}
@finally {
if ([_fileManager checkPath:className]) {
return [NSKeyedUnarchiver unarchiveObjectWithData:[_fileManager fetchFileDataWithPath:className]];
}
else
return nil;
}
}
}
- (id _Nonnull) saveLocally:(id _Nonnull) object {
BOOL isPNObjectSubclass = [[object class] isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
if ([[object class] conformsToProtocol:@protocol(PNObjectSubclassing)]) {
if ([(PNObject*) object singleInstance]) {
SEL selector = NSSelectorFromString(@"getJSONObject");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:object];
[invocation invoke];
NSDictionary *objectDict;
[invocation getReturnValue:&objectDict];
NSLogDebug(@"%@",objectDict);
NSData *objectData = [NSKeyedArchiver archivedDataWithRootObject:objectDict];
if ([self issetPNObjectModelForObject:object]) {
if ([_fileManager updateFileWithData:objectData filePath:[self objectName:object] permisson:@(0755)]) {
return object;
}
else {
return [NSError errorWithDomain:NSLocalizedString(@"Object cannot be updated", @"") code:kHTTPStatusCodeBadRequest userInfo:nil];
}
}
else {
if ([_fileManager createFileWithData:objectData filePath:[self objectName:object] permisson:@(0755)]) {
return object;
}
else {
return [NSError errorWithDomain:NSLocalizedString(@"Object cannot be created", @"") code:kHTTPStatusCodeBadRequest userInfo:nil];
}
}
}
else {
if ([self issetPNObjectModelForObject:object]) {
NSData * data = [_fileManager fetchFileDataWithPath:[self objectName:object]];
NSMutableArray *objects = [[NSMutableArray alloc] initWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:data]];
SEL selector = NSSelectorFromString(@"getJSONObject");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:object];
[invocation invoke];
NSDictionary *objectDict;
[invocation getReturnValue:&objectDict];
NSLogDebug(@"%@",objectDict);
[objects addObject:objectDict];
NSData *objectData = [NSKeyedArchiver archivedDataWithRootObject:objects];
if ([_fileManager updateFileWithData:objectData filePath:[self objectName:object] permisson:@(0755)]) {
return objects;
}
else {
return [NSError errorWithDomain:NSLocalizedString(@"Objects list cannot be updated", @"") code:kHTTPStatusCodeBadRequest userInfo:nil];
}
}
else {
NSMutableArray *objects = [[NSMutableArray alloc] init];
SEL selector = NSSelectorFromString(@"getJSONObject");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:object];
[invocation invoke];
NSDictionary *objectDict;
[invocation getReturnValue:&objectDict];
NSLogDebug(@"%@",objectDict);
[objects addObject:objectDict];
NSData *objectData = [NSKeyedArchiver archivedDataWithRootObject:objects];
if ([_fileManager createFileWithData:objectData filePath:[self objectName:object] permisson:@(0755)]) {
return object;
}
else {
return [NSError errorWithDomain:NSLocalizedString(@"Objects list cannot be created", @"") code:kHTTPStatusCodeBadRequest userInfo:nil];
}
}
}
}
else {
return [NSError errorWithDomain:NSLocalizedString(@"passed object is not conform to protocol PNObjectSubclassing", @"") code:kHTTPStatusCodeBadRequest userInfo:nil];
}
}
else {
return [NSError errorWithDomain:NSLocalizedString(@"passed object is not PNObject Subclass", @"") code:kHTTPStatusCodeBadRequest userInfo:nil];
}
BOOL isPNObjectSubclass = [[object class] isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
if ([[object class] conformsToProtocol:@protocol(PNObjectSubclassing)]) {
if ([(PNObject*) object singleInstance]) {
SEL selector = NSSelectorFromString(@"getJSONObject");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:object];
[invocation invoke];
NSDictionary *objectDict;
[invocation getReturnValue:&objectDict];
NSLogDebug(@"%@",objectDict);
NSData *objectData = [NSKeyedArchiver archivedDataWithRootObject:objectDict];
if ([self issetPNObjectModelForObject:object]) {
if ([_fileManager updateFileWithData:objectData filePath:[self objectName:object] permisson:@(0755)]) {
return object;
}
else {
return [NSError errorWithDomain:NSLocalizedString(@"Object cannot be updated", @"") code:kHTTPStatusCodeBadRequest userInfo:nil];
}
}
else {
if ([_fileManager createFileWithData:objectData filePath:[self objectName:object] permisson:@(0755)]) {
return object;
}
else {
return [NSError errorWithDomain:NSLocalizedString(@"Object cannot be created", @"") code:kHTTPStatusCodeBadRequest userInfo:nil];
}
}
}
else {
if ([self issetPNObjectModelForObject:object]) {
NSData * data = [_fileManager fetchFileDataWithPath:[self objectName:object]];
NSMutableArray *objects = [[NSMutableArray alloc] initWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:data]];
SEL selector = NSSelectorFromString(@"getJSONObject");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:object];
[invocation invoke];
NSDictionary *objectDict;
[invocation getReturnValue:&objectDict];
NSLogDebug(@"%@",objectDict);
[objects addObject:objectDict];
NSData *objectData = [NSKeyedArchiver archivedDataWithRootObject:objects];
if ([_fileManager updateFileWithData:objectData filePath:[self objectName:object] permisson:@(0755)]) {
return objects;
}
else {
return [NSError errorWithDomain:NSLocalizedString(@"Objects list cannot be updated", @"") code:kHTTPStatusCodeBadRequest userInfo:nil];
}
}
else {
NSMutableArray *objects = [[NSMutableArray alloc] init];
SEL selector = NSSelectorFromString(@"getJSONObject");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[PNObject class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:object];
[invocation invoke];
NSDictionary *objectDict;
[invocation getReturnValue:&objectDict];
NSLogDebug(@"%@",objectDict);
[objects addObject:objectDict];
NSData *objectData = [NSKeyedArchiver archivedDataWithRootObject:objects];
if ([_fileManager createFileWithData:objectData filePath:[self objectName:object] permisson:@(0755)]) {
return object;
}
else {
return [NSError errorWithDomain:NSLocalizedString(@"Objects list cannot be created", @"") code:kHTTPStatusCodeBadRequest userInfo:nil];
}
}
}
}
else {
return [NSError errorWithDomain:NSLocalizedString(@"passed object is not conform to protocol PNObjectSubclassing", @"") code:kHTTPStatusCodeBadRequest userInfo:nil];
}
}
else {
return [NSError errorWithDomain:NSLocalizedString(@"passed object is not PNObject Subclass", @"") code:kHTTPStatusCodeBadRequest userInfo:nil];
}
}
- (id _Nonnull) saveNSUSerDefautls:(id _Nonnull) object {
}
- (BOOL) removeObjectLocally:(id _Nonnull) object {
BOOL isPNObjectSubclass = [[object class] isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
if ([[object class] conformsToProtocol:@protocol(PNObjectSubclassing)]) {
if ([self issetPNObjectModelForObject:object]) {
return [_fileManager deletePath:[self objectName:object]];
}
}
}
return NO;
BOOL isPNObjectSubclass = [[object class] isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
if ([[object class] conformsToProtocol:@protocol(PNObjectSubclassing)]) {
if ([self issetPNObjectModelForObject:object]) {
return [_fileManager deletePath:[self objectName:object]];
}
}
}
return NO;
}
@end
-16
View File
@@ -1,16 +0,0 @@
//
// PNObjectProperty.h
// Pods
//
// Created by Giuseppe Nucifora on 28/12/15.
//
//
#import <Foundation/Foundation.h>
#import "PNObject.h"
@interface PNObjectProperty : NSObject
+ (NSDictionary *)propertiesForClass:(Class)PNObjClass;
@end
-84
View File
@@ -1,84 +0,0 @@
//
// PNObjectProperty.m
// Pods
//
// Created by Giuseppe Nucifora on 28/12/15.
//
//
#import "PNObjectProperty.h"
#import "objc/runtime.h"
#import "PNObjectConstants.h"
#import "PNObject+Protected.h"
@implementation PNObjectProperty
static BOOL property_getTypeString( objc_property_t property, char *buffer )
{
const char * attrs = property_getAttributes( property );
if ( attrs == NULL )
return NO;
const char * e = strchr( attrs, ',' );
if ( e == NULL )
return NO;
int len = (int)(e - attrs);
memcpy( buffer, attrs, len );
buffer[len] = '\0';
return YES;
}
+ (NSDictionary *)propertiesForClass:(Class)PNObjClass
{
if (PNObjClass == NULL) {
return nil;
}
NSMutableDictionary *results = [NSMutableDictionary dictionary];
if ([PNObjClass isSubclassOfClass:[PNObject class]] && PNObjClass != [PNObject class]) {
[results addEntriesFromDictionary:[self propertiesForClass:[PNObject class]]];
}
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(PNObjClass, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
//const char *propType = getPropertyType(property);
char propType[256];
if (!property_getTypeString(property, propType)) {
continue;
}
NSString *propertyName = [NSString stringWithUTF8String:propName];
NSString *propertyType = [NSString stringWithUTF8String:propType];
NSRange range = [propertyType rangeOfString:@"T@\""];
NSRange range2 = [propertyType rangeOfString:@"T"];
if (range.location != NSNotFound) {
NSRange subStrRange = NSMakeRange(range.length, propertyType.length - (range.length + 1));
propertyType = [propertyType substringWithRange:subStrRange];
}
else if (range2.location != NSNotFound) {
NSRange subStrRange = NSMakeRange(range2.length, propertyType.length - (range2.length));
propertyType = [propertyType substringWithRange:subStrRange];
}
//NSLogDebug(@"Prop type & name: %@ -- %@", propertyType, propertyName);
if (![[PNObject protectedProperties] containsObject:propertyName]) {
[results setObject:propertyType forKey:propertyName];
}
}
}
free(properties);
// returning a copy here to make sure the dictionary is immutable
return [NSDictionary dictionaryWithDictionary:results];
}
@end
-23
View File
@@ -1,23 +0,0 @@
//
// PNAddress.h
// Pods
//
// Created by Giuseppe Nucifora on 13/01/16.
//
//
#import "PNObject.h"
#import "PNLocation.h"
@interface PNAddress : PNObject <PNObjectSubclassing>
@property (nonatomic, strong) NSString * _Nullable country;
@property (nonatomic, strong) NSString * _Nullable province;
@property (nonatomic, strong) NSString * _Nullable city;
@property (nonatomic, strong) NSString * _Nullable street;
@property (nonatomic, strong) NSNumber * _Nullable number;
@property (nonatomic, strong) NSString * _Nullable zip;
@property (nonatomic, strong) NSString * _Nullable istruction;
@property (nonatomic, strong) PNLocation * _Nullable location;
@end
-45
View File
@@ -1,45 +0,0 @@
//
// PNUser.h
// Pods
//
// Created by Giuseppe Nucifora on 15/01/16.
//
//
#import "PNObject.h"
@interface PNUser : PNObject
@property (strong, nonatomic) NSString * _Nonnull userId;
@property (strong, nonatomic) NSString * _Nonnull firstName;
@property (strong, nonatomic) NSString * _Nonnull lastName;
@property (nonatomic, strong) UIImage * _Nullable profileImage;
@property (nonatomic, strong) NSString * _Nullable sex;
@property (nonatomic, strong) NSDate * _Nullable birthDate;
@property (nonatomic, strong) NSString * _Nullable phone;
@property (nonatomic) BOOL hasAcceptedPrivacy;
@property (nonatomic) BOOL hasAcceptedNewsletter;
@property (nonatomic) BOOL hasVerifiedEmail;
@property (nonatomic, strong) NSDate * _Nullable emailVerifiedDate;
@property (nonatomic, strong) NSString * _Nonnull email;
@property (nonatomic, strong) NSString * _Nonnull username;
@property (nonatomic, strong) NSString * _Nonnull password;
@property (nonatomic) BOOL publicProfile;
@property (nonatomic, strong) NSNumber * _Nonnull loginCount;
@property (nonatomic, strong) NSString * _Nullable facebookId;
@property (nonatomic, strong) NSString * _Nullable facebookAccessToken;
/**
* gets singleton object of current user session.
*
* @return singleton
*/
+ (instancetype _Nonnull) currentUser;
- (BOOL) isValidPassword:(NSString* _Nonnull) password;
//- (void) setPassword:(NSString * _Nonnull)password inBackGroundWithBlock:(nullable void (^)(BOOL saveStatus, id _Nullable responseObject, NSError * _Nullable error)) responseBlock;
@end
-161
View File
@@ -1,161 +0,0 @@
//
// PNUser.m
// Pods
//
// Created by Giuseppe Nucifora on 15/01/16.
//
//
#import "PNUser.h"
#import "NSString+Helper.h"
#import "PNObjectConstants.h"
#import "PNObject+Protected.h"
@interface PNUser() <PNObjectSubclassing>
@end
@implementation PNUser
@synthesize password = _password;
static PNUser *SINGLETON = nil;
static bool isFirstAccess = YES;
#pragma mark - Public Method
+ (instancetype)sharedInstance
{
return [self currentUser];
}
+ (instancetype) currentUser {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
isFirstAccess = NO;
SINGLETON = [[super allocWithZone:NULL] init];
});
return SINGLETON;
}
#pragma mark - Life Cycle
+ (instancetype) allocWithZone:(NSZone *)zone
{
return [self sharedInstance];
}
+ (instancetype)copyWithZone:(struct _NSZone *)zone
{
return [self sharedInstance];
}
+ (instancetype)mutableCopyWithZone:(struct _NSZone *)zone
{
return [self sharedInstance];
}
- (instancetype)copy
{
return [[PNUser alloc] init];
}
- (instancetype)mutableCopy
{
return [[PNUser alloc] init];
}
- (id) init
{
if(SINGLETON){
return SINGLETON;
}
if (isFirstAccess) {
[self doesNotRecognizeSelector:_cmd];
}
NSDictionary *savedUser = [[PNObjectModel sharedInstance] fetchObjectsWithClass:[self class]];
if (savedUser) {
self = [super initWithJSON:savedUser];
}
else {
self = [super init];
}
if (self) {
}
return self;
}
- (void) setEmail:(NSString *)email {
if ([email isValidEmail]) {
_email = email;
}
NSLogDebug(@"insertedEmail is not valid.");
}
- (void) setPassword:(NSString *)password {
if ([password length] >= [[PNObjectConfig sharedInstance] minPasswordLenght]) {
_password = password;
}
else {
NSLogDebug(@"Inserted Passord is not valid.Lenght must be >= %ld",(long)[[PNObjectConfig sharedInstance] minPasswordLenght]);
}
}
- (BOOL) isValidPassword:(NSString* _Nonnull) password {
if ([password length] >= [[PNObjectConfig sharedInstance] minPasswordLenght]) {
return YES;
}
return NO;
}
- (NSString *) password {
return @"password is not readble";
}
#pragma mark PNObjectSubclassing Protocol
+ (NSDictionary *)objcetMapping {
NSDictionary *mapping = @{
@"userId":@"id",
@"firstName":@"firstName",
@"lastName":@"lastName",
@"profileImage":@"profileImage",
@"sex":@"sex",
@"birthDate":@"birthDate",
@"phone":@"phone",
@"password":@"password",
@"hasAcceptedPrivacy":@"hasAcceptedPrivacy",
@"hasAcceptedNewsletter":@"hasAcceptedNewsletter",
@"hasVerifiedEmail":@"hasVerifiedEmail",
@"emailVerifiedDate":@"emailVerifiedDate",
@"email":@"email",
@"username":@"username",
@"publicProfile":@"public_profile",
@"loginCount":@"login_count",
@"facebookId":@"facebookId",
@"facebookAccessToken":@"facebookAccessToken",
};
return mapping;
}
+ (NSString *)objectClassName {
return @"User";
}
+ (BOOL) singleInstance {
return YES;
}
#pragma mark -
@end