時間を確保するための信頼できる方法を探しています。改ざんすることはできず、オフラインで作業する必要があります。したがって、インターネット時間、設定でのユーザー時間の設定、および最後の再起動以降の BSD アップタイム時間はありません。GPS は原子時計を使って動いているので、その情報にアクセスできるかどうか疑問に思っていました。
ありがとうございました
これは GPS 時刻を取得するために機能します。
#import <CoreLocation/CoreLocation.h>
CLLocation* gps = [[CLLocation alloc]
initWithLatitude:(CLLocationDegrees) 0.0
longitude:(CLLocationDegrees) 0.0];
NSDate* now = gps.timestamp;
ただし、改ざん防止ではないようです。
機内モード (iOS 6.1) の iPhone 4 でこのコードを試してみましたが、それでも問題なく時間が表示されます。ただ、残念ながら今回はシステムクロックで変わるようです。うーん。
私が見つけた面白いこと (まだ機内モード) は、システム クロックを改ざんして (off
時刻と日付のに切り替えた後Set Automatically
)、次に にSet Automatically
戻すとon
、マシンは問題なく実際の (元の) 時刻を復元することです。これは、電話の電源を入れ直した後でも機能します。そのため、デバイスが内部で保持している耐タンパー時間のようなものがあるようです。しかし、これにアクセスする方法は?
PS 2010 年のこれに関する議論。最後から 2 番目のコメントの著者は放射性降下物シェルターでこれを試しました。したがって、電話が外部ソースから元の時間を取得していないことは明らかです。
別の種類の時間測定: システム カーネルの起動時間に関するいくつかの投稿 (ここ、ここ、ここ) を見つけました。次のような呼び出しでアクセスします: sysctlbyname("kern.boottime", &boottime, &size, NULL, 0);
. 残念ながら、再起動しなくても、ユーザーが調整したデータと時刻によっても変化します。別の関数gettimeofday()
も同様に、ユーザー定義の時間に依存しています。
NSDate とそれに対応する CF はすべて、ユーザーが制御できる時間に基づいているため、改ざん防止にはなりません。
私の知る限り、GPS 時間またはキャリア時間に直接対応するオープン API はありません。ただし、mach_absolute_time をチェックして、前回の起動から改ざんされていない時間を取得し、おそらくそれを使用して、アプリが起動されてから経過した時間を少なくとも知ることができます (その間、その時間が改ざんされる可能性はありません)。アプリが実行されています)。
mach_absolute_time は、デバイスのプロセッサによって異なります。デバイスが最後に再起動されてからのティックを返します (稼働時間とも呼ばれます)。人間が読める形式で取得するには、mach_timebase_info (比率) の結果によって変更する必要があります。これにより、10 億分の 1 秒 (またはナノ秒) が返されます。これをより使いやすくするために、次のような関数を使用します。
#include <mach/mach_time.h>
int getUptimeInMilliseconds()
{
static const int64_t kOneMillion = 1000 * 1000;
static mach_timebase_info_data_t s_timebase_info;
if (s_timebase_info.denom == 0) {
(void) mach_timebase_info(&s_timebase_info);
}
// mach_absolute_time() returns billionth of seconds,
// so divide by one million to get milliseconds
return (int)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
}
GPS から時刻を取得できたとしても、GPS 時刻は UTC とまったく同じではないことに注意してください。ただし、iPhone の GPS 受信機がそれを処理してくれるかもしれません。
これにより、現在の日付と時刻が取得されます。
NSDate *now = [NSDate date];
これはあなたが得ることができるのと同じくらい信頼できます。NTP サーバーにアクセスできるようになると、iPhone の内部時計が更新されます。電話が時刻同期ソースとして GPS を使用している場合、上記の方法でアクセスできる同じシステム全体の時計を更新するためにも使用されます。
CoreFoundation に相当するものは次のようなものです。
CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
これは、通常の UNIX からのエポック秒のタイムスタンプに相当する CoreFoundation を返します。