因為釘釘出了一個打卡黑科技,離線打卡。我們這邊老板說要跟進,我們也做一個打卡,我看了看,離線打卡無非就是獲取到用戶當時打卡的時候、地點等一系列的動作,然后等到有網的時候傳到服務器。地點都好說,主要是時間,因為如果9點打卡,用戶把時間改成8:58,如果還能打卡成功,那就是bug了。
我們在網上查了一系列的資料發現講這方面的不多,所以就記錄一下
獲取準確的本地時間
我們知道iOS獲取現在的時間一般用[NSDate date]
,這樣獲取的時間一般都會跟著本地時間的變化而變化
然后我們發現釘釘第一次進入在沒有網絡的情況下,也是不能打卡的,說明所謂的黑科技,至少要進行一次網絡請求
然后我們就發現了
// 手機運行時長
- (time_t)uptime {
struct timeval boottime;
int mib[2] = {CTL_KERN, KERN_BOOTTIME};
size_t size = sizeof(boottime);
time_t now;
time_t uptime = -1;
(void)time(&now);
if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0)
{
uptime = now - boottime.tv_sec;
}
return uptime;
}
now是當前的時候,受本地系統時間的影響
sysctl 獲取的是上次設備重啟的時間,也受本地系統時間的影響
兩者之差就是系統從上次設備重啟之后所運行的時間
看一組數據
時間變化前(正常時間):
now = 1493706163
boottime.tv_sec = 1493696768
uptime = 9395
我們隨意改變一下系統時間(調整后的時間):
now = 1493526460
boottime.tv_sec = 1493516751
uptime = 9709
我們還原系統時間(正常時間):
now = 1493706822
boottime.tv_sec = 1493696768
上次設備重啟的時間并沒有變化
設備重啟后:
now = 1493707140
boottime.tv_sec = 1493707074
上次設備重啟的時間發送了變化
這樣我們就獲取設備運行時間,基本還是準確的
獲取網絡時間
網絡時間只需要設備重啟后,獲取一次就夠了,獲取到了之后就在根據獲取時的運行時間和后面調用時候的運行時間進行計算
網絡時間的獲取如果采用Http的獲取,會有網絡延時,慢的話網絡延遲會有十幾秒,所以我們選用了一個三方庫ios-ntp
這樣基本就和釘釘一樣了,必須要有一次網絡請求之后才能打卡
參考:iOS關于時間的處理
MrPeak大神的文章干貨滿滿的