离线时准确的时间检测 [英] Accurate time detection while offline

查看:149
本文介绍了离线时准确的时间检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个连接到服务器的iOS应用程序,并且可以从设备向服务器发出请求以同步本地数据库服务器的数据库。任何一个数据库都可能发生更改。该应用程序还具有脱机功能,用户可以在不连接到Internet连接的情况下修改数据,只有通过发送新数据和从服务器接收更新才能将设备的本地数据库与服务器的数据库同步。

I am developing an iOS application that is connected to a server, and requests can be made from the device towards the server to synchronize the local database with the server's database. Changes can occur on either one of the databases. The application also has an offline feature, where users can modify the data without being connected to an internet connection, and only going online in order to synchronize the device's local database with the server's database, by sending new data and receiving updates from the server.

更新了更多背景信息:处理的数据是必须在一定时间内完成的表格。它的启动时间作为属性存储在模型上,并且使用所述属性,应用程序向用户显示此表单被锁定之前剩余的时间。

Updated with more background information: The data handled is a form that must be completed in a certain amount of time. The time it is started is stored as a property on the model, and using said property, the application shows the user how much time left before this form is locked.

当设备离线时,用户可以操作时间设置,这会使从此设备接收的数据不准确。

While the device is offline, the user can manipulate the time settings, which would make the data received from this device inaccurate.

我已经搜索了一种检测设备时间设置更改的方法,但是根据这个SO答案,除非我的应用程序在后台运行,但Apple非常严格,并且除非应用程序具有后台模式,这些不适用于应用程序。

I have searched for a way to detect changes to the device time settings but according to this SO answer, that does not seem to be possible unless my application is running in the background, which Apple is very strict about, and does not allow unless the application had one of the background modes enabled, which are not applicable in the application.

更新了更多信息:正如我在上面背景信息的更新部分中提到的,数据是可能有时间限制的表单。因此,用户可以在一个设备上启动表单,但不能在那里完成。然后他们会将数据同步到服务器,跳转到另一台设备并完成相同的表格。

Updated with more information: As I mentioned in the updated part of the background information above, the data is forms that could have a time limit. Therefore a user can start a form on one device, but not finish it there. They would then synchronize the data to the server, jump to another device and complete the same form.

我最接近解决这个问题的方法是在安装应用程序时获得服务器时间和设备时间之间的差异(肯定是第一个在线)打开应用程序的时间,以便为此设备配置它,并在我想存储与时间相关的值时使用此差异作为参考。

The closest I've come to solving this problem is to get the difference between the server time and the device time when the application is installed (It is sure to be online the first time the application is opened in order to configure it for this device), and using this difference as reference whenever I want to store a time-related value.

如果服务器检测到时间差异,它将拒绝来自此设备的所有数据,这将强制设备恢复数据,更新时间差,然后才能从此设备接收数据。

If the server detects a difference in the time, it will reject all data coming from this device, which will force the device to revert the data, update the time difference, and only then will data be accepted from this device.

问题在于,当设备处于脱机状态时,用户可以更改时间设置,对数据执行更改,然后将时间设置恢复为之前的状态,然后再联机。然后,服务器将检测到时间设置没有变化,并接受无效数据。

The problem is that while the device is offline, the user could change the time settings, perform changes on the data, and then returning the time settings to what they were earlier before going online. The server would then detect no changes in time settings and will accept the invalid data.

更新以添加另一个建议的解决方案:详细说明我在下面的问题中的说明,以及@Krypton的评论,由于与上述解决方案相同的问题,设备的正常运行时间对我的情况没有多大帮助。

Update to add another proposed solution: To elaborate more on my note in the questions below, and the comments with @Krypton, the uptime of the device does not help much in my situation because of the same problem as the above solution.

将设备的正常运行时间与服务器时间进行比较是完美的,直到用户重新启动设备。它不是由用户手动更改的,但是只需要一次重启就可以破坏所有内容,这会为我产生相同的不准确数据。修复它需要计算新的差异,这在设备离线时无效。

