I am using RestKit for an iOS To app. I already had done following using restkit:
1. Pull server objects from rest api in json format.
2. Delete orphan objects in core data which are no longer present on server.
Now i have to build the following scenario, if the internet is available on the device and user is adding a new data item,then what should i do first i.e should i store the new data first locally and then post to server or first i post the data to server and the pull it back on device ?
Secondly if the internet is not available on device and user inserts a new data item then saves data locally, On internet availability how do i post newly added data items to the server i.e what approach should i follow and if restkit can help me tackling this scenario ?
RestKit includes reachability monitoring (actually part of AFNetworking). So you can set a block to be run when the status changes:
[objectManager.HTTPClient setReachabilityStatusChangeBlock:...
Generally, store the item locally in all cases. When the item has been pushed to the server, set the sync date or a flag on the item to confirm that it has been updated.
This is really a broader question about how you manage local modifications and updates to the server. You may want an overall scheme to list the dirty objects and push updates to the server and have the server response set the sync time for each item. If you use 2 dates (one for the last local modification and one for the remote sync) then a quick predicate fetch on the model will tell you which objects are dirty and need to be pushed to the server.
Related
I have been requested to make my app available off-line, which means storing the data collected via Api for use when no connection available. The problem is that when a new connection is made my local data may be out of date. Also, any changes made while off-line will need to update the server.
I'm aware of a method of syncing databases so that when new connection is made the data is automatically updated both ways. However, after browsing Google I've not found a definitive method of doing this.
Can anyone help point me in the right direction?
There should be a field like a time stamp to indicate last synced time. When ever connection is online go for a fetch validate against the timestamp and update the data in offline storage.
The same way, when you have updates while offline you can set some bool value to check whether data is synced or not and sync when you are online.
I am working on CloudKit sync in my app ("Tiny data, all devices" model, with a custom zone in the private database).
CKModifyRecordsOperation contains clientChangeTokenData property of NSData type which is described in the docs as follows:
When you modify records from a fetch operation, specify a client-generated data token using this property to indicate which version of the record you last modified. Compare the data token you supplied to the data token in the next record fetch to confirm the server has successfully received the device’s last modify request.
I don't get why I should bother given that with each request, I get a completion block which tells me whether the server has successfully received my request. Why do I need to manually compare this client token?
Is specifying clientChangeTokenData required to handle my use case correctly? I track local data changes and push everything in the queue on each data change. Remote changes are tracked via zone subscription.
If it is required, how do I generate this token correctly given that I have all kinds of record changes in my CKModifyRecordsOperation (my API usage aims for batch operations). What is the general workflow here?
Thank you.
It's unclear from the docs so I'd guess the clientChangeTokenData is useful in the case of sending up a large modify records operation, e.g. deleting 100 records. Then say your app sends a fetch request in another operation with a query (or fetch changes) result set that would be affected by the modifications which either:
is started and is running concurrently to the existing modify operation which hasn't finished yet.
is started before the server has finished processing the results of the previous modifications (the docs tend to allude to a processing delay).
If the fetch completion contains a different clientChangeTokenData to the one sent with the modify then you know it hasn't received (or finished processing?) the changes yet. In this situation you could either error, with an alert to say the server needs more time, or automatically retry the fetch after some time.
By the way in my tests, this token is per-device.
You would only have a reason to check the token if you had local changes that you want to write to CloudKit and you want to make sure that your changes are based on the latest version of the data in CloudKit.
You could also just ignore the token and save the data anyway. If the data has changed in the mean time, you will get a CloudKit error and you could handle it then.
Let's say there I have an app that has model structure "Teams" and it's respective "members". This app then pulls data from a web service in json. How does the web service communicate which data has changed and how?
I'm thinking it passes certain JSON keys to notify the app which kinds of updates have occurred. For example:
{"operations": [{"delete":"member1"}, {"add": team2}, {"rename": team3} ... ]}
What are the conventions of doing this?
Edit 1: I am not looking for frameworks that solve this problem. I just want to conceptually know how this is usually done.
Generally the app will ask the server: "What has changed since XXX" and the server will reply with the objects that have changed since that date. The server generally gives full objects for the app to parse and consume.
With that assumption you can get the response from the server and then walk the objects in the JSON payload, loading objects that exist and updating them and then inserting new objects that do not exist locally.
Deletes can be more challenging as most servers that I have seen won't tell you about them. If you control the server then you could send a response with identifiers to objects that have been deleted since the last update.
Our app supports offline activity. Meaning we want to persist locally the creation of new core data objects as well as any modifications on existing objects. Then when the app goes online again we automatically push those changes (and any dependencies) up to the server.
I would think that RestKit would support such an operation, but currently when offline we store creations/modifications in a local cache. If I kill the app, those changes are not persisted. And also there is no attempt by RestKit to post those items to their originally intended endpoints.
I cannot find any documentation to support what we need here.
Is there a way for RestKit to do what we need?
If not, how do I get offline changes to persist to the disk (and not cache)? Then would it be appropriate to flag those as not uploaded to server, and then try uploading them when we are back online?
Any other important things I should consider?
At the time of writing RestKit does not support that feature.
To save to disk you need to call saveToPersistentStore: instead of just save: on the MOC.
You need to implement a scheme yourself, observing the 'online' status of the app and scanning the data store for things that need to be uploaded (which means maintaining a flag to indicate if it's happened yet).
I solved this issue by adding another field called 'updated' to my object. This field is set to true or 1 when the object is created or modified. Each time the application is started or synchronized, it iterates through the local core data copy and sends the objects with 'updated' set. On the web service, the response ALWAYS clears 'updated' to false when returning a response. This works well in the case where the web service and app are both online.
I’m developing a iOS App and I want to have a level of offline support and I’m struggling out of local datastore or cache which approach to use as It appears that you can’t use these two feature together.
My query is quite basic and doesn’t change only the data that is retrieved can change.
if i used one of the cache policies, i get connection errors and nothing appears to be returned from the cache.
The workflow i’m after is on the lines of below.
->When connected to the internet perform query and store objects locally.
->if there is no internet retrieve previously downloaded objects.
For the workflow you describe I think you're looking for a cache. If you would like the user could modify the data without connection and then, when there is wifi again, synchronise the local data with the remote data then you'll need the local datastore behavior.
The problem for me is when you want both in different parts of the same app because in parse in you use local datastore you can't use the cache. I don't really understand why!