Start a new topic
Answered

Persistently save data

My app should work without internet connection.


I used the sync mode in DataStore and everything works perfectly until I quit the app.


When quitting and restarting the app all data is lost because the pull operation fails.


I tried to use NSKeyedArchiver.archiveRootObject, however it does not work since Entity is not a subclass of NSObject.


Is there a clean way to save the datastore (or the data) with Kinvey?

I was thinking to use the JSON representation, but I believe that is kind of an hacking


Thanks Teseo


Best Answer
Teseoch,

When you pull the data for the first time, it is saved to the device locally. This local data is maintained/ persisted across multiple app runs (killing the app and then restarting it). So when you quit the app and restart it (network is turned off), the app will fetch the data from local copy of sync datastore as it is already stored in persistent memory. I have implemented your scenario and it is working fine in offline mode. Following is my code for accessing data from local datastore copy:

 

        let user = Kinvey.sharedClient.activeUser as! CustomUser
        print(user) // Just confirming who is the active user
        
        let dataStore = DataStore<Book>.collection(.sync)  // Get an instance of sync datastore
        
	// Following method will find the data locally on the device.
        dataStore.find() { (books, error) -> Void in
            if let books = books {
                //succeed
                print("Books: \(books)")
            } else {
                //fail
            }
        }

 



Also, when you restart your app in offline mode, sync call fails. You can handle this condition by adding a check for internet availability. If online then only make a sync call otherwise skip it.



Your last question was about saving login credentials in the keychain. You don't need to do that as Kinvey does this automatically. Credentials of the logged in user are saved in the device keychain. The keychain persists data even if the app is deleted. If the app is reinstalled, it will use the stored credentials. After a successful login of a user, that user becomes an active user and it can be obtained by "Kinvey.sharedClient.activeUser" (If you successfully obtain it, you don't need to login). For more information on active user concept, check http://devcenter.kinvey.com/ios/guides/users#ActiveUser.

Login is needed only when a user exists in the app backend but has not been established in the application session (active user). Common scenarios when this is necessary:

  1. The application launches and an active user is not yet established
  2. The application is reinstalled on the same or a new device for a user who already has an account established on the back-end
  3. The user has logged out and the application needs to make more calls to Kinvey


Once the user logs in successfully, the library sets the active user and caches the user's authentication tokens for subsequent use.




Thanks,

Pranav

Kinvey


 


Answer
Teseoch,

When you pull the data for the first time, it is saved to the device locally. This local data is maintained/ persisted across multiple app runs (killing the app and then restarting it). So when you quit the app and restart it (network is turned off), the app will fetch the data from local copy of sync datastore as it is already stored in persistent memory. I have implemented your scenario and it is working fine in offline mode. Following is my code for accessing data from local datastore copy:

 

        let user = Kinvey.sharedClient.activeUser as! CustomUser
        print(user) // Just confirming who is the active user
        
        let dataStore = DataStore<Book>.collection(.sync)  // Get an instance of sync datastore
        
	// Following method will find the data locally on the device.
        dataStore.find() { (books, error) -> Void in
            if let books = books {
                //succeed
                print("Books: \(books)")
            } else {
                //fail
            }
        }

 



Also, when you restart your app in offline mode, sync call fails. You can handle this condition by adding a check for internet availability. If online then only make a sync call otherwise skip it.



Your last question was about saving login credentials in the keychain. You don't need to do that as Kinvey does this automatically. Credentials of the logged in user are saved in the device keychain. The keychain persists data even if the app is deleted. If the app is reinstalled, it will use the stored credentials. After a successful login of a user, that user becomes an active user and it can be obtained by "Kinvey.sharedClient.activeUser" (If you successfully obtain it, you don't need to login). For more information on active user concept, check http://devcenter.kinvey.com/ios/guides/users#ActiveUser.

Login is needed only when a user exists in the app backend but has not been established in the application session (active user). Common scenarios when this is necessary:

  1. The application launches and an active user is not yet established
  2. The application is reinstalled on the same or a new device for a user who already has an account established on the back-end
  3. The user has logged out and the application needs to make more calls to Kinvey


Once the user logs in successfully, the library sets the active user and caches the user's authentication tokens for subsequent use.




Thanks,

Pranav

Kinvey


 


1 person likes this

Thanks!


To summarise:

I call ping to check if I can communicate with the backend

in case of error i call find

otherwise i call sync


Is there a similar mechanism for the files?


thanks again Teseo

Teseoch,

Check this link http://devcenter.kinvey.com/ios/guides/files#Download. By default, files are cached in order to improve performance. Have you tried implementing it?

Let me know if you get any errors while implementation.

Thanks,
Pranav
Kinvey

 

Teseoch,

When you started the app for the first time, was the pull operation successful (first pull call will need network)? Because you will need to pull the copy of your data to the device first and work with it completely offline.

Please take a look at http://devcenter.kinvey.com/ios/guides/datastore#syncStore.

Also, If your Sync Store has pending local changes, they must be pushed to the backend before pulling data to the store.

Thanks,
Pranav
Kinvey

 

Hi, I never use pull, but only sync (which according to the documentation fires a pull). Anyhow it is successful and i can see all the data in my app. Also if i turn off the network everything work fine. The problem comes when i quit the app. On startup i perform a sync and it fails because there is no network. For this reason I would like to save the data (or the datastore) in the persistent memory of the phone using NSKeyedArchiver. I would like to have a similar mechanism as for the login which is saved in the keychain automatically, and the login does not fail even without network Thanks again Teseo
Login or Signup to post a comment