sbonami / pfincrementalstore Goto Github PK
View Code? Open in Web Editor NEWOffline Parse with Core Data Persistence, an NSIncrementalStore subclass.
Home Page: http://sbonami.github.io/PFIncrementalStore/
License: MIT License
Offline Parse with Core Data Persistence, an NSIncrementalStore subclass.
Home Page: http://sbonami.github.io/PFIncrementalStore/
License: MIT License
Hi,
I am making my first experiments with PFIncrementalStore. I got a first test project up and running really quickly: I love the approach and really appreciate your work. Though I am struggling with a sync bug that I can't get rid of, and I don't understand if it is a bug or if I am approaching PFIncrementalStore the wrong way.
So, here is what is happening. I correctly retrieve some data from Parse, make some changes to the data, call save:
on the main managedObjectContext
. The issue is that sometimes the data is correctly saved, sometimes not, rolling back to the previous value.
I tried to debug this behavior: I added a symbolic breakpoint to -[PFQuery getObjectInBackgroundWithId:block:]
and as I suspected this is being called twice:
-updateObject:fromRequest:inContext:error:
override (this is correct)newValuesForObjectWithID:withContext:error:
:#2 0x00007fff8c8e589a in -[NSPersistentStoreCoordinator(_NSInternalMethods) _conflictsWithRowCacheForObject:withContext:andStore:] ()
As I read it: the call to save:
immediately propagates the changes to the SQLite persistent store before the changes has been saved on the cloud. Of course CoreData find a conflict between the data state and the SQLite persistent store, so it asks PFIncrementalStore to solve it. PFIncrementalStore just fetch the data from Parse and overwrite the changes. So: the first operation that completes just wins.
If I am correct, maybe a solution could be to wait to propagate saves to the SQLite persistent store for the remote sync to complete.
In Basic Example, I added a new Artist object with relation to Song, which also has relation to Genre:
Artist *artist = [NSEntityDescription insertNewObjectForEntityForName:@"Artist" inManagedObjectContext:context];
Song *song = [NSEntityDescription insertNewObjectForEntityForName:@"Song" inManagedObjectContext:context];
Genre *genre = [NSEntityDescription insertNewObjectForEntityForName:@"Genre" inManagedObjectContext:context];
artist.artistName = @"New";
genre.genreName = @"My genre";
song.songTitle = @"Song title";
song.songArtist = artist;
song.songGenre = genre;
NSError *err;
[context save:&err];
if (err) {
NSLog(@"%@", err.description);
}
But the IncrementalStore threw an error as follows. What's rather interesting is that the code works sometime and doesn't work some other times.
I tried to delete the relation definition on Parse.com and it still works. It seems that the framework doesn't use relation definition on Parse to get the related item.
2014-05-11 02:16:02.878 Basic Example[3147:1303] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '(null)'
*** First throw call stack:
(
0 CoreFoundation 0x02e1b1e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x02b9a8e5 objc_exception_throw + 44
2 Basic Example 0x0013df7b PFSaveManagedObjectContextOrThrowInternalConsistencyException + 331
3 Basic Example 0x0014997c __80-[PFIncrementalStore newValueForRelationship:forObjectWithID:withContext:error:]_block_invoke_5 + 28
4 CoreData 0x00d1984f developerSubmittedBlockToNSManagedObjectContextPerform + 95
5 libdispatch.dylib 0x0312f4d0 _dispatch_client_callout + 14
6 libdispatch.dylib 0x0311c740 _dispatch_barrier_sync_f_invoke + 58
7 libdispatch.dylib 0x0311c3ea dispatch_barrier_sync_f + 89
8 CoreData 0x00d1977f -[NSManagedObjectContext performBlockAndWait:] + 127
9 Basic Example 0x00149924 __80-[PFIncrementalStore newValueForRelationship:forObjectWithID:withContext:error:]_block_invoke_4 + 196
10 CoreData 0x00d1984f developerSubmittedBlockToNSManagedObjectContextPerform + 95
11 CoreData 0x00d1978c -[NSManagedObjectContext performBlockAndWait:] + 140
12 Basic Example 0x0014974e __80-[PFIncrementalStore newValueForRelationship:forObjectWithID:withContext:error:]_block_invoke_3 + 1758
13 Basic Example 0x0014b20c -[PFIncrementalStore insertOrUpdateObjects:ofEntity:withContext:error:completionBlock:] + 460
14 Basic Example 0x00148f4c __80-[PFIncrementalStore newValueForRelationship:forObjectWithID:withContext:error:]_block_invoke_2 + 1180
15 CoreData 0x00d91fe3 developerSubmittedBlockToNSManagedObjectContextPerform_privateasync + 83
16 libdispatch.dylib 0x0312f4d0 _dispatch_client_callout + 14
17 libdispatch.dylib 0x0311d047 _dispatch_queue_drain + 452
18 libdispatch.dylib 0x0311ce42 _dispatch_queue_invoke + 128
19 libdispatch.dylib 0x0311dde2 _dispatch_root_queue_drain + 78
20 libdispatch.dylib 0x0311e127 _dispatch_worker_thread2 + 39
21 libsystem_pthread.dylib 0x0345edab _pthread_wqthread + 336
22 libsystem_pthread.dylib 0x03462cce start_wqthread + 30
)
libc++abi.dylib: terminating with uncaught exception of type NSException
PFFiles are sync'd from parse to local db without a problem. However when a NSData field in the model is created/update the new image is not sync'd back to parse.
Update Error: Error Domain=Parse Code=111 "The operation couldn’t be completed. (Parse error 111.)" UserInfo=0x155ce710 {code=111, error=invalid type for key photo, expected file, but got bytes}
Can you add a brief documentation about how to use this framework?
Objects may be removed from other clients, therefore PFIS should remove objects from the local backing store if it cannot be found during a subsequent fetch. Otherwise, inconsistencies ensue and we have a client out of sync with Parse.
A few things need to be kept in mind:
NSNotification
if an object gets deleted after it has been fetched)I just installed PFIncremental store from cocoa pods and there is an issue in the following method
PFIncrementalStore/PFIncrementalStore.m:970:48: No visible @interface for 'NSString' declares the selector 'isTemporaryID'
I checked the same method in the example project and the following lines
if (![[relationshipValue objectID] isTemporaryID]) {
should be replaced with
NSManagedObject *relatedObject = (NSManagedObject *)relationshipValue;
if (![[relatedObject objectID] isTemporaryID]) {
https://github.com/AFNetworking/AFIncrementalStore
Again — uses Parse's REST API as well. I think by leveraging existing open-source project, we can structure Parse-specific code around that in consequence, limit the complexity of this project, making it more robust.
PFIncrementalStore should have better inline commenting such that CocoaDocs can be created for the library.
I'm looking for a replacement for FTASync... will this do it?
We need to submit this version to cocoapods
Caching would be very helpful, however it may already be handled via Parse.
Hi,
sbonami,
Not sure if this is an appropriate place to ask this question but if not pls. redirect me to proper location.
I am trying to run & understand the Basic Example & not sure if I am approaching it correctly. There does not seem to be any UI to add artist, songs, genres and their relationships right in the app. Hence I am trying to preload the
Parse database with some test values for those objects. The difficulty I'm having is creating the relationships between the objects, e.g. songArtist. I cannot find a way to do that in the Parse Data Browser. When I try to run the example on the preloaded data without the relationships defined, I get a crash.
Am I approaching this correctly & if so how do you set up the relationships? Any insight you can provide would be gratefully received.
Thx
RB
On occasion I've seen duplicate syncing with objects, notably within the Example apps. This seems to indicate an issue where attributes or relationships are called on an object that isn't faulting or updating correctly.
Has anyone had any success with PFIncremental store? Here: http://sbonami.github.io/PFIncrementalStore/
When I load of the sample project, then add my Parse keys and start the app, I don't see any objects appear in Parse. Additionally, if I implement my own test of the library, and try to save an object, it does not appear in the Parse interface.
Any assistance or insight would be appreciated. Please let me know if there is more information that I can provide.
Thanks in advance.
See: http://stackoverflow.com/questions/25449175/pfincrementalstore-for-ios-has-anyone-made-it-work
We're currently using the Parse iOS SDK on both the iOS and OS X platform, however we should be using the appropriate SDKS for the platforms.
Currently, synced objects with related faulted objects fail. PFIS should either skip faulted objects or fetch related attributes. Checks and balances should be implemented to only sync the portion of the object graph that is necessary.
When I run, xcode prompt:
error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
Please check that you included Podfile.lock or let me know how to run this example.
This repository's URL field should so be set to http://sbonami.github.io/PFIncrementalStore/.
As near as I can tell, fetches from Parse will always be limited to 100 in the current implementation per the default for PFQuery
.
I would suggest that we set the limit
to 1000 wherever a PFQuery
is constructed.
Thoughts?
Hello,
Does this support syncing the Parse User class? If so is there anything special needed to map to a CoreData entity "User"? Also, how do you handle not being able to write to User objects that are not logged in w/o the Master key?
Thanks for putting this together!
-Aaron
Hello, my application is kind of virtual wallet. It has class Wallet which can be local wallet or shared wallet (let's call it shwallet). All data related to wallet is stored locally (Core Data + SQLite). The data related to shwallet needs to be stored both locally and remotely (so that all shwallet members are able to add their transactions to the shwallet). So my goal is to sync local shwallet's transactions with remote shwallet's transactions. What would you suggest me? Thank you.
Parse provides a [PFObject saveEventually]
method that could/should be utilized by PFIncrementalStore when possible.
Currently, predicates are handled via CoreData however some of this can be offloaded to Parse via the API.
PFIS needs better usage instructions for PFFile fields on an object.
I did more test and here is what I have found. Hope it could be a help to you guys:
We need more test coverage of the working internal bits (i.e. private methods).
PFIS forks, followers, and users:
I'm looking for a co-maintainer to keep PFIS alive. I've joined a company as lead dev and can't devote as much time as I'd like to maintain the repo. If you're interested in keeping the repo going, please reach out and discuss.
Thanks!
I have implemented PFIncrementalStore in a simple 2-table coredata project with both tables linked to each other by a to-many relationship.
When saving my managed object to the coredata context, the object gets pushed to Parse (each class gets automatically created the first time) but nothing happens for the relationships?
Am I supposed to pre-define these relationships on Parse?
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.