Created
March 5, 2013 20:42
-
-
Save jonnolen/5094081 to your computer and use it in GitHub Desktop.
PSPDFAnnotationProvider implementation backed by core data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// UserCoreDataAnnotationProvider.m | |
// BoardRoom | |
// | |
// Created by Jonathan Nolen on 3/2/13. | |
// | |
// | |
#import "UserCoreDataAnnotationProvider.h" | |
#import "Annotation.h" | |
#import "CachedAnnotation.h" | |
@interface UserCoreDataAnnotationProvider() | |
@property (nonatomic, strong) NSMutableDictionary *pageCache; | |
@property (nonatomic, strong) Packet *packet; | |
@property (nonatomic, strong) NSString *username; | |
@end | |
@implementation UserCoreDataAnnotationProvider | |
@synthesize providerDelegate; | |
+(UserCoreDataAnnotationProvider *)coreDataAnnotationProviderWithPacket:(Packet *)packet andUser:(NSString *)username{ | |
UserCoreDataAnnotationProvider *result = [self new]; | |
result.packet = packet; | |
result.username = username; | |
return result; | |
} | |
-(id)init{ | |
if (self = [super init]){ | |
_pageCache = [NSMutableDictionary dictionaryWithCapacity:1]; | |
} | |
return self; | |
} | |
-(BOOL)addAnnotations:(NSArray *)annotations forPage:(NSUInteger)page{ | |
__block BOOL supportsAllAnnotations = YES; | |
[annotations enumerateObjectsUsingBlock:^(PSPDFAnnotation *annotation, NSUInteger indx, BOOL *stop){ | |
if ((annotation.type & [self supportedTypes]) != annotation.type){ | |
*stop = YES; | |
supportsAllAnnotations = NO; | |
return; | |
} | |
}]; | |
if (!supportsAllAnnotations){ | |
return NO; | |
} | |
[annotations enumerateObjectsUsingBlock:^(PSPDFAnnotation *annotation, NSUInteger idx, BOOL *stop){ | |
Annotation *coreDataAnnotation = [self saveAnnotation:annotation]; | |
CachedAnnotation *cachedAnnotation = [CachedAnnotation cachedAnnotationWithObjectId:coreDataAnnotation.objectID nativeAnnotation:annotation]; | |
[self cacheAnnotationToProperPage:cachedAnnotation]; | |
}]; | |
return YES; | |
} | |
-(Annotation *)saveAnnotation:(PSPDFAnnotation *)annotation{ | |
Annotation *result = [Annotation MR_createEntity]; | |
result.packet = self.packet; | |
result.username = self.username; | |
result.page = @(annotation.page); | |
result.annotationJson = [[annotation externalRepresentationInFormat:PSPDFModelJSONFormat] JSONString]; | |
[result.managedObjectContext MR_saveOnlySelfAndWait]; | |
annotation.dirty = NO; | |
return result; | |
} | |
-(void)cacheAnnotationToProperPage:(CachedAnnotation *)annotation{ | |
NSMutableSet *pageAnnotations = [self pageCacheForPage:annotation.annotation.page]; | |
[pageAnnotations addObject:annotation]; | |
} | |
- (NSArray *)annotationsForPage:(NSUInteger)page{ | |
NSMutableSet *annotationsForPage = [self pageCacheForPage:page]; | |
return [annotationsForPage valueForKey:@"annotation"]; | |
} | |
-(NSMutableSet *)pageCacheForPage:(NSUInteger)page{ | |
NSMutableSet *pageAnnotations = nil; | |
@synchronized(self){ | |
if (self.pageCache[@(page)]){ | |
pageAnnotations = self.pageCache[@(page)]; | |
} | |
else{ | |
//get core data annotations for page. | |
NSArray *coreDataAnnotations = [self coreDataAnnotationsForPage:page]; | |
pageAnnotations = [NSMutableSet setWithCapacity:coreDataAnnotations.count]; | |
//for each core data annotation, create the CacheAnnotation object and add it to pageAnnotations. | |
[coreDataAnnotations enumerateObjectsUsingBlock:^(Annotation *annotation, NSUInteger idx, BOOL *stop){ | |
[pageAnnotations addObject:[CachedAnnotation cachedAnnotationWithCoreDataAnnotation:annotation]]; | |
}]; | |
self.pageCache[@(page)] = pageAnnotations; | |
} | |
} | |
return pageAnnotations; | |
} | |
-(CachedAnnotation *)cachedAnnotationForNativeAnnotation:(PSPDFAnnotation *)nativeAnnotation{ | |
NSSet *annnotationsForNativeAnnotationPage = self.pageCache[@(nativeAnnotation.page)]; | |
CachedAnnotation *cachedAnnotation = [[annnotationsForNativeAnnotationPage objectsPassingTest:^(CachedAnnotation *ca, BOOL *stop){ | |
return (BOOL)(ca.annotation == nativeAnnotation); | |
}] anyObject]; | |
return cachedAnnotation; | |
} | |
-(NSArray *)coreDataAnnotationsForPage:(NSUInteger)page{ | |
NSFetchRequest *fetchAnnotationsForUserInPacketForPage = [Annotation | |
MR_requestAllWithPredicate:[NSPredicate | |
predicateWithFormat:@"packet == %@ AND username == %@ and page == %@", | |
self.packet, | |
self.username, | |
@(page)]]; | |
return [Annotation MR_executeFetchRequest:fetchAnnotationsForUserInPacketForPage]; | |
} | |
- (void) didChangeAnnotation:(PSPDFAnnotation *)annotation originalAnnotation:(PSPDFAnnotation *)originalAnnotation keyPaths:(NSArray *)keyPaths options:(NSDictionary *)options{ | |
CachedAnnotation *cachedAnnotation = [self cachedAnnotationForNativeAnnotation:annotation]; | |
if (cachedAnnotation){ | |
Annotation *coreDataAnnotation = (Annotation *)[[NSManagedObjectContext MR_contextForCurrentThread] objectWithID:cachedAnnotation.objectId]; | |
if ([keyPaths[0] isEqualToString:@"isDeleted"]){ | |
[coreDataAnnotation MR_deleteEntity]; | |
[self deleteAnnotation:cachedAnnotation]; | |
} | |
else{ | |
NSError *error = nil; | |
NSDictionary *jsonRepresentation = [annotation externalRepresentationInFormat:PSPDFModelJSONFormat]; | |
[jsonRepresentation enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){ | |
NSLog(@"key class/value: %@/%@, obj class/value: %@/%@", [key class], key, [obj class], obj); | |
}]; | |
coreDataAnnotation.annotationJson = [[annotation externalRepresentationInFormat:PSPDFModelJSONFormat] JSONStringWithOptions:JKSerializeOptionNone error:&error]; | |
if (error){ | |
NSLog(@"%@", error); | |
} | |
} | |
[coreDataAnnotation.managedObjectContext MR_saveOnlySelfWithCompletion:nil]; | |
annotation.dirty = NO; | |
} | |
} | |
-(void)deleteAnnotation:(CachedAnnotation *)cachedAnnotation{ | |
[self.pageCache[@(cachedAnnotation.annotation.page)] removeObject:cachedAnnotation]; | |
} | |
-(NSDictionary *)dirtyAnnotations{ | |
return @{}; | |
} | |
-(BOOL)hasLoadedAnnotationsForPage:(NSUInteger)page{ | |
return (self.pageCache[@(page)] != nil); | |
} | |
-(BOOL)saveAnnotationsWithError:(NSError *__autoreleasing *)error{ | |
return YES; | |
} | |
-(PSPDFAnnotationType)supportedTypes{ | |
return (PSPDFAnnotationTypeHighlight | | |
PSPDFAnnotationTypeInk | | |
PSPDFAnnotationTypeNote ); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment