移动应用数据管理

时间:2015-10-07 10:24:34

标签: ios sqlite uitableview mobile-application data-management

我的问题围绕着一个点 - 移动应用程序中的数据管理。我创建了一个移动应用程序,其中数据来自服务器。数据包括文本和图像。以下是我为此所做的步骤:

  

首次发布:
  1.获取服务器数据   2.在Sqlite数据库中保存服务器数据   3.显示Sqlite数据。

     

接下来发布:
  1.显示Sqlite数据   2.在后台获取服务器数据   3.删除以前的Sqlite数据   4.在Sqlite数据库中保存新的服务器数据   5.显示Sqlite数据。

我对这些步骤有几个问题:
1. 这是正确的方法吗?其他方式可能是每次从服务器显示数据,但不会立即在屏幕上显示数据(取决于互联网速度)。
2.我还想过将Sqlite数据与新服务器数据进行比较。但面临着巨大的挑战。新服务器数据可能具有新记录或已删除记录。另外,我找不到合适的方法来将每个数据库字段与JSON数据进行比较 那么将本地Sqlite数据与新服务器数据进行比较的最佳方法是什么?
3.每次我删除Sqlite数据并插入新数据然后刷新屏幕(具有UITableView)时,它会闪烁一秒钟,这很明显。 如果遵循步骤3,4,5,如何避免此问题?
4. 如果我每次或在应用程序变为活动状态时返回屏幕,我应该如何继续进行数据更新?我非常了解NSOperationQueues或使用GCD对于这个问题。但是如果我疯了又一次又一次地来回屏幕怎么办?队列中将有一些NSOperations

4 个答案:

答案 0 :(得分:2)

同步服务器数据是一个挑战,我以前做过,如果你可以花时间,我会说这是最好的解决方案。

您可能需要在服务器和本地对象上创建和修改日期,以便比较它们 - 这将允许您决定要添加,更新和删除的对象。 如果服务器仅向您发送最近更新的对象,则可以节省大量流量并提高性能(但删除的对象将更难检测)。

如果数据仅在服务器中更改,则更容易,当应用程序也可以更改数据时,它变得更加复杂(但似乎不是你的情况)。当然,这还取决于数据库的复杂程度。

如果您不想花一些时间来做这件事,那么每次获取所有数据也是有效的,即使它不理想!您可以在输入时让用户等待2-3秒,而不是显示旧数据并使其闪烁,同时获取新数据。或者你只能在启动应用程序时获取数据,所以当你到达那个视图控制器时它就已经准备好了。

这是一个每个人都会在某个时刻面临的复杂问题,所以我很想知道其他人会提出什么建议:)

答案 1 :(得分:2)

这是一个很好的问题。

我个人认为下载数据,本地存储以及稍后尝试同步是一种危险的情况。易于引入错误,掌握< - >奴隶问题(如果要使用多个设备等,应该掌握哪些数据)

我认为这样的事情可能是一种有效的方法:

1。我会尝试根据需要延迟加载来自服务器的数据。也就是说,当用户拥有应显示数据的View时,通过创建特定View来加载特定数据。这可确保数据始终保持同步。

2. 通过简单地将下载的数据作为对象存储在内存中(不使用SqlLite),可以解决从每个视图重新加载服务器数据的需要。该视图将尝试通过缓存管理器加载所需的数据,如果可用,它将从内存中提供。如果不在内存中,只需从服务器获取数据并将其添加到内存缓存中。 内存缓存可以是一个自制数据管理器,包含存储在Dictionary AppDelegate上的myCamera = getCameraInstance(); mediaRecorder = new MediaRecorder(); myCamera.unlock(); mediaRecorder.setCamera(myCamera); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); mediaRecorder.setPreviewDisplay(mSurfaceView.getHolder().getSurface()); ,或者某些全局" Singelton"包装缓存管理/存储和数据加载。

3. 对于延迟加载的数据和内存缓存,您需要确保更新(更改,新记录,已删除的记录)更新内存数据模型,并将这些更改推送到服务器尽快。根据数据大小等,您可以强制用户等待,或者直接将其作为后台进程。

4. 为确保数据同步,您应确保定期使缓存中的本地内存记录无效(删除),从而强制从服务器更新数据。最佳方法可能是为内存缓存中的每条记录设置最后更新的时间戳。所以定期的无效者只会删除旧记录"来自内存缓存(再次不是来自服务器)。

为了使服务器免于不必要的数据加载,当用户在视图中需要数据时,数据仍应按需加载,而不是作为"缓存失效的一部分"。

5。根据您可能需要查看的数据大小"缓存失效"。可能就像存储xx记录时一样简单,开始从内存缓存中删除旧对象(不是服务器,只在设备上本地删除)。

6。如果数据同步非常关键,您可能需要在允许用户更改数据之前查看为记录刷新内存缓存。例如。当用户点击"编辑"或类似的,您从服务器获取该记录的最新数据。这只是为了确保用户不会使用过期数据更新记录,从而意外地覆盖远程或其他设备等所做的任何更改。

-

我接受它。我不相信有一个完美的正确方式"去做这个。但这将是我想要做的事情。

希望这将有助于一些想法和灵感。

enter image description here

答案 2 :(得分:1)

这个怎么样:

  1. 如果SqlLite中存在数据,则加载到" in-memory"复制并展示
  2. 在后台加载新服务器数据
  3. 删除旧的sqlite数据(如果存在)(请注意内存中的副本仍然存在)
  4. 将新服务器数据保存到sqlite
  5. 将新的sqlite数据加载到"内存中"复制并展示它。
  6. 如果在步骤1中未找到任何数据,则显示" loading"在步骤2中向用户显示屏幕。

    我假设SqlLite中的数据足够小,可以在内存中保留副本以显示在UITable视图中(UITable视图始终显示内存中的数据)。

    如果数据足够小以便同时在内存中保存两个副本,则可以组合步骤4和步骤5(您将创建新的内存中副本并在完成时与可见副本交换)。 / p>

    注意: 我在这里没有谈论错误处理,但我建议您不要删除sqlite数据,直到您有新数据替换它。

    这种方法也消除了确定这是否是第一次发射的需要。逻辑总是保持不变,这应该使它更容易实现。

    希望这很有用。

答案 3 :(得分:1)

你可以通过MultiVersion并发控制(MVCC)更有效地做同样的事情,它为每个数据记录使用一个计数器(一种非常简单的“时间戳”),只要记录被更改就会更新,这意味着你需要获取上次同步调用后更新的数据,减少大量冗余数据和带宽。

来源:MultiVersion Concurrency Control