Mobile application data management
Asked Answered
N

4

9

My question surrounds around one single point - data management in mobile application. I have created a mobile application where data comes from server. The data includes both text and images. Following are the steps I am doing for this :

First launch :
1. Get server data.
2. Save server data in Sqlite database.
3. Show Sqlite data.

Next launches :
1. Show Sqlite data.
2. Get server data in background.
3. Delete previous Sqlite data.
4. Save new server data in Sqlite database.
5. Show Sqlite data.

I have couple of questions on these steps :
1. Is this the right approach ? Other way could be showing data every time from server but that would not display the data on screen immediately (depending on internet speed).
2. I also thought of comparing the Sqlite data with the new server data. But faced a big challenge. The new server data might have new records or deleted records. Also, I could not find an appropriate approach to compare each database field with JSON data.
So what is the best approach to compare local Sqlite data with new server data ?
3. Each time I delete the Sqlite data and insert new data and then refresh the screen (which has a UITableView), it blinks for a second which is obvious. How to avoid this issue if steps 3, 4, 5 are followed ?
4. How should I proceed with data update in case I come back on the screen each time or when the application becomes active ? I am very aware of NSOperationQueues or using GCD for that matter. But what if I am crazy and go back and forth to screen again and again. There will be a number of NSOperations in the queue.

Neils answered 7/10, 2015 at 10:24 Comment(4)
in your approach , if server data does not contain new data/ somthing change in server. also for this situation you are downloading the server data in the backgound?Exhilarant
@jamil65able : Yes that is.Neils
@Neils R u Coding for both server side and device sideCimbri
It sounds like the data is read-only in that the user never modifies it and it never needs to be pushed back to the server. Is this correct? If this is so, the job is a bit easier. If there's something that could be considered a primary key, then it would be easier still, but it sounds like you're considering every piece of data to be unique? Do you have an idea of uniqueness, or do you always just want all the data from the server. If you can avoid replacing data in the UI you might be able to avoid the flicker. Is there an ordering to the data? This will help us answer. Thanks.Blurt
P
2

It's a challenge to synchronise server data, I've done that before, and if you can spend time on it I'd say it's the best solution.

You may need creation and modification dates on both server and local objects, to compare them - this will let you decide which objects to add, update and delete. If the server sends you only the recently updated objects you can save a lot of traffic and improve performance (but deleted objects will be harder to detect).

If the data is only changed in the server it's easier, when the app can change the data too it becomes more complicated (but it seems that it's not your case). It also depends on how complex the database is, of course.

If you don't want to invest some time in doing this, just fetching all data everytime works too, even if it is not ideal! Instead of showing the old data and blinking it, you can just make the user wait 2-3 seconds when entering, while you get the new data. Or instead you can fetch the data only when starting the app, and so when you get to that view controller it will be ready already.

It's a complex problem that everyone faces at some point, so I'm curious to see what other people will suggest :)

Polytypic answered 7/10, 2015 at 10:46 Comment(2)
Thanks for your thoughts. Data can be changed from the App as well. The local database which I have is not similar to the complex server database. I am creating table on the basis of what I need to show on the screen. JSON has a lot of data fields which I don't require and which I haven't included in the tables. Waiting for 2-3 seconds is a good option but as per client, data should be immediately shown.Neils
Just select what objects you need on the JSON (comparing the modification dates), and add/update each of those in the database. If the JSON has too much data and it takes a long time to receive/parse, you may need to ask the server-side people for a simpler webservice :)Polytypic
R
2

This is a good question.

I personally think downloading data, store locally and later try to sync is a dangerous scenario. Easy to introduce bugs, master <-> slave issues (what data should be master, if multiple devices would be used etc.)

I think something like this could be a working approach:

1. I would try to look at possibilities to lazy load the data from the server on-demand. That is when a user have a View that should display data, load that specific data with the creation of that specific View. This ensures the data is allways in sync.

2. Tackling the need to reload data from server from every view, could be done by simply storing the downloaded data as objects in memory (not using SqlLite). The view will try to load the needed data trough your cache manager, and it would serve it from memory, if available. If not in memory simply get the data from your server and add it to your memory cache. The memory cache could be a home made data manager wrapping a Dictionary stored on you AppDelegate, or some global "Singelton" to wrap the cache management/storing and data loading.

3. With lazy loaded data and memory cache you would need to make sure any updates (changes, new records, deleted records) updates your memory data model, as well as pushing these changes to the server as soon as possible. Depending on data size etc. you could force the user to wait, or do it directly as background process.

4. To ensure the data is in sync, you should make sure that you periodically invalidate (delete) the local memory records in the cache and thereby force data updates from the server. Best approach would probably be to have a last updated timestamp for each record in the memory cache. So the periodical invalidator would only delete "old records" from the memory cache (once again not from the server).

To save server from unnecessary data load, the data should still load on demand when the user needs it in a view, and not as part of "cache invalidation".

5. Depending on the data size you might need to look at "cache invalidation". Could be as simple as when xx records are stored, start deleting old objects from memory cache (not server, only locally on device).

6. If data sync is absolutely critical you might want to look at refreshing your memory cache for a record, just before you allow the user to change data. E.g. when user taps "Edit" or similar, you grab the latest data from server for that record. This is just to make sure the user is not going to update a record using outdated data and thereby accidentally overriding any changes made remote, or on another device etc.

--

My take on it. I do not believe there is a "perfect right way" to do this. But this would be what I would try to do.

Hope this will help with some ideas and inspiration.

enter image description here

Ruralize answered 16/10, 2015 at 10:52 Comment(0)
D
1

How about this:

  1. If data exists in SqlLite, load into "in-memory" copy and show it
  2. In background load new server data
  3. delete old sqlite data if it exists (note that the in-memory copy remains)
  4. save new server data to sqlite
  5. load new sqlite data into "in-memory" copy and show it.

If no data was found in step 1, display a "loading" screen to the user during step 2.

I'm making the assumption that the data from SqlLite is small enough to keep a copy in memory to show in your UITable view (The UITable view would always show data from in-memory).

It may be possible to combine steps 4 and 5 if the data is small enough to hold two copies in memory at the same time (you would create a new in-memory copy and swap with the visible copy when complete).

Note: I don't talk about error handling here, but I would suggest that you don't delete the sqlite data until you have new data to replace it with.

This approach also eliminates the need to determine if this is the first launch or not. The logic always remains the same which should make it a little easier to implement.

Hope this is useful.

Deviate answered 10/10, 2015 at 23:27 Comment(0)
S
1

You can do same things more efficiently by MultiVersion Concurrency Control (MVCC), which uses a counter (sort of a very simple "time stamp") for every data record, which is updated whenever the record is changed means you need to get those data which is Updated after last sync call that reduces lots of redundant data and bandwidth.

Source: MultiVersion Concurrency Control

Surprisal answered 15/10, 2015 at 8:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.