Reputation: 14768
I'm working on an old incredibly poorly written Objective-C app. The feature I'm working on involves taking different record types from core-data and sending them to a server. And one record type (A) has to be sent before another one (B) can be sent.
EDIT: A
refers to ActivitySession
objects and B
refers to ActivityRun
objects.
Here's the problem: somewhere in the app, there's some kind of listener deleting all of the B records after the A records are sent. I've spent a while trying to figure out where this is happening, but I've had no luck. My solution was to then just load all of the B records into memory before sending the A records (thinking even if the B records are deleted from core data, they will still exist in memory). But I'm finding after the B records are deleted from core data, my array of records are also being cleared.
Here is the meat of the logic I'm talking about:
__block NSArray* activityRuns = [coreData fetchByEntitiyName:@"ActivityRun"];
NSLog(@"---> Sending %@ students", @([students count]));
return [self sendStudents:students withApiKey:apiKey]
.then(^{
// This must happen before sending anything with activity references
NSLog(@"---> Fetching activities");
return [self fetchActivitiesWithApiKey:apiKey];
})
.then(^{
NSArray* data = [coreData fetchByEntitiyName:@"ActivitySession"];
NSLog(@"---> Sending %@ activity sessions", @([data count]));
return [self sendActivitySessions:data withApiKey:apiKey].catch(failLogger(@"Failed to upload activity sessions", nil));
})
.then(^{
NSLog(@"---> Sending %@ activity runs", @([activityRuns count]));
return [self sendActivityRuns:activityRuns withApiKey:apiKey].catch(failLogger(@"Failed to upload activity runs", nil));
})
activityRuns
is the in-memory data I'm trying to send (with [self sendActivityRuns:activityRuns withApiKey:apiKey]
). Here is how fetchByEntitiyName
is defined:
- (NSArray*) fetchByEntitiyName:(NSString*) entityName {
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] initWithEntityName:entityName];
NSError* error = nil;
NSArray* results = [_mainQueueContext executeFetchRequest:fetchRequest error:&error];
if (results == nil) {
ELog(@"--- Failed to fetch %@: %@", entityName, error);
return @[];
}
return results;
}
activityRuns
isn't used/passed anywhere other than in the code snippet above where each activity run is sent using an HTTP request. I tried adding breakpoints to right after the array is created (the objects are valid and contain data) and right before they're sent (they're all nil
).
How do I keep core data from shitting on my in-memory objects when something deletes records?
Upvotes: 0
Views: 183
Reputation: 80265
Simple solution:
Why don't you prepare all the data you need to send to the server first, including format and serialisation? You can then store this in memory or elsewhere and send to your server in the right order.
Upvotes: 1
Reputation: 6280
There are a few ways for this to happen:
deleteObject
and put breakpoints there.activityRun.student = nil;
, it should have the same effect (again have to delete manually when needed).There's a way to see all the CoreData SQL commands that happen under the hood - see here.
Upvotes: 1