PNObject/Pod/Classes/PNObjectModel.m
2016-01-26 00:29:37 +01:00

278 lines
8.7 KiB
Objective-C

//
// PNObjectModel.m
// Pods
//
// Created by Giuseppe Nucifora on 16/01/16.
//
//
#import "PNObjectModel.h"
#import "PNObject+Protected.h"
#import "PEARFileManager.h"
#import "PNObjectConstants.h"
@interface PNObjectModel()
@property (nonatomic, strong) PEARFileManager *fileManager;
@end
@implementation PNObjectModel
static PNObjectModel *SINGLETON = nil;
static bool isFirstAccess = YES;
#pragma mark Public Method
+ (instancetype) sharedInstance
{
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)]) {
NSLogDebug(@"%@",[object subClassDelegate]);
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];
}
#pragma mark -
+ (id) allocWithZone:(NSZone *)zone
{
return [self sharedInstance];
}
+ (id)copyWithZone:(struct _NSZone *)zone
{
return [self sharedInstance];
}
+ (id)mutableCopyWithZone:(struct _NSZone *)zone
{
return [self sharedInstance];
}
- (id)copy
{
return [[PNObjectModel alloc] init];
}
- (id)mutableCopy
{
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];
}
return self;
}
- (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;
}
}
}
- (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(@"getObject");
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(@"getObject");
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(@"getObject");
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) removeObjectAndSaveLocally:(id _Nonnull) object {
BOOL isPNObjectSubclass = [[object class] isSubclassOfClass:[PNObject class]];
if(isPNObjectSubclass) {
if ([[object class] conformsToProtocol:@protocol(PNObjectSubclassing)]) {
if ([(PNObject*) object singleInstance]) {
}
}
}
}
@end