gonzalezreal / groot Goto Github PK
View Code? Open in Web Editor NEWFrom JSON to Core Data and back.
License: Other
From JSON to Core Data and back.
License: Other
Given the following JSON:
{
"id": "1699",
"name": "Batman",
"powers": [
"4",
"9"
],
"publisher": "10",
"real_name": "Bruce Wayne"
}
When powers
and publisher
are mapped to a to-many and to-one relationships respectively and provided that the corresponding entities specify an identityAttribute
, the relationships should be created as expected.
A solution that solves this issue is provided by #15 and #16, but those are not compatible with the new approach taken in https://github.com/gonzalezreal/Groot/tree/1.0.
I have situations where after Groot populates an NSManagedObject with data (be it a new instance or an existing instance) I need to do some post-processing of the object, like setting up some relationships that aren't described in the JSON. Is there any way to hook into right after Groot populates an NSManagedObject? This would be akin to JSONDictionaryTransformerName which lets you do some pre-processing.
Building Groot fails under Xcode 7.1 with the error
Include of non-modular header inside framework module 'Groot.Groot'
The cause of the issue is the way headers are included in Groot.h file:
#import <Groot/GRTError.h>
#import <Groot/GRTManagedStore.h>
#import <Groot/NSValueTransformer+Groot.h>
#import <Groot/GRTJSONSerialization.h>
Changing the includes to
#import "GRTError.h"
#import "GRTManagedStore.h"
#import "NSValueTransformer+Groot.h"
#import "GRTJSONSerialization.h"
fixes the issue.
Hi,
In the projects where I use Groot, very often I need to update existing objects that has not (yet) a primary key using a given JSON.
As an example, let's think I can create a Character
from my app and send to my server. The Character
I created has not a primary key, because that key is provided by the server after being pushed. It would be great if once the Character
is pushed I can use the response from my server to update it:
let character = Character(context: managedObjectContext)
character.name = "Batman"
character.realName = "Bruce Wayne"
character.pushToServer { json in // the json is: {"id": 1, "name": "Batman", "real_name": "Bruce Wayne"}
character.update(with: json)
// now, character.id = 1
}
I usually solve it by creating a NSManagedObject
category that provides this functionality, basically exposing one private method. I wonder if it would make sense adding such functionality to the official release. If so, I could prepare a pull request.
Any thoughts?
After evaluating tons of Core Data wrappers and object mappers I came across Groot and I'm really happy with its simplicity and approach.
My application has a one-way connection (so it's read-only) to a REST API to display some sort of news feed. I'm currently using the mergeObjectsForEntityName method to update my local Core Data store with data from the API. As expected, this does NOT remove items from Core Data which are no longer in the server's response. Is this a feature which could be incorporated into Groot or can you suggest a way of implementing this in my own code? I don't want to wipe out my whole Core Data entity and use insertObjectsForEntityName because my entities store additional meta data.
Thanks! :)
I believe that at some point there were some wiki pages but they seem to have disappeared?
Anyway, I love Groot but it really lack proper documentation. The README gave some info, but not enough. Like:
JSONKeyPath
= null
for that)Having a README with some "QuickStart" & examples is great, but not as useful as a complete documentation. I think the wiki may be a nice place for that so that it can be easily editable and updatable (from anyone who wishes to contribute as well).
solved
Update the pod spec and make sure we keep support for iOS 6.
When installing the pod I get this error message:
Unable to read the license file /Users/.../Pods/Groot/LICENSE
for the spec Groot (1.0)
No Groot source file is downloaded.
In my coredata DB there are concrete object B, C, D, that inherit from another abstract object A.
Another object C has a relationship with A, that at runtime could be B, C, D.
During the unmarshaling (NSDictionary -> NSManagedObject) what entity does groot recognize? A or B/C/D?
I know iOS 9 is still in beta, but there is some errors while compailing under Xcode 7 beta4.
I have a simplified scenario with two tables in a one to many relationship. Each table has one column called 'Name':
Parent ---< Child
Let us say we want the Parent.name to be unique - which is easy.
We also want a Child.name to be unique for a parent, ie. a composite key. How do I implement this ?
( This assumes that no parent will ever give the same name to two children )
I do not have an explicit id
field in any of my core data entities, but I would like to have a unique identifier for serialization -- in my application I use the NSManagedObject objectID property as the unique identifier, is it possible to have Groot serialize it along with the rest of my fields?
Can you give us an example of how to use value transformers for say an NSDate coming with "yyyy-MM-dd'T'HH:mm:ssZ" format from/to the server.
I saw in the documents that it's an attribute you set in the inspector, however how and where do I add the actual value transformer ?? In the model class or ???
Having some issues running on legacy versions of Swift, latest version of Xcode 8 requires an automatic conversion of certain projects using legacy Swift versions - about 95% converts correctly but there are still some compile issues with Groot.
Update
For those using CocoaPods and have just upgraded to Xcode 8 using iOS10 for project, specify the version of swift in your project and there shouldn't be an issue with Groot.
post_install do |installer|
installer.pods_project.build_configuration_list.build_configurations.each do |configuration|
configuration.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
configuration.build_settings['SWIFT_VERSION'] = '2.3'
end
end
I have a JSON blob like this:
[
{
"id": 1,
"title": "Audio Title",
"type": "audio",
},
{
"id": 2,
title: "Video Title",
type: "video",
}
]
I'm no Core Data expert, but I suppose it's possible to have a common Media base class entity with two entity subclasses for Video and Audio objects? If so, do you think Groot will be able to correctly deserialize the JSON blob above into Video and Audio object entities respectively based on the type property?
Thanks!
When using mergeObjectForEntityName:..., I see that updated entities are not validated if the value is
nil. This happens at line 285 in
GRTJSONSerialization.m`:
if (merge && value == nil) {
return YES;
}
Now the problem is that when merging, I sometime have new object to insert. But if those new objects have an empty field, they are not validated. So if I have a non-optional attribut in a newly inserted object, and the value is nil, no error is created.
Could there be a way, when using the merge
method, so that attributes in objects to insert are using the validation process, even if nil?
Is there an annotation to cover the following case:
The JSON structure is the following:
{
"users": [
{
"id": 1,
"sentMessages": [
{
"id": 1,
"type": "textMessage",
"text": "asdfghjkl"
},
{
"id": 2,
"type": "pictureMessage",
"url": "http://example.com/image.png"
}
]
}
]
}
The logic for the messages is taken from your example for entityMapperName
, but I am not sure how to map the relationship between the objects.
How should I annotate the relations textMessages
and pictureMessages
together with the entityMapperName
logic for the abstract base entity Message
?
In my Data Model I have an entity A that has a relationship one-to-many to entity B.
When implementing the proper userInfo
keys for B I'd like to use as identityAttributes
a combination of an attribute in B and an attribute in A (for which B has an inverse relationship), such that I can uniquely identify an object in B for every unique object A.
Wouldn't it be better to use propertyByName
instead of attributeByName
to match the values that uniquely identifies an entity?
It could be something like identityProperties
that gives the opportunity to also include attributes within other objects in a relationship.
Error: Include of none-modular header inside framework module.
I get an error on a header file every time I install from cocoa pods in a swift project.
I followed to the letter the install process, however I am getting the following errors. I have to unlock the header files and comment the import statements.
Thank you for this library. We use it often!
In my data model I'm downloading my entities through separate endpoints, and my relationships are all described through string identifiers. Right now the JSON->CoreData serialization is working great with the JSONKeyPath userInfo key. However, when I try to serialize these objects back to JSON with JSONDictionaryFromObject: it serializes the entire relationship's object instead of just the identifier. Is there some way to do this without post-processing of the data?
NSArray *powersJSON = @[
@{
@"id": @"4",
@"name": @"Agility"
},
@{
@"id": @"9",
@"name": @"Insanely Rich"
}
];
[GRTJSONSerialization objectsWithEntityName:@"Power"
fromJSONArray:powersJSON
inContext:self.context
error:&error];
NSDictionary *batmanJSON = @{
@"name": @"Batman",
@"real_name": @"Bruce Wayne",
@"id": @"1699",
@"powers": @[@"4", @"9"],
};
Character *batman = [GRTJSONSerialization objectWithEntityName:@"Character"
fromJSONDictionary:batmanJSON
inContext:self.context
error:&error];
NSDictionary *object = [GRTJSONSerialization JSONDictionaryFromObject:batman];
NSLog(@"%@", object);
// {
id = 1699;
name = Batman;
powers = (
{
id = 4;
name = Agility;
},
{
id = 9;
name = "Insanely Rich";
}
);
realName = "<null>";
}
Hello,
there seems to be a problem with the binary version that is attached to the current tag.
It can not be linked in Xcode 7.1
My solution for now is to let Carthage build the library instead of downloading it.
$ carthage update --platform iOS --no-use-binaries
Maybe someone has the same issue :-)
Kind regards,
Florian
Hello @gonzalezreal,
I'm having an issue building my Swift project after installing Groot 1.2 via CocoaPods 0.39.0.
Specifically, I get the following errors while trying to build Groot:
.../Pods/Groot/Groot/Groot.h
.../Pods/Groot/Groot/Groot.h:31:9: Include of non-modular header inside framework module 'Groot.Groot'
.../Pods/Groot/Groot/Groot.h:32:9: Include of non-modular header inside framework module 'Groot.Groot'
.../Pods/Groot/Groot/Groot.h:33:9: Include of non-modular header inside framework module 'Groot.Groot'
.../Pods/Groot/Groot/Groot.h:34:9: Include of non-modular header inside framework module 'Groot.Groot'
Could not build Objective-C module 'Groot'
I took a look at this CocoaPods issue but this seems to be about importing header files from outside the Framework in question, whereas this issue is within the Framework.
My problem can be fixed by changing those lines from #import <Groot/$HEADER.h>
to #import "$HEADER.h"
. Unfortunately, I don't know enough about Obj-C to know why, but I suspect that the former form makes Xcode think the header is outside of the framework.
I attempted another solution which was to change the Build Setting "Allow Non-modular Includes In Framework Modules" to Yes inside my Project, the Pods Project, the Groot target, and the Pods-$MYPROJECT target. This didn't solve the problem.
Thanks!
Cutter
for a very easy code:
let data: JSONDictionary = [
"enrollment_capacity": 10,
"enrollment_total": 5,
"section": "sec1"
]
do {
let eg: UWFetchedData = try object(withEntityName: "UWFetchedData", fromJSONDictionary: data, inContext: self.context) as! UWFetchedData
print( "\(eg.section) \(eg.enrollment_capacity) / \(eg.enrollment_total)" )
} catch {}
it prints "nil 0 / 0"
UWFetchedData are shown as this:
the first two fields are integer, the last one is string
During the time it parse JSONDictionary, it prints error:
2016-12-12 00:45:51.531977 reflash-uw-course[87237:2702331] [error] error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///Users/jianxingzhang/Library/Developer/CoreSimulator/Devices/502A214A-B536-4863-A62C-0AB185CF9C07/data/Containers/Data/Application/DA5B5DDA-1551-488E-88F2-D0B00A804875/Library/Application%20Support/reflash_uw_course.sqlite options:{
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1;
} ... returned error Error Domain=NSCocoaErrorDomain Code=134140 "(null)" UserInfo={sourceModel=(<NSManagedObjectModel: 0x600000085960>) isEditable 1, entities {
UWCourse = "(<NSEntityDescription: 0x600000145f90>) name UWCourse, managedObjectClassName NSManagedObject, renamingIdentifier UWCourse, isAbstract 0, superentity name (null), properties {\n catalogNumber = "(<NSAttributeDescription: 0x618000108b80>), name catalogNumber, isOptional 0, isTransient 0, entity UWCourse, renamingIdentifier catalogNumber, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue 1171";\n hasFetchedData = "(<NSAttributeDescription: 0x600000108dc0>), name hasFetchedData, isOptional 1, isTransient 0, entity UWCourse, renamingIdentifier hasFetchedData, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 800 , attributeValueClassName NSNumber, defaultValue (null)";\n newRelationship = "(<NSRelationshipDescription: 0x600000146880>), name newRelationship, isOptional 1, isTransient 0, entity UWCourse, renamingIdentifier newRelationship, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, destination entity UWFetchedData, inverseRelationship newRelationship, minCount 0, maxCount 0, isOrdered 0, deleteRule 1";\n subject = "(<NSAttributeDescription: 0x600000108e50>), name subject, isOptional 0, isTransient 0, entity UWCourse, renamingIdentifier subject, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue cs";\n term = "(<NSAttributeDescription: 0x600000108ca0>), name term, isOptional 0, isTransient 0, entity UWCourse, renamingIdentifier term, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue 489";\n}, subentities {\n}, userInfo {\n}, versionHashModifier (null), uniquenessConstraints (\n)";
UWFetchedData = "(<NSEntityDescription: 0x600000146f60>) name UWFetchedData, managedObjectClassName NSManagedObject, renamingIdentifier UWFetchedData, isAbstract 0, superentity name (null), properties {\n "enrollment_capacity" = "(<NSAttributeDescription: 0x6100001080d0>), name enrollment_capacity, isOptional 1, isTransient 0, entity UWFetchedData, renamingIdentifier enrollment_capacity, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue (null)";\n "enrollment_total" = "(<NSAttributeDescription: 0x610000108550>), name enrollment_total, isOptional 0, isTransient 0, entity UWFetchedData, renamingIdentifier enrollment_total, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 200 , attributeValueClassName NSNumber, defaultValue 0";\n newRelationship = "(<NSRelationshipDescription: 0x6100001465c0>), name newRelationship, isOptional 1, isTransient 0, entity UWFetchedData, renamingIdentifier newRelationship, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, destination entity UWCourse, inverseRelationship newRelationship, minCount 0, maxCount 1, isOrdered 0, deleteRule 1";\n section = "(<NSAttributeDescription: 0x610000108430>), name section, isOptional 1, isTransient 0, entity UWFetchedData, renamingIdentifier section, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue (null)";\n}, subentities {\n}, userInfo {\n}, versionHashModifier (null), uniquenessConstraints (\n)";
}, fetch request templates {
}, destinationModel=(<NSManagedObjectModel: 0x618000082c10>) isEditable 0, entities {
UWCourse = "(<NSEntityDescription: 0x6080001467d0>) name UWCourse, managedObjectClassName UWCourse, renamingIdentifier UWCourse, isAbstract 0, superentity name (null), properties {\n catalogNumber = "(<NSAttributeDescription: 0x618000106ff0>), name catalogNumber, isOptional 0, isTransient 0, entity UWCourse, renamingIdentifier catalogNumber, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue 1171";\n hasFetchedData = "(<NSAttributeDescription: 0x6180001078f0>), name hasFetchedData, isOptional 1, isTransient 0, entity UWCourse, renamingIdentifier hasFetchedData, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 800 , attributeValueClassName NSNumber, defaultValue (null)";\n subject = "(<NSAttributeDescription: 0x6180001073e0>), name subject, isOptional 0, isTransient 0, entity UWCourse, renamingIdentifier subject, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue cs";\n term = "(<NSAttributeDescription: 0x618000107e00>), name term, isOptional 0, isTransient 0, entity UWCourse, renamingIdentifier term, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue 489";\n}, subentities {\n}, userInfo {\n}, versionHashModifier (null), uniquenessConstraints (\n)";
UWFetchedData = "(<NSEntityDescription: 0x608000146930>) name UWFetchedData, managedObjectClassName UWFetchedData, renamingIdentifier UWFetchedData, isAbstract 0, superentity name (null), properties {\n "enrollment_capacity" = "(<NSAttributeDescription: 0x618000106e40>), name enrollment_capacity, isOptional 1, isTransient 0, entity UWFetchedData, renamingIdentifier enrollment_capacity, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 300 , attributeValueClassName NSNumber, defaultValue 0";\n "enrollment_total" = "(<NSAttributeDescription: 0x618000106f60>), name enrollment_total, isOptional 0, isTransient 0, entity UWFetchedData, renamingIdentifier enrollment_total, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 300 , attributeValueClassName NSNumber, defaultValue 0";\n section = "(<NSAttributeDescription: 0x618000106d20>), name section, isOptional 1, isTransient 0, entity UWFetchedData, renamingIdentifier section, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue (null)";\n}, subentities {\n}, userInfo {\n}, versionHashModifier (null), uniquenessConstraints (\n)";
}, fetch request templates {
}, reason=Can't find or automatically infer mapping model for migration, NSUnderlyingError=0x618000055c00 {Error Domain=NSCocoaErrorDomain Code=134190 "(null)" UserInfo={entity=UWFetchedData, property=enrollment_capacity, reason=Source and destination attribute types are incompatible}}} with userInfo dictionary {
NSUnderlyingError = "Error Domain=NSCocoaErrorDomain Code=134190 "(null)" UserInfo={entity=UWFetchedData, property=enrollment_capacity, reason=Source and destination attribute types are incompatible}";
destinationModel = "(<NSManagedObjectModel: 0x618000082c10>) isEditable 0, entities {\n UWCourse = "(<NSEntityDescription: 0x6080001467d0>) name UWCourse, managedObjectClassName UWCourse, renamingIdentifier UWCourse, isAbstract 0, superentity name (null), properties {\n catalogNumber = \"(<NSAttributeDescription: 0x618000106ff0>), name catalogNumber, isOptional 0, isTransient 0, entity UWCourse, renamingIdentifier catalogNumber, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 700 , attributeValueClassName NSString, defaultValue 1171\";\n hasFetchedData = \"(<NSAttributeDescription: 0x6180001078f0>), name hasFetchedData, isOptional 1, isTransient 0, entity UWCourse, renamingIdentifier hasFetchedData, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 800 , attributeValueClassName NSNumber, defaultValue (null)\";\n subject = \"(<NSAttributeDescription: 0x6180001073e0>), name subject, isOptional 0, isTransient 0, entity UWCourse, renamingIdentifier subject, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 700 , attributeValueClassName NSString, defaultValue cs\";\n term = \"(<NSAttributeDescription: 0x618000107e00>), name term, isOptional 0, isTransient 0, entity UWCourse, renamingIdentifier term, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 700 , attributeValueClassName NSString, defaultValue 489\";\n}, subentities {\n}, userInfo {\n}, versionHashModifier (null), uniquenessConstraints (\n)";\n UWFetchedData = "(<NSEntityDescription: 0x608000146930>) name UWFetchedData, managedObjectClassName UWFetchedData, renamingIdentifier UWFetchedData, isAbstract 0, superentity name (null), properties {\n \"enrollment_capacity\" = \"(<NSAttributeDescription: 0x618000106e40>), name enrollment_capacity, isOptional 1, isTransient 0, entity UWFetchedData, renamingIdentifier enrollment_capacity, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 300 , attributeValueClassName NSNumber, defaultValue 0\";\n \"enrollment_total\" = \"(<NSAttributeDescription: 0x618000106f60>), name enrollment_total, isOptional 0, isTransient 0, entity UWFetchedData, renamingIdentifier enrollment_total, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 300 , attributeValueClassName NSNumber, defaultValue 0\";\n section = \"(<NSAttributeDescription: 0x618000106d20>), name section, isOptional 1, isTransient 0, entity UWFetchedData, renamingIdentifier section, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 700 , attributeValueClassName NSString, defaultValue (null)\";\n}, subentities {\n}, userInfo {\n}, versionHashModifier (null), uniquenessConstraints (\n)";\n}, fetch request templates {\n}";
reason = "Can't find or automatically infer mapping model for migration";
sourceModel = "(<NSManagedObjectModel: 0x600000085960>) isEditable 1, entities {\n UWCourse = "(<NSEntityDescription: 0x600000145f90>) name UWCourse, managedObjectClassName NSManagedObject, renamingIdentifier UWCourse, isAbstract 0, superentity name (null), properties {\n catalogNumber = \"(<NSAttributeDescription: 0x618000108b80>), name catalogNumber, isOptional 0, isTransient 0, entity UWCourse, renamingIdentifier catalogNumber, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 700 , attributeValueClassName NSString, defaultValue 1171\";\n hasFetchedData = \"(<NSAttributeDescription: 0x600000108dc0>), name hasFetchedData, isOptional 1, isTransient 0, entity UWCourse, renamingIdentifier hasFetchedData, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 800 , attributeValueClassName NSNumber, defaultValue (null)\";\n newRelationship = \"(<NSRelationshipDescription: 0x600000146880>), name newRelationship, isOptional 1, isTransient 0, entity UWCourse, renamingIdentifier newRelationship, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, destination entity UWFetchedData, inverseRelationship newRelationship, minCount 0, maxCount 0, isOrdered 0, deleteRule 1\";\n subject = \"(<NSAttributeDescription: 0x600000108e50>), name subject, isOptional 0, isTransient 0, entity UWCourse, renamingIdentifier subject, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 700 , attributeValueClassName NSString, defaultValue cs\";\n term = \"(<NSAttributeDescription: 0x600000108ca0>), name term, isOptional 0, isTransient 0, entity UWCourse, renamingIdentifier term, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 700 , attributeValueClassName NSString, defaultValue 489\";\n}, subentities {\n}, userInfo {\n}, versionHashModifier (null), uniquenessConstraints (\n)";\n UWFetchedData = "(<NSEntityDescription: 0x600000146f60>) name UWFetchedData, managedObjectClassName NSManagedObject, renamingIdentifier UWFetchedData, isAbstract 0, superentity name (null), properties {\n \"enrollment_capacity\" = \"(<NSAttributeDescription: 0x6100001080d0>), name enrollment_capacity, isOptional 1, isTransient 0, entity UWFetchedData, renamingIdentifier enrollment_capacity, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 700 , attributeValueClassName NSString, defaultValue (null)\";\n \"enrollment_total\" = \"(<NSAttributeDescription: 0x610000108550>), name enrollment_total, isOptional 0, isTransient 0, entity UWFetchedData, renamingIdentifier enrollment_total, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 200 , attributeValueClassName NSNumber, defaultValue 0\";\n newRelationship = \"(<NSRelationshipDescription: 0x6100001465c0>), name newRelationship, isOptional 1, isTransient 0, entity UWFetchedData, renamingIdentifier newRelationship, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, destination entity UWCourse, inverseRelationship newRelationship, minCount 0, maxCount 1, isOrdered 0, deleteRule 1\";\n section = \"(<NSAttributeDescription: 0x610000108430>), name section, isOptional 1, isTransient 0, entity UWFetchedData, renamingIdentifier section, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 700 , attributeValueClassName NSString, defaultValue (null)\";\n}, subentities {\n}, userInfo {\n}, versionHashModifier (null), uniquenessConstraints (\n)";\n}, fetch request templates {\n}";
}
I would find it useful to be able to obtain the identity attribute from an entity description.
I can certainly accomplish all of these already but I end up restating the identity attribute in many locations.
Do you think it would be reasonable to expose -grt_identityAttribute
so that an app can inspect this configuration?
How can I manage the fact that I can only have the relationships in 2 requests, instead of one?
For example, using characters and publishers model, I would have: http://myapi/characters.json which gives me the list of characters ; And http://myapi/publishers.json which gives me the list of publishers.
And in the characters.json, for each character, have a key: "publisher_id": xxx (contrary to your example, where the publisher is embedded in the character.json.
How can I make Groot to build the relationship between characters and its publisher, if publishers are fetched in another request?
Sincerely,
Jery
This is just a thought, but perhaps you could provide examples of Groot being used in a SWIFT environment. Especially if there are any caveats.
Hello.
Thank you for the great library!
I am not sure if something is wrong with my setup, but if I add a entityMapperName to two entities (for example PictureMessage and TextMessage, which both inherit from Message), and also have JSONDictionaryTransformerName for both PictureMessage and TextMessage, those JSONDictionaryTransformerName will not be called. Only a JSONDictionaryTransformerName on the abstract Message class works.
Personally this caused me a few hours of headache to get to work so I am submitting a pull request that documents this behavior: #65
I'm building framework on top of Groot, and I use methods declared in its private headers. While I used CocoaPods I could include them directly, although this is dirty of-course. Now I've migrated to Carthage, and I can't include them anymore except directly copying them to my project. May be move them to public?
"grt_identityAttributes" method is very handy!
NSEntityDescription+Groot.h
NSPropertyDescription+Groot.h
@gonzalezreal
Hi!
Thank you for your open source library, I have a question:Can you provide a demo?
Jack
We could provide an API to setup a function that transforms a JSON dictionary into an entity name:
[NSValueTransformer grt_setEntityMapperWithName:@"FancyName" mapBlock:^NSString *(NSDictionary *JSONDictionary) {
// return an entity name based on the JSON dictionary
}];
This entity mapper could then be specified in the user info dictionary of an abstract entity.
This kind of functionality was requested in #12.
Hi there,
I'm pretty new to cocoapods as well as xcode/iOS development in general so I'm likely doing something wrong. I've set up CocoaPods itself (I tested it with AFNetworking) but when I include Groot it gets a ton of compile errors. Is there something else I need to include as well?
Below are the copied compile errors (not sure if its actually useful or not). All I'm doing is adding pod 'Groot' to my Podfile and running the install and then trying to compile the project:
CompileSwift normal x86_64 /Users/kristoforwilson/Projects/cps-inspection/Pods/Groot/Groot/Groot.swift
cd /Users/kristoforwilson/Projects/cps-inspection/Pods
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -primary-file /Users/kristoforwilson/Projects/cps-inspection/Pods/Groot/Groot/Groot.swift /Users/kristoforwilson/Projects/cps-inspection/Pods/Groot/Groot/NSValueTransformer+Groot.swift -target x86_64-apple-ios8.0 -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.4.sdk -I /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Products/Debug-iphonesimulator -F /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Products/Debug-iphonesimulator -g -import-underlying-module -module-cache-path /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/ModuleCache -D COCOAPODS -serialize-debugging-options -Xcc -I/Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/swift-overrides.hmap -Xcc -iquote -Xcc /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/Groot-generated-files.hmap -Xcc -I/Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/Groot-own-target-headers.hmap -Xcc -I/Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/Groot-all-non-framework-target-headers.hmap -Xcc -ivfsoverlay -Xcc /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/all-product-headers.yaml -Xcc -iquote -Xcc /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/Groot-project-headers.hmap -Xcc -I/Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/kristoforwilson/Projects/cps-inspection/Pods/Headers/Private -Xcc -I/Users/kristoforwilson/Projects/cps-inspection/Pods/Headers/Private/Groot -Xcc -I/Users/kristoforwilson/Projects/cps-inspection/Pods/Headers/Public -Xcc -I/Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/DerivedSources/x86_64 -Xcc -I/Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/DerivedSources -Xcc -DDEBUG=1 -Xcc -DCOCOAPODS=1 -Xcc -ivfsoverlay -Xcc /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/unextended-module-overlay.yaml -Xcc -working-directory/Users/kristoforwilson/Projects/cps-inspection/Pods -emit-module-doc-path /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/Objects-normal/x86_64/Grootpartial.swiftdoc -Onone -module-name Groot -emit-module-path /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/Objects-normal/x86_64/Grootpartial.swiftmodule -serialize-diagnostics-path /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/Objects-normal/x86_64/Groot.dia -emit-dependencies-path /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/Objects-normal/x86_64/Groot.d -emit-reference-dependencies-path /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/Objects-normal/x86_64/Groot.swiftdeps -o /Users/kristoforwilson/Library/Developer/Xcode/DerivedData/cps-inspection-donliihuvlglwhbfwljnwvpimznd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Groot.build/Objects-normal/x86_64/Groot.o
:1:9: note: in file included from :1:
^
/Users/kristoforwilson/Projects/cps-inspection/Pods/Target Support Files/Groot/Groot-umbrella.h:3:9: note: in file included from /Users/kristoforwilson/Projects/cps-inspection/Pods/Target Support Files/Groot/Groot-umbrella.h:3:
^
/Users/kristoforwilson/Projects/cps-inspection/Pods/Groot/Groot/Groot.h:34:9: note: in file included from /Users/kristoforwilson/Projects/cps-inspection/Pods/Groot/Groot/Groot.h:34:
^
/Users/kristoforwilson/Projects/cps-inspection/Pods/Groot/Groot/GRTJSONSerialization.h:42:30: error: expected '>'
Include of non-modular header inside framework module Groot.Groot
Could not build Objective-C module Groot
I'm using Groot with a pretty large provided data set (~100,000 objects with relationships). Some entities only have ~100 objects but the larger ones have around 30,000. Right now it's taking a long time for the parsing to take place, which seems to be related to the -[NSManagedObject(Groot) grt_setRelationship:fromJSONDictionary:mergeChanges:error:]. Specifically in the existingObjectsWithJSONArray method for executeFetchRequest. Does anyone have suggestions to speed up this specific process, perhaps on the CoreData level?
Hello,
first of all thanks for the great project!
I have a question, is it somehow possible to preserve the order in the json?
Since core data only provides sets it would be great to e.g. set an index in the relationship.
Is something like that possible?
Kind regards,
Florian
This is more of a feature request than a bug, and is the only thing preventing Groot from doing exactly what my App needs. As it stands all relationships are treated as complete/perfect relationships, which is not always the case.
Feature:
Be able to set an annotation on a relationship that flags it to not override existing relationships but instead merge them.
For example, my situation requires that certain objects be attached to the current logged in User object. These objects may already be attached to another User and as such need to retain that relationship post mapping.
I have been trying to work on my own fork to get this to work, and so far have had no success.
several months ago , i found Groot . (maybe is 0.2 version ,i don't remember clearly).
groot is very useful with coredata .
but , i found the lastest verson is very troublesome.
i should must creat JSONKeyPath for every attribute in entity , even if the attribute name is the same as in json , and even if the attribute dont need to transform back to json .
i just still have no clue, why you would do so .
just to transform json from coredata ?
in what case, transform json from coredata will be very useful ?
Hi,
Is there a way for Groot to serialize back to JSON Dictionary only some properties of my NSManaged Object?
Also, I want to know if it's possible to serialize from JSON some properties and to not serial back to JSON all of those properties. For example the createdAt time stamp that is created by the server.
How can I do that? the new objects does not saved after update
Enhance the JSONKeyPath
annotation so that it can contain multiple key paths, for instance: genre_ids, genres
.
Key paths will be evaluated in the order in which they are specified and the first value encountered will be used.
The JSONTransformerName
annotation should be enhanced in the same way to express the corresponding transformers: GenreIDTransformer, GenreTransformer
or , GenreTransformer
(the comma is needed to state that the first key path does not need a transformer).
Enhance identityAttribute
annotation to support multiple attributes separated by comma, maybe renaming it to identityAttributes
and providing backwards compatibility.
If possible optimise the predicate for the single identity attribute case.
May be related to #11?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.