2012-04-15 4 views
0

Ich versuche CLLocation Manager zu verwenden, um den Standort von jemandem zu erhalten, wenn sie den lat, lng und timestamp in die Kerndaten verschieben und speichern, und dann in einer tabellarischen Ansicht anzeigen. Allerdings zeigt die Ausgabe in der Konsole immer, dass managedObjectContext ist nill durch dieses Protokoll werfen coredataproject[12478:11903] After managedObjectContext: <NSManagedObjectContext: 0x7248230>Warum kommt mein managedObjectContext zurück?

Hier ist der relevante Code in meiner AppDelgate Implementierungsdatei

#import "AppDelegate.h" 
#import "RootViewController.h" 
#import "FirstViewController.h" 



@implementation AppDelegate 

@synthesize window; 
@synthesize navigationController; 


#pragma mark - 
#pragma mark Application lifecycle 

- (void)applicationDidFinishLaunching:(UIApplication *)application { 

    // Configure and show the window. 

    RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain]; 

    NSManagedObjectContext *context = [self managedObjectContext]; 
    if (!context) { 
     NSLog(@"Could not create context for self"); 
    } 
    rootViewController.managedObjectContext = context; 

    UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; 
    self.navigationController = aNavigationController; 

    [window addSubview:[navigationController view]]; 
    [window makeKeyAndVisible]; 


} 

/** 
applicationWillTerminate: saves changes in the application's managed object context before the application terminates. 
*/ 
- (void)applicationWillTerminate:(UIApplication *)application { 

    NSError *error; 
    if (managedObjectContext != nil) { 
     if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { 
      // Handle the error. 
     } 
    } 
} 

Hier wird der FirstViewController.M Code, wo ich bin die Lage bekommen und es in den Stammdaten ‚Ereignis‘ Einheit

- (void)viewDidLoad 
{ 


    locationManager =[[CLLocationManager alloc] init]; 

    locationManager.delegate = self; 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
    locationManager.distanceFilter = kCLDistanceFilterNone; 
    [locationManager startUpdatingLocation]; 


-(void) locationmanager: (CLLocationManager *) manager 
     didUpdateToLocation: (CLLocation *) newLocation 
     fromLocation: (CLLocation *) oldLocation 
{ 


    CLLocation *location = [locationManager location]; 
    if (!location) { 
     return; 
    } 

    /* 
    Create a new instance of the Event entity. 
    */ 
    RootViewController *rootviewcontroller = [RootViewController alloc];  
    Event *event = (Event *)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:rootviewcontroller.managedObjectContext]; 

    // Configure the new event with information from the location. 
    CLLocationCoordinate2D coordinate = [location coordinate]; 
    [event setLatitude:[NSNumber numberWithDouble:coordinate.latitude]]; 
    [event setLongitude:[NSNumber numberWithDouble:coordinate.longitude]]; 



    // Should be the location's timestamp, but this will be constant for simulator. 
    // [event setCreationDate:[location timestamp]]; 
    [event setTimeStamp:[NSDate date]]; 

    // Commit the change. 
    NSError *error; 

    if (![rootviewcontroller.managedObjectContext save:&error]) { 
     NSLog(@"Save Error"); 
    } 

    //RootViewController *rootviewcontroller = [RootViewController alloc]; 
    [rootviewcontroller.eventsArray insertObject:event atIndex:0]; 
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; 
    [rootviewcontroller.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
    [rootviewcontroller.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

} 

und schließlich ist hier die RootViewController Datei zu speichern, wo ich zu holen und anzuzeigen bin versucht, was in den Kerndaten ist. Es ist, wenn ich dieses Register, das die Konsole mir sagt, dass managedObjectConsole

- (void)viewDidLoad { 

[super viewDidLoad]; 

if (managedObjectContext == nil) 
{ 
    managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
    NSLog(@"After managedObjectContext: %@", managedObjectContext); 
}  
// Set the title. 
self.title = @"Locations"; 

/* 
Fetch existing events. 
Create a fetch request; find the Event entity and assign it to the request; add a sort descriptor; then execute the fetch. 
*/ 
NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext]; 
[request setEntity:entity]; 

// Order the events by time stamp, most recent first. 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO]; 
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
[request setSortDescriptors:sortDescriptors]; 


// Execute the fetch -- create a mutable copy of the result. 
NSError *error = nil; 
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy]; 
if (mutableFetchResults == nil) { 
    NSLog(@"Mutable Fetch Results equals nill"); 
} 

// Set self's events array to the mutable array, then clean up. 
[self setEventsArray:mutableFetchResults]; 

nill ist}

Ich bin auch bei der Organisation der Tabellendaten etwas mehr Sachen zu tun, wenn es da ist, aber ich glaube nicht, da ist das Problem.

Ich bin mir nicht sicher, warum nichts in managedObjectContext sein würde, da es die Standortdaten vom Standortmanager haben sollte. Ich bin mit Core-Daten nicht so vertraut, also mache ich wahrscheinlich einfach etwas falsches, aber jede Einsicht wäre willkommen!

+0

Warum erstellen Sie einen neuen RootViewController jedes Mal, wenn der Standort aktualisiert wird ??? – Felix

+0

Es ist nur zum Testen im Moment. Ich werde es zu einem Entfernungsfilter von ungefähr 20 Metern ändern, wenn es tatsächlich anfängt zu arbeiten. – michael03m

+0

Und ich brauche keinen neuen RootViewController, ich brauche ihn nur, um einen neuen Speicherort über CoreData an RootViewController zu senden. – michael03m

Antwort

1

Ihr Fehler ist in der DidUpdateToLocation-Methode. Dort erstellen Sie eine neue Instanz von RootViewController. Sie müssen den newLocation nur in CoreData speichern und benötigen dazu den MOC (nicht den RootViewController). Sie müssen also eine Möglichkeit finden, die MOC an den FirstViewController zu übergeben. Sie können diese ähnlich tun wie Sie in den AppDelegate oder wie dies tun:

managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 

Warum Sie die MOC von RootViewController in viewDidLoad zurücksetzen? Sie haben es bereits in applicationDidFinishLaunching übergeben!

Ich würde empfehlen, eine NSFetchedResultsController für die Tabellenansicht zu verwenden. Es erkennt automatisch Änderungen an den Daten und lädt die Tabelle bei Bedarf neu. Implementieren Sie den Delegierten einfach korrekt. Hier ist ein hilfreiches Tutorial dazu: http://www.raywenderlich.com/999/core-data-tutorial-how-to-use-nsfetchedresultscontroller

+0

Danke! Das bringt mich auf den richtigen Weg. – michael03m