0

I'm a in a really common situation mostly driven by inexperience...

My application inserts pre-built data in the DB at the first launch. I just check for db existence in the device... if it doesn't exist this is the first launch so I add my pre-built data after DB creation.

At the end of the development I decide to activate iCloud, wow! just one row of code to make it works... I tried it on different devices and my pre-built data were obviously duplicated :(

I understood that the better way to manage pre-built data is to work with more than one persistent store, creating read-only store for pre-built data (my pre-built data don't need to be modified by the user, so the read-only solution would be ok).

The problem is that I have relationship between data inserted by user so I can't work on multiple persistent store (core-data doesn't support relation between different stores).

I took a look at Fetched Properties but it seems to require a super drastic edit on my code.

I thought to go with de-duplicating data... so just removing data that are already in the DB, my doubt is that this process is really dangerous for relationship, how can I delete the object that is just a duplicate of the "original" created at the first launch?=

Given that my pre-build data are can't be modified or deleted by the users, which is in your opinion the best way to correct this problem?

// EDIT: Some information about the model:

The entity that users are dealing with (add/edit/modify)represents a TASK. this entities have a name, and a CATEGORY.

CATEGORY are the entities that I pre-build.

So user add a name for the task and select a CATEGORY from the pre-built data.

MatterGoal
  • 16,038
  • 19
  • 109
  • 186
  • Rather than checking for the existence of the database, can you check for the existence of the prebuilt data? – David Berry Mar 18 '14 at 19:41
  • @David The problem is that data are inserted by iCloud in the future. Am I wrong? – MatterGoal Mar 18 '14 at 19:49
  • ...and I can't verify which data are added by iCloud. – MatterGoal Mar 18 '14 at 19:49
  • 2
    The other alternative is to split the model into your private prebuilt data in one model and and the cloud mutable data in another model. Use some kind of persistent key and a bit of wrapping to link the two. This should be pretty straight forward if the relations are all from user data to prebuilt data and none the other way around. – David Berry Mar 18 '14 at 19:52
  • Could you tell me more about this solution? I think it could be interesting! (maybe add it as an answer) – MatterGoal Mar 18 '14 at 19:55
  • @David I've also added some information about my current model. – MatterGoal Mar 18 '14 at 19:59
  • possible duplicate of [iCloud + CoreData - how to avoid pre-filled data duplication?](http://stackoverflow.com/questions/9097541/icloud-coredata-how-to-avoid-pre-filled-data-duplication) – Robotic Cat Mar 18 '14 at 20:09
  • I've flagged this as a possible duplicate. Please check that question along with it's answer. – Robotic Cat Mar 18 '14 at 20:09
  • 1
    @RoboticCat I don't think this is a duplicate, although obviously related. In the linked response the issue is dealing with iCloud synchronized mutable data. In this case there's a portion of the database which is essentially non-mutable and really doesn't need to be synchronized at all, because it's globally shared. In any case, perusing the linked answer is worthwhile. – David Berry Mar 18 '14 at 20:17

1 Answers1

1

In your Category entity, in the PrebuiltData model, create an "id" property (and make sure that this is consistent from version to version) This model should not be managed by iCloud.

In your Task entity, in the UserData model, create a "categoryId" property. This model should be managed by iCloud (or this discussion is meaningless)

Now you can create a method on your Category entity to fetch all the Tasks in the category using:

-(NSArray*)tasks
{
    NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Task"];
    request.predicate = [NSPredicate predicateWithFormat:@"id = %@", self.id];
    return [gTaskManagedObjectContext executeFetchRequest:request error:NULL];
}

Likewise, you can create a method on your Task entity to fetch the category:

-(Category*)category
{
    NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Category"];
    request.predicate = [NSPredicate predicateWithFormat:@"id = %@", self.categoryId];
    NSArray*        results = [gTaskManagedObjectContext executeFetchRequest:request error:NULL];

    return results.count > 0 ? results[0] : nil;
}
David Berry
  • 40,941
  • 12
  • 84
  • 95