Cross-store weak relationships with selected properties?

I would like to separate my data from my user data in my Core Data model in order to simplify future updates of my application (and because I plan to store the database in the cloud and there is no need to store reference data on the cloud, as it is part of my application) . So I searched for a while to encode the relationships between the repositories using the extracted properties. I have not found any examples of implementing this.

I have a Core Data model with two configurations:

  • Data Model Configuration 1: UserData (Objects Relative to User)

  • Data Model 2 Configuration: ReferenceData (objects related to the application itself)

I installed 2 different SQLite persistent repositories for both configurations.

  • UserData configuration (and storage) contains a User object

  • The configuration (and repository) of the ReferenceData contains the Type and Element objects.

I would like to create two one-way weak relationships, as shown below:

  • "User" has a unique "Type"

  • "User" has many "elements"

Here are my questions:

  • How to configure my properties?

  • Do I need 2 properties for each relationship (one to store a unique identifier, and the other to access my selected results)?

  • Is it possible to streamline this weak connection?

  • Can someone give me an example of implementing this?

As a follow-up to Marcus's answer:

Looking through forums and documents, I read that I should use the URI representation of my object instance instead of objectID. What is the reason for this?

// Get the URI of my object to reference NSURL * uriObjectB [[myObjectB objectID] URIRepresentation]; 

Next, I wonder how can I save the URI of my object B (NSURL) in my parent object A as a weak relation? What type of attribute should I use? How to do it? I heard about the archive ...?

Then, later I have to get the managed object in the same way (by unconvert / unarchive URIR representation) and get the Object from the URI

 // Get the Object ID from the URI NSManagedObjectID* idObjectB = [storeCoordinator managedObjectIDForURIRepresentation:[[myManagedObject objectID] URIRepresentation]]; // Get the Managed Object for the idOjectB ... 

And last but not least, let me declare two properties in my entity A, one to preserve the needs of the URI, and the other to receive the direct access object B?

 NSURL * uriObjectB [objectA uriObjectB]; ObjectB * myObjectB = [objectA objectB]; 

As you can read, I really missed a simple example to implement a weak relationship! I would really appreciate help.

+4
source share
2 answers

Sharing data is the right answer. Reference data should not be synchronized with the cloud, especially since iCloud has soft restrictions on the fact that it will allow the program to synchronize and store in documents.

To create soft links in stores (they don’t need to be SQLite, but this is a good idea for the overall performance of the application), you will need to have some unique key that can be referenced from the other side; good old fashioned foreign key.

From there, you can create the selected property in the model to reference the object.

While this relationship cannot be ordered directly, you can create an order through the sort index, or if it has a logical sort, then you can sort it after receiving the data (I use convenient methods for this, which return the sorted array instead of installed).

I can create an example, but you're really on the right track. The only interesting part is migration. When you discover a migration situation, you will need to migrate each store independently until when you create your main data stack. It sounds complicated, but it really is not that difficult.

Example

Imagine that there is a UserBar object in the user repository and a RefBar object in the link repository. After that, the RefBar will have a "fetchedProperty" relationship with the UserBar, thereby creating a ToOne relationship.

 UserBar ---------- refBarID : NSInteger RefBar -------- identifier : NSInteger 

Then you can create the selected property in the RefBar object in the model with a predicate:

$ FETCHED_PROPERTY.refBarID == identifier

Lets you name the predicate "userBarFetched"

Now that the array is returned, so we want to add a convenience method to the RefBar

 @class UserBar; @interface RefBar : NSManagedObject - (UserBar*)userBar; @end @implementation RefBar - (UserBar*)userBar { NSArray *fetched = [self valueForKey:@"userBarFetched"]; return [fetched lastObject]; } @end 

To create ToMany is the same, except that your convenience method returns an array, and you must sort the array before returning it.

As Heath Borders mentioned, you can add sorting to NSFetchedProperty if you want, but you have to do this in code. Personally, I always considered it wasteful and did not use this function. Perhaps it would be more useful if I could set the sort in the modeler.

Using ObjectID

I do not recommend using an ObjectID or URIR representation. The ObjectID (and therefore the URIR representation of this ObjectID) can and will change. Whenever you migrate a database whose value changes. You are much better off creating an immutable GUID.

Weak ratio

You need only one value on the M side of the relationship and which stores the external identifier. In your subclass of objects, you only need to implement accessors that retrieve the object (or objects).

+6
source

I would go with just one store.

To store things in the cloud, you still have to serialize the data, both in JSON and in SQL queries, or by any other scheme.

You will need a local copy of the data on the user device so that it can quickly and offline access it. Cloud storage can only have a user object, while the local store (part of the application) can also have a reference object.

I have a similar project with a huge repository of links (20,000 entries) with geographic information and user content ("posts"). I use one store. When I submit the application, the "posts" object is also defined, but empty. When I update the data model, I simply regenerate the entire link store before submitting.

I see absolutely no reason for a cross-store solution here.

-2
source

Source: https://habr.com/ru/post/1382242/


All Articles