Skip to content

Instantly share code, notes, and snippets.

@brentsimmons
Last active August 29, 2015 13:56
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brentsimmons/9283338 to your computer and use it in GitHub Desktop.
Save brentsimmons/9283338 to your computer and use it in GitHub Desktop.
//
// VSTagAuthority.m
// Vesper
//
// Created by Brent Simmons on 2/28/14.
// Copyright (c) 2014 Q Branch LLC. All rights reserved.
//
#import "VSTagAuthority.h"
#import "VSTag.h"
@interface VSTagAuthority ()
@property (nonatomic, readonly) NSManagedObjectContext *context;
@property (nonatomic, readonly) NSMutableDictionary *tagIDs;
@end
@implementation VSTagAuthority
#pragma mark - Init
- (instancetype)initWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator *)storeCoordinator {
NSParameterAssert(storeCoordinator != nil);
self = [super init];
if (!self) {
return nil;
}
_context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_context setPersistentStoreCoordinator:storeCoordinator];
[_context setUndoManager:nil];
NSAssert(_context != nil, nil);
_tagIDs = [NSMutableDictionary new];
[self fetchTags];
return self;
}
#pragma mark - Tag Cache
- (void)fetchTags {
[self.context performBlock:^{
NSArray *allTags = [VSTag allObjects:self.context];
for (VSTag *oneTag in allTags) {
NSString *oneClientID = oneTag.clientID; /*clientID is the unique ID for tag.*/
NSAssert(oneClientID != nil, nil);
self.tagIDs[oneClientID] = [oneTag objectID];
}
}];
}
#pragma mark - API
- (VSTag *)existingTagWithName:(NSString *)name context:(NSManagedObjectContext *)context {
NSParameterAssert(name != nil && [name length] > 0);
NSParameterAssert(context != nil);
__block NSManagedObjectID *objectID = nil;
[self.context performBlockAndWait:^{
NSString *clientID = [VSTag clientIDForTagName:name];
objectID = self.tagIDs[clientID];
NSAssert(![objectID isTemporaryID], nil);
}];
if (objectID) {
return (VSTag *)[context objectWithID:objectID];
}
return nil;
}
- (VSTag *)tagWithName:(NSString *)name context:(NSManagedObjectContext *)context error:(NSError **)error {
NSParameterAssert(name != nil && [name length] > 0);
NSParameterAssert(context != nil);
__block NSManagedObjectID *objectID = nil;
[self.context performBlockAndWait:^{
NSString *clientID = [VSTag clientIDForTagName:name];
objectID = self.tagIDs[clientID];
if (!objectID) {
VSTag *tag = [VSTag insertObject:self.context];
tag.name = name;
tag.clientID = clientID;
if ([self.context save:error]) {
objectID = [tag objectID];
NSAssert(![objectID isTemporaryID], nil); /*Just saved -- should be permanent.*/
self.tagIDs[clientID] = objectID;
}
else {
NSLog(@"Error inserting tag: %@", *error);
}
}
}];
if (objectID) {
return (VSTag *)[context objectWithID:objectID];
}
return nil;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment