2012-07-20 7 views
1

J'ai essayé d'intégrer Core Data à une application storyboard qui commence par le contrôleur de vue standard mais le didacticiel que je suis utilise une barre d'onglets comme vue initiale.L'application Core Data se bloque au démarrage

Existe-t-il un moyen de démarrer l'application avec le contrôleur de vue initial, puis d'appliquer la barre d'onglets dans le délégué de l'application? Le didacticiel utilise le délégué de l'application pour implémenter les données principales et utilise le contrôleur de la barre d'onglets comme vue initiale.

est ici l'application delegate.h

#import <UIKit/UIKit.h> 
#import <CoreData/CoreData.h> 

@interface AppDelegate : UIResponder <UIApplicationDelegate> 

@property (strong, nonatomic) UIWindow *window; 

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; 
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; 
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; 
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController; 

- (void)saveContext; 
- (NSURL *)applicationDocumentsDirectory; 

@end 

et voici le fichier delegate.m app

#import "AppDelegate.h" 

#import "PersonsTVC.h" 
#import "RolesTVC.h" 

@implementation AppDelegate 

@synthesize window = _window; 
@synthesize managedObjectContext = __managedObjectContext; 
@synthesize managedObjectModel = __managedObjectModel; 
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator; 
@synthesize fetchedResultsController = __fetchedResultsController; 

- (void)insertRoleWithRoleName:(NSString *)roleName 
{ 
Role *role = [NSEntityDescription insertNewObjectForEntityForName:@"Role" 
               inManagedObjectContext:self.managedObjectContext]; 

role.name = roleName; 

[self.managedObjectContext save:nil]; 
} 

- (void)importCoreDataDefaultRoles { 

NSLog(@"Importing Core Data Default Values for Roles..."); 
[self insertRoleWithRoleName:@"C/C++ Developer"]; 
[self insertRoleWithRoleName:@"Obj-C Developer"]; 
[self insertRoleWithRoleName:@"Java Developer"]; 
[self insertRoleWithRoleName:@"ASP.NET Developer"]; 
[self insertRoleWithRoleName:@"Unix Engineer"]; 
[self insertRoleWithRoleName:@"Windows Engineer"]; 
[self insertRoleWithRoleName:@"Business Analyst"]; 
[self insertRoleWithRoleName:@"Infrastructure Manager"]; 
[self insertRoleWithRoleName:@"Project Manager"]; 
[self insertRoleWithRoleName:@"Operations Manager"]; 
[self insertRoleWithRoleName:@"Desktop Support Analyst"]; 
[self insertRoleWithRoleName:@"Chief Information Officer"]; 
NSLog(@"Importing Core Data Default Values for Roles Completed!"); 
} 
- (void)setupFetchedResultsController 
{ 
// 1 - Decide what Entity you want 
NSString *entityName = @"Role"; // Put your entity name here 
NSLog(@"Setting up a Fetched Results Controller for the Entity named %@", entityName); 

// 2 - Request that Entity 
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName]; 

// 3 - Filter it if you want 
//request.predicate = [NSPredicate predicateWithFormat:@"Person.name = Blah"]; 

// 4 - Sort it if you want 
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" 
                       ascending:YES 
                        selector:@selector(localizedCaseInsensitiveCompare:)]]; 
// 5 - Fetch it 
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request 
                    managedObjectContext:self.managedObjectContext 
                     sectionNameKeyPath:nil 
                       cacheName:nil]; 
[self.fetchedResultsController performFetch:nil]; 
} 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
[self setupFetchedResultsController]; 

if (![[self.fetchedResultsController fetchedObjects] count] > 0) { 
    NSLog(@"!!!!! ~~> There's nothing in the database so defaults will be inserted"); 
    [self importCoreDataDefaultRoles]; 
} 
else { 
    NSLog(@"There's stuff in the database so skipping the import of default data");  
} 

// The Tab Bar 
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController; 

// The Two Navigation Controllers attached to the Tab Bar (At Tab Bar Indexes 0 and 1) 
UINavigationController *personsTVCnav = [[tabBarController viewControllers] objectAtIndex:0]; 
UINavigationController *rolesTVCnav = [[tabBarController viewControllers] objectAtIndex:1]; 

// The Persons Table View Controller (First Nav Controller Index 0) 
PersonsTVC *personsTVC = [[personsTVCnav viewControllers] objectAtIndex:0]; 
personsTVC.managedObjectContext = self.managedObjectContext;  

