Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored different members out in favour of SPJSONDiff and policies #121

Closed
wants to merge 76 commits into from

Conversation

mackross
Copy link
Contributor

Added support for embeddedObjects in 1-1 and 1-* relationships.

⚠️ not yet ready to merge ⚠️

  • Needs to use policies on transformable members so that if they transform to strings they don't do string diffs rather than replaces.
  • Support operation type for member to force operation types.
  • Wait for jsondiff list diff spec to be properly fleshed out for full recursive and then implement in objc.
  • Probably a few more tests on the member stuff would be a good idea.
  • Fix bug when transforming embedded objects
  • Provide a migration path from SPManagedObject to SPEmbeddedManagedObject?

Hey @mikejohnstn, @Rjonhson, @tomwitkin, @jleandroperez

I've done some a first pass on recursive embedded objects and embedded object lists. I've tested sending objects up and down without problems. I've got to do some tests on transformations tomorrow and iron out any bugs there are. I've heavily refactored the SPMember and SPDiffer classes. In fact the entire diff/applydiff/transformation process occurs completely in json formatted values (its pretty much a direct port of jsondiff.js). The member class then uses the transformed json formatted values to update the core data model.

The biggest benefit of this change is that data is much easier to access with the javascript libraries and data is synced as conceptually whole units. For example in our app we have an inspection entity that inspection areas which in turn have inspection items which have photos ( [inspection]1-[areas]1-[items]1-*[photo-reference] ). This used to be stored on simperium in 4 buckets. Now it is stored as just 1 and as soon as the inspection is loaded it's guaranteed that all the areas, items, and photo references are updated and ready to go too.

The way that it works is pretty simple. Like normal you make your bucket objects inherit from SPManagedObject. All objects that you want to embed in relationships must inherit from SPEmbeddedManagedObject and the relationship to the SPEmbeddedManagedObject from the object must have the userInfo key 'spEmbed'. I've also changed the base64 type to a transformable type that can have a custom transformer set on it. A useful case for this might be if you store UIColor on your entity as a transformable. If you create a UIColorToHexStringValueTransformer class and then set spJSONTransformerName in the userInfo dictionary to this class name. The UIColor would now be stored in simperium as the hex string but in core data as a UIColor (archived with NSKeyedArchiver most liked).

Please let me know what you think. We're going to be rolling this out into our production app very soon.

PS Apologies for the spelling and what not, it's late!

…. Added support for embeddedObjects in 1-1 and 1-* relationships.
@mikejohnstn
Copy link
Contributor

Epic, I look forward to digging into this. At first glance, appreciate some of the stylistic improvements as well. And _keyPathsFromEmbeddedObjectsToBucketObjectsByEmbeddedObjectEntityName deserves an award.

@Rjonhson
Copy link

Looking fantastic, I will surely look into this.

Thanks Mackross!

@mackross
Copy link
Contributor Author

Yep haha - there is definitely a bug in the SPTransformDiff method. I'll try work it out asap.

@mikejohnstn
Copy link
Contributor

@jleandroperez and I will be starting to look at this next week, but I'm thinking it might be better to merge the existing develop branch to master first (plus enable WebSockets by default, etc.), and then merge this into a fresh develop. That could take some time because we also need to update a bunch of documentation.

@mackross
Copy link
Contributor Author

⭐ sounds like a plan

@@ -0,0 +1,534 @@
//
// SPJSONDiff.m
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pretty monstrous file, and will only grow as we continue to add complexity to diff policies (like different kinds of conflict resolution). Worth pulling out the categories into their own files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep good idea. That's how I initially had it but there were already simperium categories for these classes and I really wanted to differentiate the JSON diff from everything else. Perhaps something like NSString+SPJONDiff, etc?

