Skip to content

Instantly share code, notes, and snippets.

@jgongo
Last active December 14, 2015 10:59
Show Gist options
  • Save jgongo/5075937 to your computer and use it in GitHub Desktop.
Save jgongo/5075937 to your computer and use it in GitHub Desktop.
Creation of simple Core Data stack using Typhoon 1.1.2
#import "Assembly+CoreData.h"
#import <Typhoon/Typhoon.h>
#import <CoreData/CoreData.h>
#pragma mark NSPersistentStoreCoordinator configuration
@interface NSPersistentStoreCoordinator (InjectedConfiguration)
- (void)configureStoreCoordinatorUsingDefaultComponentFactory;
- (void)configureStoreCoordinatorUsingDefaultComponentFactoryWithLightweightMigration;
@end
@implementation NSPersistentStoreCoordinator (InjectedConfiguration)
- (void)configureStoreCoordinatorUsingDefaultComponentFactory
{
NSURL *storeURL = [[TyphoonComponentFactory defaultFactory] componentForKey:@"storeURL"];
[self addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:nil];
}
- (void)configureStoreCoordinatorUsingDefaultComponentFactoryWithLightweightMigration
{
NSURL *storeURL = [[TyphoonComponentFactory defaultFactory] componentForKey:@"storeURL"];
[self addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:@{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES} error:nil];
}
@end
#pragma mark - Assembly Core Data stack definition
@implementation Assembly (CoreData)
#pragma mark Managed object model creation
- (id)mainBundle
{
return [TyphoonDefinition withClass:[NSBundle class] initialization:^(TyphoonInitializer *initializer) {
initializer.selector = @selector(mainBundle);
}];
}
- (id)modelURL
{
return [TyphoonDefinition withClass:[NSBundle class] initialization:^(TyphoonInitializer *initializer) {
initializer.selector = @selector(URLForResource:withExtension:);
[initializer injectParameterAt:0 withValueAsText:@"model" requiredTypeOrNil:[NSString class]];
[initializer injectParameterAt:1 withValueAsText:@"momd" requiredTypeOrNil:[NSString class]];
} properties:^(TyphoonDefinition *definition) {
definition.factory = [self mainBundle];
}];
}
- (id)managedObjectModel
{
return [TyphoonDefinition withClass:[NSManagedObjectModel class] initialization:^(TyphoonInitializer *initializer) {
initializer.selector = @selector(initWithContentsOfURL:);
[initializer injectParameterAtIndex:0 withDefinition:[self modelURL]];
}];
}
#pragma mark Persistent store coordinator creation
- (id)fileManager
{
return [TyphoonDefinition withClass:[NSFileManager class] initialization:^(TyphoonInitializer *initializer) {
initializer.selector = @selector(defaultManager);
}];
}
- (id)applicationDocumentsDirectories
{
return [TyphoonDefinition withClass:[NSArray class] initialization:^(TyphoonInitializer *initializer) {
initializer.selector = @selector(URLsForDirectory:inDomains:);
[initializer injectParameterAt:0 withValueAsText:@"9" requiredTypeOrNil:nil]; // NSDocumentDirectory
[initializer injectParameterAt:1 withValueAsText:@"1" requiredTypeOrNil:nil]; // NSUserDomainMask
} properties:^(TyphoonDefinition *definition) {
definition.factory = [self fileManager];
}];
}
- (id)applicationDocumentsDirectory
{
return [TyphoonDefinition withClass:[NSURL class] initialization:^(TyphoonInitializer *initializer) {
initializer.selector = @selector(lastObject);
} properties:^(TyphoonDefinition *definition) {
definition.factory = [self applicationDocumentsDirectories];
}];
}
- (id)storeURL
{
return [TyphoonDefinition withClass:[NSURL class] initialization:^(TyphoonInitializer *initializer) {
initializer.selector = @selector(URLByAppendingPathComponent:);
[initializer injectParameterAt:0 withValueAsText:@"database.sqlite" requiredTypeOrNil:[NSString class]];
} properties:^(TyphoonDefinition *definition) {
definition.factory = [self applicationDocumentsDirectory];
}];
}
- (id)persistentStoreCoordinator
{
return [TyphoonDefinition withClass:[NSPersistentStoreCoordinator class] initialization:^(TyphoonInitializer *initializer) {
initializer.selector = @selector(initWithManagedObjectModel:);
[initializer injectParameterAtIndex:0 withDefinition:[self managedObjectModel]];
} properties:^(TyphoonDefinition *definition) {
definition.afterPropertyInjection = @selector(configureStoreCoordinatorUsingDefaultComponentFactory);
}];
}
#pragma mark Managed object context creation
- (id)managedObjectContext
{
return [TyphoonDefinition withClass:[NSManagedObjectContext class] properties:^(TyphoonDefinition *definition) {
[definition injectProperty:@selector(persistentStoreCoordinator) withDefinition:[self persistentStoreCoordinator]];
definition.scope = TyphoonScopeSingleton;
}];
}
@end
@jasperblues
Copy link

Note that you don't have to use componentForKey with the block assembly. You can just do this:

Assembly* assembly = [TyphoonComponentFactory defaultFactory];
NSURL* url = [assembly storeURL];

This isn't shown in the sample app, in order to remain compatible with XML style. . . (I should change this).

@jasperblues
Copy link

NB2: If you're injecting parameters in the order they're defined, you don't need to use the index. Just

[initiliazer injectWith]

@sidorchick
Copy link

Have tested your solutions with Typhoon 1.1.4 and discovered two issues:

  1. persistentStoreCoordinator for managedObjectContext should be set with afterPropertyInjection, because method injection is forbidden.
  2. configureStoreCoordinatorUsingDefaultComponentFactory throws exception:
    Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** setObjectForKey: object cannot be nil (key: NSStoreModelVersionIdentifiers)'

José, could you help me with the second issue because I have really no idea how to fix it

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment