因為釘釘出了一個打卡黑科技控硼,離線打卡泽论。我們這邊老板說要跟進,我們也做一個打卡卡乾,我看了看翼悴,離線打卡無非就是獲取到用戶當時打卡的時候、地點等一系列的動作幔妨,然后等到有網(wǎng)的時候傳到服務器抄瓦。地點都好說,主要是時間陶冷,因為如果9點打卡钙姊,用戶把時間改成8:58,如果還能打卡成功埂伦,那就是bug了煞额。
我們在網(wǎng)上查了一系列的資料發(fā)現(xiàn)講這方面的不多,所以就記錄一下
獲取準確的本地時間
我們知道iOS獲取現(xiàn)在的時間一般用[NSDate date]
沾谜,這樣獲取的時間一般都會跟著本地時間的變化而變化
然后我們發(fā)現(xiàn)釘釘?shù)谝淮芜M入在沒有網(wǎng)絡的情況下膊毁,也是不能打卡的,說明所謂的黑科技基跑,至少要進行一次網(wǎng)絡請求
然后我們就發(fā)現(xiàn)了
// 手機運行時長
- (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是當前的時候婚温,受本地系統(tǒng)時間的影響
sysctl 獲取的是上次設備重啟的時間,也受本地系統(tǒng)時間的影響
兩者之差就是系統(tǒng)從上次設備重啟之后所運行的時間
看一組數(shù)據(jù)
時間變化前(正常時間):
now = 1493706163
boottime.tv_sec = 1493696768
uptime = 9395
我們隨意改變一下系統(tǒng)時間(調整后的時間):
now = 1493526460
boottime.tv_sec = 1493516751
uptime = 9709
我們還原系統(tǒng)時間(正常時間):
now = 1493706822
boottime.tv_sec = 1493696768
上次設備重啟的時間并沒有變化
設備重啟后:
now = 1493707140
boottime.tv_sec = 1493707074
上次設備重啟的時間發(fā)送了變化
這樣我們就獲取設備運行時間媳否,基本還是準確的
獲取網(wǎng)絡時間
網(wǎng)絡時間只需要設備重啟后栅螟,獲取一次就夠了,獲取到了之后就在根據(jù)獲取時的運行時間和后面調用時候的運行時間進行計算
網(wǎng)絡時間的獲取如果采用Http的獲取篱竭,會有網(wǎng)絡延時力图,慢的話網(wǎng)絡延遲會有十幾秒,所以我們選用了一個三方庫ios-ntp
這樣基本就和釘釘一樣了掺逼,必須要有一次網(wǎng)絡請求之后才能打卡
參考:iOS關于時間的處理
MrPeak大神的文章干貨滿滿的