mackross and others added 23 commits August 26, 2013 15:47
Untested after merge. Probably requires some fixes.
tomlongo and others added 27 commits December 20, 2013 17:33
Conflicts:
	External/diffmatchpatch/DiffMatchPatch.m
	Simperium.podspec
	Simperium.xcodeproj/project.pbxproj
	Simperium/JSONKit+Simperium.h
	Simperium/NSArray+Simperium.m
	Simperium/SPAuthenticator.m
	Simperium/SPBucket.h
	Simperium/SPBucket.m
	Simperium/SPChangeProcessor.h
	Simperium/SPChangeProcessor.m
	Simperium/SPCoreDataExporter.m
	Simperium/SPCoreDataStorage.m
	Simperium/SPDiffer.h
	Simperium/SPDiffer.m
	Simperium/SPIndexProcessor.h
	Simperium/SPIndexProcessor.m
	Simperium/SPManagedObject.h
	Simperium/SPManagedObject.m
	Simperium/SPMember.h
	Simperium/SPMember.m
	Simperium/SPMemberBase64.m
	Simperium/SPMemberDate.m
	Simperium/SPMemberDouble.m
	Simperium/SPMemberEntity.m
	Simperium/SPMemberFloat.m
	Simperium/SPMemberInt.m
	Simperium/SPMemberJSONList.h
	Simperium/SPMemberJSONList.m
	Simperium/SPMemberList.m
	Simperium/SPMemberText.m
	Simperium/SPNetworkInterface.h
	Simperium/SPSchema.h
	Simperium/SPSchema.m
	Simperium/SPWebSocketChannel.h
	Simperium/SPWebSocketChannel.m
	Simperium/Simperium.h
	Simperium/Simperium.m
Conflicts:
	Simperium.xcodeproj/project.pbxproj
	Simperium/SPChangeProcessor.m
	Simperium/SPSchema.m
Conflicts:
	Simperium.xcodeproj/project.pbxproj
	Simperium/SPMemberJSON.m
	Simperium/SPSchema.h
	Simperium/SPSchema.m
Conflicts:
	Simperium/SPBucket.m
	Simperium/SPChangeProcessor.m
	Simperium/SPRelationshipResolver.m
	Simperium/SPWebSocketInterface.m
When both the local and remote diff are additions to a nil value,
the diff transform code drops the local diff in favour of the remote
diff. This commit replaces the previous remote diff with the new local
diff so that each key is transformed consistently.
Conflicts:
	Simperium.xcodeproj/project.pbxproj
	Simperium/SPBucket.h
	Simperium/SPChangeProcessor.m
Conflicts:
	Simperium.xcodeproj/project.pbxproj
	Simperium/SPChangeProcessor.m
	Simperium/SPDiffer.h
	Simperium/SPDiffer.m
	Simperium/SPIndexProcessor.h
	Simperium/SPIndexProcessor.m
	Simperium/SPMember.h
	Simperium/SPMember.m
	Simperium/SPMemberBase64.m
	Simperium/SPMemberDate.m
	Simperium/SPMemberDouble.m
	Simperium/SPMemberEntity.m
	Simperium/SPMemberFloat.m
	Simperium/SPMemberInt.m
	Simperium/SPMemberJSON.m
	Simperium/SPMemberJSONList.m
	Simperium/SPMemberList.m
	Simperium/SPMemberText.h
	Simperium/SPMemberText.m
	Simperium/Simperium.m
Conflicts:
	Simperium.xcodeproj/project.pbxproj
	Simperium/SPWebSocketInterface.m
Conflicts:
	Simperium.xcodeproj/project.pbxproj
	Simperium/NSArray+Simperium.m
	Simperium/SPBucket.m
	Simperium/SPChangeProcessor.m
	Simperium/SPCoreDataStorage.m
	Simperium/SPDiffer.m
	Simperium/SPIndexProcessor.h
	Simperium/SPIndexProcessor.m
	Simperium/SPManagedObject.h
	Simperium/SPManagedObject.m
	Simperium/SPMember.h
	Simperium/SPMember.m
	Simperium/SPMemberBase64.m
	Simperium/SPMemberDate.m
	Simperium/SPMemberDouble.m
	Simperium/SPMemberEntity.h
	Simperium/SPMemberEntity.m
	Simperium/SPMemberFloat.m
	Simperium/SPMemberInt.m
	Simperium/SPMemberJSON.m
	Simperium/SPMemberJSONList.m
	Simperium/SPMemberList.m
	Simperium/SPMemberText.m
	Simperium/SPRelationshipResolver.m
	Simperium/SPSchema.m
	Simperium/SPWebSocketInterface.m
	Simperium/Simperium+Internals.h
	Simperium/Simperium.m
Conflicts:
	Simperium/SPChangeProcessor.m
	Simperium/SPMemberBase64.m
@jleandroperez
Copy link
Contributor

Gentleman,

I'm closing this one, since the codebase has diverged considerably in between. Hope everyone is doing (more than) great.

Thank you for helping us out!

@jleandroperez jleandroperez removed this from the v0.9.0 milestone Jan 12, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants