Browse files

manual merge

  • Loading branch information...
2 parents b04da5f + a602205 commit 8b9db9cf60974017549bf99febd98958d191fc7e @drewcrawford committed Apr 23, 2013
View
10 CoreDataHelp.xcodeproj/project.pbxproj
@@ -76,6 +76,9 @@
3A803D821520057B007D0B62 /* NSManagedObject+DCAAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A803D801520057B007D0B62 /* NSManagedObject+DCAAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
3A803D831520057B007D0B62 /* NSManagedObject+DCAAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A803D811520057B007D0B62 /* NSManagedObject+DCAAdditions.m */; };
3A803D8415201D0E007D0B62 /* DCACacheFirstIncrementalStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A803D50151FC7A3007D0B62 /* DCACacheFirstIncrementalStore.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 3A84839316D61E4B00927A33 /* NSManagedObject+CDHRepo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A84839116D61E4B00927A33 /* NSManagedObject+CDHRepo.h */; };
+ 3A84839416D61E4B00927A33 /* NSManagedObject+CDHRepo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A84839216D61E4B00927A33 /* NSManagedObject+CDHRepo.m */; };
+ 3A84839B16D620A900927A33 /* NSManagedObject+CDHRepo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A84839116D61E4B00927A33 /* NSManagedObject+CDHRepo.h */; settings = {ATTRIBUTES = (Public, ); }; };
3ACBFA391568C1A700CCD332 /* NSThreadWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3ACBFA371568C1A700CCD332 /* NSThreadWrapper.h */; };
3ACBFA3A1568C1A700CCD332 /* NSThreadWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 3ACBFA381568C1A700CCD332 /* NSThreadWrapper.m */; };
3AF76D5A170EAA20000B02A9 /* FutureLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A49EF8916CC84DE00B4B147 /* FutureLite.m */; };
@@ -151,6 +154,8 @@
3A803D7D152004F1007D0B62 /* DCAFetchRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DCAFetchRequest.m; sourceTree = "<group>"; };
3A803D801520057B007D0B62 /* NSManagedObject+DCAAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+DCAAdditions.h"; sourceTree = "<group>"; };
3A803D811520057B007D0B62 /* NSManagedObject+DCAAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+DCAAdditions.m"; sourceTree = "<group>"; };
+ 3A84839116D61E4B00927A33 /* NSManagedObject+CDHRepo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+CDHRepo.h"; sourceTree = "<group>"; };
+ 3A84839216D61E4B00927A33 /* NSManagedObject+CDHRepo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+CDHRepo.m"; sourceTree = "<group>"; };
3ACBFA371568C1A700CCD332 /* NSThreadWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSThreadWrapper.h; sourceTree = "<group>"; };
3ACBFA381568C1A700CCD332 /* NSThreadWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSThreadWrapper.m; sourceTree = "<group>"; };
BE38A4EC1521340A005AE1E8 /* CoreDataStack+Singleton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CoreDataStack+Singleton.h"; sourceTree = "<group>"; };
@@ -301,6 +306,8 @@
3A49EF8E16CC8E2500B4B147 /* RegistryObserverProtocol.h */,
3A49EF9F16CCD89000B4B147 /* FutureRegistry.h */,
3A49EFA016CCD89000B4B147 /* FutureRegistry.m */,
+ 3A84839116D61E4B00927A33 /* NSManagedObject+CDHRepo.h */,
+ 3A84839216D61E4B00927A33 /* NSManagedObject+CDHRepo.m */,
);
name = AdrenalineLite;
sourceTree = "<group>";
@@ -334,6 +341,7 @@
3A49EF9516CC8F8800B4B147 /* NSFetchRequest+CDH.h in Headers */,
3A49EF9A16CCCE8100B4B147 /* NSManagedObject+ExternalStorage.h in Headers */,
3A49EFA216CCD89000B4B147 /* FutureRegistry.h in Headers */,
+ 3A84839B16D620A900927A33 /* NSManagedObject+CDHRepo.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -363,6 +371,7 @@
3A49EF9316CC8F6B00B4B147 /* NSFetchRequest+CDH.h in Headers */,
3A49EF9916CCCE8100B4B147 /* NSManagedObject+ExternalStorage.h in Headers */,
3A49EFA116CCD89000B4B147 /* FutureRegistry.h in Headers */,
+ 3A84839316D61E4B00927A33 /* NSManagedObject+CDHRepo.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -522,6 +531,7 @@
3A49EF9416CC8F6B00B4B147 /* NSFetchRequest+CDH.m in Sources */,
3A49EF9B16CCCE8100B4B147 /* NSManagedObject+ExternalStorage.m in Sources */,
3A49EFA316CCD89000B4B147 /* FutureRegistry.m in Sources */,
+ 3A84839416D61E4B00927A33 /* NSManagedObject+CDHRepo.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
66 CoreDataHelp/CDHRepo.h
@@ -8,6 +8,7 @@
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
+@class CoreDataStack;
typedef void(^operationBlock)();
@interface CDHRepo : NSObject
@@ -18,6 +19,37 @@ typedef void(^operationBlock)();
/**Initializes the repository with documents storage. Provide a file name (no path) in which the repository should be saved. This type of store should not be used to store sensitive data. */
- (CDHRepo*) initWithDocumentsStorage:(NSString*) fileName;
+/**Initializes the repository with incremental store storage. */
+
+- (CDHRepo *)initWithIncrementalStoreClass:(Class)incrementalStore configuration:(NSString*)configuration URL:(NSURL*) url options:(NSDictionary*) options;
+
+/**This creates a (new) CoreDataStack for backwards compatability interop with CDHRepo. This allows you to do a staggered migration of your code.
+
+ "Under the hood", this stack is a sibling of the receiver. Changes in one are not reflected in the other without explicit fault semantics. If this bothers you, I recommend you migrate more code.
+
+ 1. You probably want to hang onto this pointer in some capacity rather than create new ones all the time.
+ 2. CDHRepo and CoreDataStack objects can't interact. For one thing, the confinement pattern is totally different, so it is difficult to work out when objects under two sets of rules are both legal. For another thing, it just plain isn't supported. You can get some small amount of interop with backwardsCompatabilityVersion:inStack: so that you can stagger your migration.
+
+ @warning this isn't supported for non-root repos. I have no idea what it will do.
+
+ */
+
+-(CoreDataStack*) newBackwardsCompatabilityStack;
+
+/**This allows very limited migration for an object between the Stack and Repo worlds.
+
+ @param object a repo-based object. The object must be valid at the time this is called according to the CDHRepo confinement rules.
+ @param stack the stack to which you want to port the object
+ @return An object that is valid on the MAIN THREAD in the CoreDataStack. It is okay to call this function from not-the-main-thread, but the return value cannot be used for any purpose until you arrive on the main thread.
+
+ Consider using performBlockAndReturnOnMain to call this function.
+
+ @warning this function is provided only for backwards compatability reasons. It is very slow as it aquires a large number of locks.
+
+ */
+
+-(id) backwardsCompatabilityVersion:(NSManagedObject*) object inStack:(CoreDataStack*) stack;
+-(NSArray*) backwardsCompatabilityVersions:(NSArray*) objects inStack:(CoreDataStack*) stack;
/**
ALL CDH OBJECTS MUST BE ACCESSED INSIDE A BLOCK! IF YOU ACCESS OBJECTS OUTSIDE THEIR BLOCK THIS PRODUCES **UNDEFINED** BEHAVIOR. **UNDEFINED** MEANS **UNDEFINED**. WE COULD PLAY PONG.
@@ -28,27 +60,16 @@ typedef void(^operationBlock)();
You *may* **copy** fundamental types (strings, NSNumbers, and collections containing only these) which are then "ordinary" objects that are usable from any thread. This strategy might make sense if you are going to do something that takes a long time (like read in a large file that is specified by the CoreData object) and don't want other queries to be stopped in their tracks in the meantime. (You can also run long operations against a separate CDHRepo that's been forked off the main repo; this is probably faster in some situations.)
- Note that BY DESIGN THESE BLOCKS ARE ASYNCHRONOUS, and there is NO WAY to make them syncronous. Attempts to do so by lock, mutex, semaphore, hook, crook, or even my own guide for making things synchronous (http://sealedabstract.com/uncategorized/roll-your-own-dispatch_sync/) are NOT SUPPORTED and WILL CAUSE DEADLOCKS EVEN IF IT WORKS SOMETIMES ON THE SIMULATOR.
+ Note that BY DESIGN THESE BLOCKS ARE ASYNCHRONOUS, and there is NO WAY to make them syncronous. Attempts to do so by lock, mutex, semaphore, hook, crook, or even my own guide for making things synchronous (http://sealedabstract.com/uncategorized/roll-your-own-dispatch_sync/) are NOT SUPPORTED and WILL CAUSE DEADLOCKS EVEN IF IT WORKS SOMETIMES ON THE SIMULATOR. If you want a synchronous version, check out performBlockAndWait__DISPATCH_SYNC_TO_MAIN_IS_NOW_FORBIDDEN__.
*/
-(void) performBlock:(operationBlock) b;
-/** This is purely semantic sugar around
-
- [repo performBlock:^{
- dispatch_sync(dispatch_get_main_thread(),^{
- //something
- });
- }];
-
- Your block runs on the main thread eventually but NOT IMMEDIATELY.
+/**This is like performBlock, but it waits for the operation to complete. You **MAY NOT** dispatch_sync onto the main thread inside this block. It's recommdended that you not use this method unless absolutely necessary.
- Also, see the BIG FREAKING WARNING on performBlock:
+ You **MAY NOT** call this method from the main thread, or a queue that was joined to the main thread (e.g. via dispatch_sync). You should only call this method from a background queue.
*/
--(void) performBlockAndReturnOnMain:(operationBlock) b;
-
-/**Okay, I lied. There is a way to make it synchronous. The thing is, you can't touch the main thread with this. Ever. */
--(void) performOnBlockAndWait__MAIN__IS__FORBIDDEN__:(operationBlock) b;
+-(void) performBlockAndWait__DISPATCH_SYNC_TO_MAIN_IS_NOW_FORBIDDEN__:(operationBlock) b;
/**This function must be run from a block. */
- (NSArray *)executeFetchRequest:(NSFetchRequest *)fetchRequest err:(NSError**) err;
@@ -60,18 +81,27 @@ typedef void(^operationBlock)();
-(id) objectWithObjectID:(NSManagedObjectID*) obj;
+/**Marks the object as deleted. The object is not actually deleted until the repository is saved.
+ After the repository is saved, the objects attributes/relationships/values are undefined. */
+-(void) deleteObject:(NSManagedObject*) obj;
+
+#ifdef CAFFEINE_IOS_IS_AVAILABLE
+- (NSArray*) arrayWithOpaqueResult:(CaffeineOpaqueResult*) opaqueResult;
+#endif
+
/**This drops the object from ram.
@warning it's a bug to call this on an object with unsaved changes. */
-(void) fault:(NSManagedObject*) obj;
-/**Deletes the object from the repo.*/
--(void) deleteManagedObject:(NSManagedObject*) object;
-
+ (CDHRepo *)rootRepo;
+ (void) setRootRepo:(CDHRepo*) root;
+/**@section private*/
+
+//these methods are not to be used
++(CDHRepo*) repoLookupWithMoc:(NSManagedObjectContext*) moc;
@end
View
103 CoreDataHelp/CDHRepo.m
@@ -7,8 +7,20 @@
//
#import "CDHRepo.h"
-#import <DCAKit/NSError+LessTerrible.h>
+#import <DCAKit/DCAKit.h>
+#import "CoreDataStack.h"
+#import "CoreDataHelpError.h"
+#import "NSManagedObject+CDHRepo.h"
static CDHRepo *rootRepo;
+static NSMapTable *reposByMoc;
+
+
+#ifdef CAFFEINE_IOS_IS_AVAILABLE
+@protocol DontCoupleWithCaffeineProtocol
+- (NSArray*) arrayWithOpaqueResult:(CaffeineOpaqueResult*) opaqueResult;
+@end
+#endif
+
@interface CDHRepo() {
NSManagedObjectContext *_moc;
NSPersistentStoreCoordinator *_psc;
@@ -18,19 +30,30 @@ @interface CDHRepo() {
@implementation CDHRepo
#pragma mark initializers
-- (CDHRepo *)initWithBlackholeStorage {
+
+- (id)init {
if (self = [super init]) {
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ reposByMoc = [NSMapTable weakToWeakObjectsMapTable];
+ });
+ }
+ return self;
+}
+- (CDHRepo *)initWithBlackholeStorage {
+ if (self = [self init]) {
_psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:[NSBundle allBundles]]];
NSError *err = nil;
[_psc addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:&err];
if (err) [err present];
_moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
+ reposByMoc[_moc] = self;
}
return self;
}
- (CDHRepo*) initWithDocumentsStorage:(NSString*) fileName {
- if (self = [super init]) {
+ if (self = [self init]) {
_psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:[NSBundle allBundles]]];
NSString *documentsdirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSURL *url = [NSURL fileURLWithPath:[documentsdirectory stringByAppendingPathComponent:fileName]];
@@ -39,10 +62,32 @@ - (CDHRepo*) initWithDocumentsStorage:(NSString*) fileName {
if (err) [err present];
_moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_moc setPersistentStoreCoordinator:_psc];
+ reposByMoc[_moc] = self;
+
}
return self;
}
+- (CDHRepo *)initWithIncrementalStoreClass:(Class)incrementalStore configuration:(NSString*)configuration URL:(NSURL*) url options:(NSDictionary*) options {
+ if (self = [self init]) {
+ _psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:[NSBundle allBundles]]];
+ [NSPersistentStoreCoordinator registerStoreClass:incrementalStore forStoreType:NSStringFromClass(incrementalStore)];
+ NSError *err = nil;
+ [_psc addPersistentStoreWithType:NSStringFromClass(incrementalStore) configuration:configuration URL:url options:options error:&err];
+ if (err) [err present];
+ _moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
+ [_moc setPersistentStoreCoordinator:_psc];
+ reposByMoc[_moc] = self;
+ }
+ return self;
+}
+
+-(CoreDataStack*) newBackwardsCompatabilityStack {
+ return [CoreDataStack stackWithPersistentStoreCoordinator:_psc];
+
+}
+
+
#pragma mark threading
-(void) internalReallyPerformBlock:(operationBlock) b {
@@ -57,7 +102,11 @@ -(void) internalPerformBlock:(operationBlock) b {
}];
}
--(void) performOnBlockAndWait__MAIN__IS__FORBIDDEN__:(operationBlock)b {
+-(void) performBlockAndWait__DISPATCH_SYNC_TO_MAIN_IS_NOW_FORBIDDEN__:(operationBlock)b {
+ if ([NSThread isMainThread]) {
+ NSError *err = [CoreDataHelpError errorWithCode:CDHErrorCodeDeprecated format:@"You're calling performBlockAndWait__DISPATCH_SYNC_TO_MAIN_IS_NOW_FORBIDDEN__ on the main thread, which is known to cause deadlocks. This will crash in a future release."];
+ [err present];
+ }
[_moc performBlockAndWait:^{
[self internalReallyPerformBlock:b];
}];
@@ -69,17 +118,10 @@ -(void) performBlock:(operationBlock) b {
}];
}
--(void) performBlockAndReturnOnMain:(operationBlock) b {
- [self internalPerformBlock:^{
- dispatch_sync(dispatch_get_main_queue(), ^{
- b();
- });
- }];
-}
-
#pragma mark ops
- (NSArray *)executeFetchRequest:(NSFetchRequest *)fetchRequest err:(NSError**) err{
+ NSAssert(err, @"Err is not optional.");
NSAssert(threading_looks_okay, @"Try inside a block.");
id result = [_moc executeFetchRequest:fetchRequest error:err];
if (*err) [*err present];
@@ -103,12 +145,39 @@ - (id)insertInstanceOfClass:(Class)c {
return [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass(c) inManagedObjectContext:_moc];
}
--(void) deleteManagedObject:(NSManagedObject*) object {
+- (void)deleteObject:(NSManagedObject *)obj {
NSAssert(threading_looks_okay, @"Try doing this inside a block.");
- [_moc deleteObject:object];
+ NSAssert(obj.repo==self, @"Object didn't come from this repo.");
+ [_moc deleteObject:obj];
}
+#ifdef CAFFEINE_IOS_IS_AVAILABLE
+- (NSArray*) arrayWithOpaqueResult:(CaffeineOpaqueResult*) opaqueResult {
+ NSAssert(threading_looks_okay, @"Try doing this inside a block.");
+ id<DontCoupleWithCaffeineProtocol> caffeinableContext = (id<DontCoupleWithCaffeineProtocol>) _moc;
+ return [caffeinableContext arrayWithOpaqueResult:opaqueResult];
+}
+#endif
+
+- (NSManagedObject *)backwardsCompatabilityVersion:(NSManagedObject *)object inStack:(CoreDataStack *)stack {
+ __block NSManagedObject *mainThreadObj = nil;
+ [stack backgroundOperationSync:^{
+ NSManagedObject *obj = [stack objectOnCurrentThreadFromID:object.objectID];
+ mainThreadObj = [stack objectOnMainThread:obj];
+ }];
+ return mainThreadObj;
+
+}
+
+- (NSArray *)backwardsCompatabilityVersions:(NSArray *)objects inStack:(CoreDataStack *)stack {
+ NSMutableArray *newVersions = [[NSMutableArray alloc] initWithCapacity:objects.count];
+ for(NSManagedObject *obj in objects) {
+ [newVersions addObject:[self backwardsCompatabilityVersion:obj inStack:stack]];
+ }
+ return newVersions;
+}
+
- (void)fault:(NSManagedObject *)obj {
NSAssert(!obj.hasChanges, @"Bug. Don't fault things with changes.");
[_moc refreshObject:obj mergeChanges:NO];
@@ -124,5 +193,11 @@ + (void) setRootRepo:(CDHRepo*) root {
rootRepo = root;
}
+#pragma mark private
+
+
++ (CDHRepo *)repoLookupWithMoc:(NSManagedObjectContext *)moc {
+ return reposByMoc[moc];
+}
@end
View
1 CoreDataHelp/CoreDataHelp.h
@@ -22,6 +22,7 @@
#import <CoreDataHelp/RegistryObserverProtocol.h>
#import <CoreDataHelp/NSFetchRequest+CDH.h>
#import <CoreDataHelp/NSManagedObject+ExternalStorage.h>
+#import <CoreDataHelp/NSManagedObject+CDHRepo.h>
void objc_retain(id x);
#define WORK_AROUND_RDAR_10732696(X) objc_retain(X)
View
3 CoreDataHelp/CoreDataHelpError.h
@@ -13,7 +13,8 @@ static const NSString *CDHErrorDomain __attribute__((used)) = @"com.dca.CoreData
typedef enum {
CDHErrorCodeNotSupported,
CDHErrorCodeHTTP,
- CDHErrorCacheTooOld
+ CDHErrorCacheTooOld,
+ CDHErrorCodeDeprecated
} CDHErrorCode;
View
2 CoreDataHelp/CoreDataHelpError.m
@@ -14,6 +14,6 @@ + (NSError *)errorWithCode:(CDHErrorCode)code format:(NSString *)format, ... {
va_start(args,format);
NSString *errorStr = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
- return [NSError errorWithDomain:(NSString*) CDHErrorDomain code:code userInfo:[NSDictionary dictionaryWithObject:errorStr forKey:@"errorString"]];
+ return [NSError errorWithDomain:(NSString*) CDHErrorDomain code:code userInfo:[NSDictionary dictionaryWithObject:errorStr forKey:NSLocalizedFailureReasonErrorKey]];
}
@end
View
1 CoreDataHelp/CoreDataStack.h
@@ -20,6 +20,7 @@
+ (CoreDataStack*) onDiskStack;
+ (CoreDataStack*) incrementalStoreStack:(Class) autoInstallableIncrementalStore;
+ (CoreDataStack*) incrementalStoreStackWithClass:(Class) nsIncrementalStoreClass model:(NSManagedObjectModel*) model configuration:(NSString*) configuration url:(NSURL*) url options:(NSDictionary*) options caching:(BOOL) caching;
++ (CoreDataStack*) stackWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator*) coordinator;
- (id) executeFetchRequest:(NSFetchRequest*) fetchRequest err:(NSError * __autoreleasing *) err;
- (id) insertNewObjectOfClass:(Class) c;
View
8 CoreDataHelp/CoreDataStack.m
@@ -153,6 +153,14 @@ + (CoreDataStack*) incrementalStoreStack:(Class) autoInstallableIncrementalStore
return stack;
}
++ (CoreDataStack*) stackWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator*) coordinator {
+ CoreDataStack *stack = [[CoreDataStack alloc] init];
+ stack->managedObjectModel = coordinator.managedObjectModel;
+ stack->persistentStoreCoordinator = coordinator;
+ [stack installManagedObjectContexts];
+ return stack;
+}
+
+ (CoreDataStack*) incrementalStoreStackWithClass:(Class) nsIncrementalStoreClass model:(NSManagedObjectModel*) model configuration:(NSString*) configuration url:(NSURL*) url options:(NSDictionary*) options caching:(BOOL) caching{
CoreDataStack *stack = [[CoreDataStack alloc] init];
stack->managedObjectModel = model;
View
13 CoreDataHelp/NSManagedObject+CDHRepo.h
@@ -0,0 +1,13 @@
+//
+// NSManagedObject+CDHRepo.h
+// CoreDataHelp
+//
+// Created by Drew Crawford on 2/21/13.
+//
+//
+
+#import <CoreData/CoreData.h>
+@class CDHRepo;
+@interface NSManagedObject (CDHRepo)
+-(CDHRepo*) repo;
+@end
View
15 CoreDataHelp/NSManagedObject+CDHRepo.m
@@ -0,0 +1,15 @@
+//
+// NSManagedObject+CDHRepo.m
+// CoreDataHelp
+//
+// Created by Drew Crawford on 2/21/13.
+//
+//
+
+#import "NSManagedObject+CDHRepo.h"
+#import "CDHRepo.h"
+@implementation NSManagedObject (CDHRepo)
+- (CDHRepo *)repo {
+ return [CDHRepo repoLookupWithMoc:self.managedObjectContext];
+}
+@end
View
13 README.md
@@ -0,0 +1,13 @@
+# Installation
+
+add CDH as a submodule
+
+ git submodule add git@github.com:drewcrawford/CoreDataHelp.git CoreDataHelp
+
+DCAKit must be installed in a sibling directory
+
+ git submodule add git@github.com:drewcrawford/DCAKit.git DCAKit
+
+Link your parent project against both DCAKit and CDH.
+
+Ensure that your configurations are duplicated appropriately to DCAKit and CDH.
View
BIN develop-environment/ios-sim
Binary file not shown.
View
1 readme.txt
@@ -1 +0,0 @@
-This is completely out of date... I need to do a better writeup of our internal doc at https://github.com/drewcrawford/DrewCrawfordApps/wiki/XCode-libraries---schemes---buildbot,-how-does-it-work that explains how this installed.

0 comments on commit 8b9db9c

Please sign in to comment.