Taking the device's uptime and comparing it to the server time is perfect, until the user reboots the device. It is not manually changeable by the user, however all it takes it one reboot to break everything, which would yield the same inaccurate data for me. Fixing it would require calculating the new difference, which would not help when the device is offline.



  1. 保存与时间相关的值时,是否存在可以作为参考的不可更改的时间戳,以使其不受$ b的影响$ b会改变用户的设备时间吗?一个例子是
    自设备首次激活以来的时间。 (注意:我最近发现任何相关的
    是设备的
    正常运行时间,但这对我的帮助不大情况)

  2. 有没有办法知道当前的时间而不需要
    每当与时间相关的值保存时都会上线?

  3. 有没有办法解决我建议的解决方案,或者更好的
    解决方案?

  1. Is there an unchangeable timestamp that can be used as reference when saving a time-related value, such that it cannot be affected by changes to device time from the user? An example of this would be the time since the device was first activated. (Note: The closest I have come to finding anything related is the uptime of the device, but that doesn't help much in my situation)
  2. Is there a way any way to know the current time without the need to go online whenever a time-related value is going to be saved?
  3. Is there a way to fix my proposed solution, or any better solution?


推荐答案

有三种方法可以在设备上获得时间。

There are three ways to get the time on a device.


  1. NSDate 。用户可以修改的时间。

  2. mach_absolute_time 。这是设备的绝对时间。但正如您所指出的,这会破坏设备重启的一切。此外,当设备暂停时,这将不正确。

  3. 启动时间。自启动以来的时间。使用正常运行时间来获取此信息。

  1. NSDate. The time the user can modify.
  2. mach_absolute_time. This is the device's absolute time. But as you pointed out, this breaks everything on a device reboot. Also, this will get incorrect when the device is suspended.
  3. Boot time. The time since boot. Use uptime to get this.

您将需要使用组合 NSDate 正常运行时间。也许您可以保存对表单所做的任何更改的时间戳。您将能够计算这些值在更改之间的任何差异,并为您的应用程序执行必要的计算。如果可能,您可能还希望保存并与服务器时间进行比较。

You will want to use a combination of NSDate and uptime. Perhaps you could save the timestamp of both on any changes made to the form. You'll be able to calculate any difference between these values on changes and do the necessary calculations for your application. You may also want to save and compare with the server time if possible.

现在仍然存在重启设备的问题。如果您能够获取设备启动的时间,则可以计算上次保存的 NSDate 与启动时间之间的差异。幸运的是,这是可能的。有关可能的方法,请参阅此答案或任何其他答案。请注意,实施此操作可能会导致小的(1-10秒)不准确。

Now there is still the issue of a restarted device. If you were able fetch the time the device booted, you can calculate the difference between your last saved NSDate and boot time. Luckily, that is possible. See this answer or any of the other answers for possible ways to do so. Do note that implementing this could cause a small (1-10 seconds) inaccuracy.

另一个选项是在设备重启后不允许应用程序在没有互联网连接的情况下启动。

Another option is not allowing the app to start without an internet connection after device reboot.

此外, NSSystemClockDidChangeNotification 应该能够提供帮助。

Also, the NSSystemClockDidChangeNotification should be able to help.

编辑:我将如何做到这一点。请记住,这并不完美,无论您选择什么,都会有权衡。

This how I would do this. Keep in mind, this is not perfect and whatever you choose, there will be trade-offs.

当您有互联网连接时,您可以经常获取服务器时间并将其保存在模型中。这允许您计算设备时间和服务器时间之间的时间差。您可以通过将正常运行时间 NSDate 保存为模型中的时间戳来完成此操作。如果设备尚未重置,请使用正常运行时间。计算启动的 NSDate 见这里),然后开始测量再次。如果这些差异发生显着变化,您就会知道时间被篡改了。请记住,即使用户没有更改时间(测量错误,夏令时......), 的这些差异也会发生变化。您的考虑很大程度上取决于您的应用程序。

You can fetch the server time every so often when you have an internet connection and save this in the model. This allows you to calculate the time difference between the device time and your server's time. You can do this by saving the uptime and NSDate as timestamps in your model. If the device has not been reset, use uptime. Calculate the NSDate of boot (see here), and start measuring again. If these differences change significantly, you know the time's been tampered with. Keep in mind that these differences will change, even if the user does not change the time (measuring mistakes, daylight saving time...). What you consider significantly depends a lot on your application.

如果时间已经改变,你必须决定你想做什么。您可以考虑计算所用时间是否不超过最大值(如果设备尚未重置,则使用正常运行时间)或者可以完全放弃更改。

Then you have to decide what you want to do if the time has been changed. You can consider calculating if the time taken wasn't longer than the maximum (use uptime if the device hasn't been reset) or maybe discard the changes altogether.

这篇关于离线时准确的时间检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