// The Roles Table View Controller (Second Nav Controller Index 0) 
RolesTVC *rolesTVC = [[rolesTVCnav viewControllers] objectAtIndex:0]; 
rolesTVC.managedObjectContext = self.managedObjectContext; 

//NOTE: Be very careful to change these indexes if you change the tab order 

// Override point for customization after application launch. 
// UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController; 
// RolesTVC *controller = (RolesTVC *)navigationController.topViewController; 
// controller.managedObjectContext = self.managedObjectContext; 
return YES; 
} 

- (void)applicationWillResignActive:(UIApplication *)application 
{ 
/* 
Sent when the application is about to move from active to inactive state. This can occur  for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 
*/ 
} 

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
/* 
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 
*/ 
} 

- (void)applicationWillEnterForeground:(UIApplication *)application 
{ 
/* 
Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 
*/ 
} 

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
/* 
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 
*/ 
} 

- (void)applicationWillTerminate:(UIApplication *)application 
{ 
// Saves changes in the application's managed object context before the application terminates. 
[self saveContext]; 
} 

- (void)saveContext 
{ 
NSError *error = nil; 
NSManagedObjectContext *managedObjectContext = self.managedObjectContext; 
if (managedObjectContext != nil) 
{ 
    if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) 
    { 
     /* 
     Replace this implementation with code to handle the error appropriately. 

     abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
     */ 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 
} 
} 

#pragma mark - Core Data stack 

/** 
Returns the managed object context for the application. 
If the context doesn't already exist, it is created and bound to the persistent store 
coordinator for the application. 
*/ 
- (NSManagedObjectContext *)managedObjectContext 
{ 
if (__managedObjectContext != nil) 
{ 
    return __managedObjectContext; 
} 

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
if (coordinator != nil) 
{ 
    __managedObjectContext = [[NSManagedObjectContext alloc] init]; 
    [__managedObjectContext setPersistentStoreCoordinator:coordinator]; 
} 
return __managedObjectContext; 
} 

/** 
Returns the managed object model for the application. 
If the model doesn't already exist, it is created from the application's model. 
*/ 
- (NSManagedObjectModel *)managedObjectModel 
{ 
if (__managedObjectModel != nil) 
{ 
    return __managedObjectModel; 
} 
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"]; 
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 
return __managedObjectModel; 
} 

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
{ 
if (__persistentStoreCoordinator != nil) 
{ 
    return __persistentStoreCoordinator; 
} 

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"StaffManager.sqlite"]; 

NSError *error = nil; 
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 


NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
         [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
         [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) 
{ 
    /* 
    Replace this implementation with code to handle the error appropriately. 

    abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 

    Typical reasons for an error here include: 
    * The persistent store is not accessible; 
    * The schema for the persistent store is incompatible with current managed object model. 
    Check the error message to determine what the actual problem was. 


    If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory. 

    If you encounter schema incompatibility errors during development, you can reduce their frequency by: 
    * Simply deleting the existing store: 
    [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil] 

    * Performing automatic lightweight migration by passing the following dictionary as the options parameter: 
    [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 

    Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details. 

    */ 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
}  

return __persistentStoreCoordinator; 
} 

#pragma mark - Application's Documents directory 


- (NSURL *)applicationDocumentsDirectory 
{ 
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 
} 

@end 

Comme vous pouvez le voir, je suis en train d'ajouter les données de base à mon application story-board . Dans ce scénario, dans le délégué de l'application, j'ajoute le contrôleur de tabulation en tant que contrôleur de vue racine, puis j'ajoute des contrôleurs à la barre d'onglets.

J'aime ajouter une vue de début avant la barre d'onglets dans l'application déléguer, puis ajouter la barre d'onglets et ses contrôleurs respectifs par la suite.

J'ai essayé d'ajouter la barre d'onglets comme sous-vue, mais les objets gérés ne sont pas invoqués et l'application se bloque.

J'apprécie vraiment si des programmeurs plus expérimentés peuvent offrir de l'aide. Je peux envoyer un e-mail au projet si nécessaire ou télécharger des codes si nécessaire. Je suis dans le besoin de direction les gars et je suis très reconnaissant de toute aide que je reçois.

+1

Quel est le message d'erreur exact lorsqu'il se bloque? Sur quelle ligne s'écrase-t-il exactement? – Anna

Répondre

0

Eh bien, j'ai finalement compris. J'ai ajouté une vue secondaire à la barre en tant qu'enfant de la barre d'onglets et la définir comme première vue et cela fonctionne.