FastEasyMapping
FastEasyMapping copied to clipboard
Save At Position
Hello,
Can we save Object at first location.
I would like store/insert object at first position is it possible??
thanks in advance.
Hello. What do you mean by "first position"? Sorting?
First we are getting array and that array sorted and i have stored inside coredata.
but after that i am inserting new recored inside coredata. after that that record i am getting in last position but i would like to get that record at first position..
Are you inserting objects as a part of mapping or manually?
mapping like
[MagicalRecord saveWithBlock:^(NSManagedObjectContext * _Nonnull localContext) {
arr = [FEMDeserializer collectionFromRepresentation:[dict objectForKey:@"data"] mapping:[_LeadStatusList defaultMapping] context:localContext];
} completion:^(BOOL contextDidSave, NSError * _Nullable error) {
[self.view makeToast:dict[@"message"]];
[self.navigationController popViewControllerAnimated:YES];
}];
Are you talking about root object order or it is a relationship?
Order
I meant is it an order of the root object or an order of the relationship's object
relationship object.
In this case you should create your own assignment policy that will manage order in a way that you need. See Assignment Policy description. Also take a look at the implementation of the FEMAssignmentPolicyCollectionReplace to get an idea of how it works.
Can you explain me how assignment policy works with replacing particular object???
Sorry, I was busy. Sure, here is an explanation:
Lets say that we're mapping a response for an object Object
that has a relationship children
with values A
, B
, C
. Response contains same Object but with the relationship values C
, D
. Resulting relationship should looks like C
, D
, while A
and B
should b removed.
Type of the collection that holds both relationships depends on the property type that holds that relationship. For our example lets assume that property is of NSSet
type as the default for the CoreData's to-many relationships.
Therefore legend looks like this:
-
context.sourceRelationshipValue
- corresponds to a collection withA
,B
,C
. NSSet. -
context.sourceRelationshipValue
- corresponds to a collection withC
,D
. NSSet.
Here is the code with explanations:
FEMAssignmentPolicy FEMAssignmentPolicyCollectionReplace = ^id(FEMRelationshipAssignmentContext *context) {
// There is no reason to run complex logic in case previous relationship value was nil (i.e. no A, B, C)
// In this case we're just returning target value. "Target" means the one that I'd like to have for my Object
if (!context.sourceRelationshipValue) return context.targetRelationshipValue;
// This is another corner case when we're ensuring that backend has responded with something. Otherwise we're just returning previous value of the relationship and skip complex logic (i.e. keeping `children` at `A, B, C` values.
if (context.targetRelationshipValue) {
// This is an internal check, because FEM maintains its own protocol for common collections like NSArray, NSSet, NSOrderedSet (and mutable counterparts) that knows how to perform a replace. Search for a FEMExcludableCollection for more info.
NSCAssert(
[context.sourceRelationshipValue conformsToProtocol:@protocol(FEMExcludableCollection)],
@"Collection %@ should support protocol %@",
NSStringFromClass([context.targetRelationshipValue class]),
NSStringFromProtocol(@protocol(FEMExcludableCollection))
);
// As I mentioned above, FEM knows how to replace contents of one collection by another one.
// For a replacement algorithm looks as follows: find a "delta" between previous collection and a new one (all of the objects that are not presented in the targetRelationshipValue) and delete them
// Then simply return targetValue.
id objectsToDelete = [(id <FEMExcludableCollection>)context.sourceRelationshipValue collectionByExcludingObjects:context.targetRelationshipValue];
for (id object in objectsToDelete) {
[context deleteRelationshipObject:object];
}
} else {
for (id object in context.sourceRelationshipValue) {
[context deleteRelationshipObject:object];
}
}
return context.targetRelationshipValue;
};
Now going back to your question about how to alway prepend your objects in the beginning of the relationship:
If this is not a replacement, then:
- Declare your relationship as an ordered one (should be NSOrderedSet)
- Declare your custom merge policy with a following logic
- Handle corner cases like no
sourceRelationshipValue
ortargetRelationshipValue
- When both values presented: assert that both have type of the NSOrderedSet
- You can make a mutable copy of the
sourceRelationshipValue
- Iterate over new values from
targetRelationshipValue
and run- [resultingMutableOredereSet insertObject:newObject atIndex:0]
- Handle corner cases like no
Few comments: this doesn't handle complex cases when target relationship value contains new and old values in a mixed order. Therefore values like this [New, New, Old, New]
can not be handled correctly and will be inserted into the resulting site in the following order [New, New, New, Old]
.