【问题标题】:iOS how to detect user has changed system time, and if not compare device time with server timeiOS如何检测用户更改了系统时间,如果没有将设备时间与服务器时间进行比较
【发布时间】:2015-12-04 03:19:33
【问题描述】:

要求是必须检测 iPhone 的系统时间是否被用户手动更改。为此我使用了

NSNotificationCenter.defaultCenter().addObserver(self, selector: "timeChangedNotification:", name: NSSystemClockDidChangeNotification, object: nil)

 func timeChangedNotification(notification:NSNotification){
    println("Device time has been changed...")
    }

但没有得到结果。 此外,如果这个时间没有改变意味着它是网络提供的自动时间,那么必须与服务器时间进行比较。如何做到这一点?请提供相同的帮助。

【问题讨论】:

    标签: ios swift clock


    【解决方案1】:

    根据其文档,NSSystemClockDidChangeNotification 是:

    在系统时钟更改时发布。这可以通过调用 settimeofday() 或用户更改 Date and Time Preference 面板中的值来启动。

    因此,除非您希望用户在您的应用运行时更改日期或时间,否则您显然不会听到任何声音。通知由事件触发。

    iOS 没有为您提供一种方式来询问系统认为时间和日期是当前值的权限 - 无论是运营商网络时间、时间服务器时间、用户提供的时间还是其他什么。没有单一的服务器时间,也没有办法要求它。想做的事做不到。

    【讨论】:

      【解决方案2】:

      我已经尝试了 3 个选项来为我所做的企业应用程序执行此操作,这需要时间始终在用户之间保持同步。由于我们无法控制用户对设备时间的设置,我也面临着你的困境:

      选项 1 - 使用 GPS 时间:我尝试获取 GPS 时间戳并将其与本地设备时间进行比较。它在某些国家有效,但在其他国家无效。其他国家出于某种原因返回设备时间。

      选项 2 - 使用后台进程来估计大致时间。每当您的应用程序进入后台时,您所做的是获取时间戳。运行一个每 5 分钟触发一次的计时器(+/- 取决于您的容忍度)。然后通过将您的应用程序激活时经过的 5 分钟滴答声添加到存储的时间戳来计算估计时间。但是,这种方法只能在您的应用程序已经运行时检测时间是否已更改。如果时间在您的应用程序启动之前更改,则不会。

      选项 3 - 在后端使用时间检查。这就是我最终要做的。我有一个返回 UTC 时间的小型 php 后端程序。因此,每次我的应用程序执行或返回到前台时,我的应用程序都会根据我的时间服务器快速检查时间。为了处理离线情况,我存储了系统进入后台之前的最后一个时间戳,这样您至少可以检查日期/时间是否回溯。待系统上线后再与时间服务器核对。

      到目前为止,这是对我有用的第三个选项。但我想结合 2 和 3 甚至会使系统更加防拉。

      【讨论】:

      • 第三种方法存在一个问题。我正在开发的应用程序是时间跟踪应用程序。如果用户杀死应用程序,拉回时间,在我的应用程序中记录时间,将时间提前并再次记录时间。如果他在第二次录制后打开应用程序。存储在应用程序或服务器中的时间戳是没有用的。由于时间已经过去了,我们当时没有与服务器同步。
      • hmm 他杀死应用程序后如何“记录我的应用程序中的时间”?或者我不明白这个场景。他必须做的是在他再次运行应用程序之前将时间放回去,这样应用程序就不会知道时间发生了变化。但那毕竟是意图。在我的用例中,这通常是由于用户退出应用程序、玩糖果迷、弄乱时间以获取更多宝石、忘记更正时间并再次运行我的应用程序造成的。
      【解决方案3】:
          This code worked for me in Swift 3
      
          NotificationCenter.default.addObserver(self, selector: #selector(ClassName.timeChangedNotification), name: NSNotification.Name.NSSystemClockDidChange, object: nil)
          }
      
          // Method get called user changed the system time manually.
      
          func timeChangedNotification(notification:NSNotification){
              print("Device time has been changed...")
          }
      

      【讨论】:

        【解决方案4】:

        已经有一段时间了,但它可能对将来会像我今天一样发现这个问题的任何人有用。

        您也可以使用NTP protocol 了解您的应用进入后台/前台或在didFinishLaunching 中的真实纪元时间。不过,这需要应用程序在线。但在大多数情况下它会有所帮助。

        至少有两个适用于 iOS 和 Android 的开源库可以提供帮助:TrueTimeKronos

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-30
          • 2015-05-08
          相关资源
          最近更新 更多