iOS核心数据:如何将后续记录添加到1:多个关系中的“多个”?

时间:2013-10-02 01:53:19

标签: ios core-data core-location

我正在编写一个GPS运行应用程序,我希望按“路径”存储多个位置或运行。 我在理解ORM风格DB的新概念时遇到了一些麻烦。 (我知道Core Data使用SQLLite作为底层机制,并不是真正的ORM,但除此之外..) 我有两个实体设置,'路径'和'位置',从路径>>带有级联删除的位置的'To-Many'关系,以及一个对删除无效的反转。

enter image description here enter image description here

我在做:

//SEND TO CORE DATA
        bdAppDelegate *appDelegate =
        [[UIApplication sharedApplication] delegate];

        NSManagedObjectContext *context =
        [appDelegate managedObjectContext];

        // get GPS lat/lng
        double lat = newLocation.coordinate.latitude;
        double lng = newLocation.coordinate.longitude;

        // insert Path
        Path *currentPathInfo = [NSEntityDescription insertNewObjectForEntityForName:@"Path" inManagedObjectContext:context];
        currentPathInfo.name = currentPathName;
        currentPathInfo.createddate =[NSDate date];

        // insert location/GPS point
        Location *currentPathLocation = [NSEntityDescription insertNewObjectForEntityForName:@"Location" inManagedObjectContext:context];
        currentPathLocation.lat = [NSNumber numberWithDouble:lat];
        currentPathLocation.lng = [NSNumber numberWithDouble:lng];

        // insert 'Location' relationship to 'Path'
        [currentPathInfo addLocationsObject:currentPathLocation];

        NSError *error;
        if (![context save:&error]) {
            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
        }

这是在初次启动时(按下按钮) 但是,如何继续添加更多与初始“路径”相关的“位置”,而不会因重复上述代码而继续添加更多“路径”?

在SQL中,我有一个PathID整数(标识),我将其用于“位置”表中的外键以插入位置...我正在断开连接......

2 个答案:

答案 0 :(得分:1)

创建关系的方法只有两种:

[currentPathInfo addLocationsObject:currentPathLocation];

currentPathLocation.path = currentPathInfo;

因此,您需要在某处使用ivar记住您的“currentPathInfo”,或者每次根据某种唯一标识符(如果您有的话)从核心数据中获取它。

答案 1 :(得分:0)

我不理解的是: 我需要做一个FetchRequest来检查Path是否存在,

- (NSArray *)checkIfPathExistsByName {
// check first if this path exists ..
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription
                                          entityForName:@"Path" inManagedObjectContext:context];
[request setEntity:entityDescription];

// Set WHERE clause
NSPredicate *predicate = [NSPredicate predicateWithFormat:
                          @"(name LIKE %@)", currentPathName];
[request setPredicate:predicate];

// sort
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"createdDate" ascending:NO];
[request setSortDescriptors:@[sortDescriptor]];

NSError *error;
NSArray *array = [context executeFetchRequest:request error:&error];
return array;

}我在locationManager委托中调用它

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

// check first if this path exists ..
NSArray *array;
array = [self checkIfPathExistsByName];

if (array == nil)
{
    // Deal with error...
}
else
{
    if (array.count == 0){
        // if exists, just add Locations
        [self startNewPathAndInsertFirstCoordinate:newLocation forPathName:currentPathName];
    }else{            
        // start new if doesn't exist
        Path *myPath = [array lastObject];
        [self insertNewCoordinate:newLocation forPath:myPath];
    }
}

} 在这里,如果它是一个新路径,我传递currentPathName& startNewPathAndInsertFirstCoordinate的位置,但如果它确实找到Path(array.count> 0)从数组中取出Path并将其传递给另一个名为InsertNewCoordinate的方法。在insertNewCoordinate中,因为我已经获取了Path,我可以在insert上设置位置与它的关系,如下所示:

- (void)insertNewCoordinate:(CLLocation *)newLocation forPath:(Path *)currentPath{

//SEND TO CORE DATA    
NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
NSLog(@"howRecent: %f\n",howRecent);    

// get GPS lat/lng
double lat = newLocation.coordinate.latitude;
double lng = newLocation.coordinate.longitude;

// insert location/GPS point
Location *currentPathLocation = [NSEntityDescription insertNewObjectForEntityForName:@"Location" inManagedObjectContext:context];
currentPathLocation.lat = [NSNumber numberWithDouble:lat];
currentPathLocation.lng = [NSNumber numberWithDouble:lng];

// insert 'Location' relationship to 'Path'
[currentPath addLocationObject:currentPathLocation];

NSError *error;
if (![context save:&error]) {
    NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}}

- (void)startNewPathAndInsertFirstCoordinate:(CLLocation *)newLocation forPathName:(NSString *)pathName {

NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
NSLog(@"howRecent: %f\n",howRecent);

if (abs(howRecent) < 35.0)
{
    //Location timestamp is within the last 15.0 seconds, let's use it!
    NSLog(@"horizontalAccuracy: %f\n",newLocation.horizontalAccuracy);
    if(newLocation.horizontalAccuracy < 85.0){
        //Location seems pretty accurate, let's use it!
        NSLog(@"latitude %+.6f, longitude %+.6f\n",
              newLocation.coordinate.latitude,
              newLocation.coordinate.longitude);
        NSLog(@"Horizontal Accuracy:%f", newLocation.horizontalAccuracy);

        //SEND TO CORE DATA

        // get GPS lat/lng
        double lat = newLocation.coordinate.latitude;
        double lng = newLocation.coordinate.longitude;

        // insert Path
        Path *currentPathInfo = [NSEntityDescription insertNewObjectForEntityForName:@"Path" inManagedObjectContext:context];
        currentPathInfo.name = currentPathName;
        currentPathInfo.createdDate =[NSDate date];

        // insert location/GPS point
        Location *currentPathLocation = [NSEntityDescription insertNewObjectForEntityForName:@"Location" inManagedObjectContext:context];
        currentPathLocation.lat = [NSNumber numberWithDouble:lat];
        currentPathLocation.lng = [NSNumber numberWithDouble:lng];

        // insert 'Location' relationship to 'Path'
        [currentPathInfo addLocationObject:currentPathLocation];

        NSError *error;
        if (![context save:&error]) {
            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
        }
    }
}
[self.locationManager startUpdatingLocation];

}