Подтвердить что ты не робот

Получить дату и время с Apple Server

Я разрабатываю приложение, которое можно использовать только в определенное время дня. Я не могу получить время локального устройства, так как пользователь может легко изменить время устройства, тем самым обеспечивая доступ к приложению в любое время суток.

Есть ли способ получить текущую дату и время с сервера Apple (или, если нет), есть ли другой способ?

4b9b3361

Ответ 1

Я думаю, что вы должны использовать интернет-сервер времени. Они используют стандартизированный протокол под названием NTP. IOS имеет встроенную поддержку для чтения времени NTP-сервера, но это не доступно для вас, как для разработчика приложений. Либо вы реализуете это сами, либо можете использовать библиотеку с открытым исходным кодом, такую как ios-ntp или HS NTP. Я не использовал ни одного из них сам. Вероятно, неплохо бы проверить положение устройства и определить часовой пояс, чтобы получить настоящее пуленепробиваемое решение.

Здесь вы можете прочитать больше о серверах и прочем; NIST Интернет Сервис Времени

В идеале у вас должен быть список серверов в приложении. Если один из них выходит из строя, вы вызываете следующий NTP-сервер в списке.

Ответ 2

- (NSDate *) CurrentDate 
{
    if ([self hasInternetConnectivity]) // this tests Internet connectivity based off Apple Reachability sample code
    {
        NSSURL * scriptUrl = [NSURL URLWithString: @"http:// <yoursite>. Com / <the 2 line PHP скрипт>. Php"];
        NSData * data = [NSData dataWithContentsOfURL: scriptUrl];

        if (data! = nil) {
            NSString * tempString = [NSString stringWithUTF8String: [data bytes]];
            NSDate * currDate = [NSDate dateWithTimeIntervalSince1970: [tempString doubleValue]];
            NSLog (@ "String returned from the site is:% @ and date is:% @", tempString, [currDate description]);
           return currDate;
             }
        else {
           NSLog (@ "nsdata download failed");
           return [NSDate date];
        }
    }
    else {
    NSLog (@ "InternetConnectivity failed");
        return [NSDate date];
    }
}

Ответ 3

Вы можете использовать этот открытый источник, чтобы получить время от сервера NTP по умолчанию, или выбрать свой сервер: https://github.com/huynguyencong/NHNetworkTime

[[NHNetworkClock sharedNetworkClock] syncWithComplete:^{
        NSLog(@"%s - Time synced %@", __PRETTY_FUNCTION__, [NSDate networkDate]);
    }];

И используйте:

NSDate *networkDate = [NSDate networkDate];

Ответ 4

Ответ Karan имел некоторые опечатки, а также не смог проверить ответ "0" вместо "ноль". (Я реализовал его в своем приложении, и у меня появилось несколько ложных срабатываний из слабых соединений или несанкционированных сетей.)

Я адаптировал его ниже и добавил соответствующий код сервера для тех, кто не знает, о чем говорил Каран. Это реализовано как метод категории в расширении NSDate, поэтому вы можете вызвать его с помощью [NSDate verifiedDate];

+(NSDate*)verifiedDate {
    if([self hasInternetConnectivity]) {
        NSURL *scriptUrl = [NSURL URLWithString:@"http://[yourwebsite].com/timestamp.php"];
        NSData *data = [NSData dataWithContentsOfURL: scriptUrl];

        if(data != nil) {
            NSString *tempString = [NSString stringWithUTF8String:[data bytes]];

            if([tempString doubleValue] > 946684800) { // Date is at least later than 2000 AD, or else something went wrong
                NSDate *currDate = [NSDate dateWithTimeIntervalSince1970:[tempString doubleValue]];
                NSLog(@"verifiedDate: String returned from the site is: %@ and date is: %@", tempString, [currDate description]);
                return currDate;
            } else {
                NSLog(@"verifiedDate: Server returned false timestamp (%@)", tempString);
                return [NSDate date];
            }
        } else {
            NSLog(@"verifiedDate: NSData download failed");
            return [NSDate date];
        }
    } else {
        NSLog(@"verifiedDate: InternetConnectivity failed");
        return [NSDate date];
    }
}

И вот код сервера, хранящийся в корневой папке вашего сервера как "timestamp.php"

<?php
    echo(time());
?>

Ответ 5

Я считаю, что ваше требование может быть удовлетворено некоторыми веб-службами, которые возвращают данные json.

Один из них - jsontest.com: http://date.jsontest.com. Вот что он возвращает:

{
   "time": "02:11:29 AM",
   "milliseconds_since_epoch": 1513563089492,
   "date": "12-18-2017"
} 

"milliseconds_since_epoch" представляет миллисекунды с 1970 года, поэтому легко конвертировать в Date, используя Date.init(timeIntervalSince1970: milliseconds_since_epoch/1000). Затем мы можем использовать класс Calendar для получения локального времени.

Ответ 6

Вот мой код, использующий 2 разных веб-сервиса на случай, если один из них не работает:

NSString *urlString = [NSString stringWithFormat:@"http://date.jsontest.com"];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
NSError *error;

NSNumber *milliSecondsSince1970 = nil;

if (data != nil) {
    NSDictionary *json =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
    milliSecondsSince1970 = [json valueForKey:@"milliseconds_since_epoch"];

    NSLog(@"milliSecondsSince1970 = %@", milliSecondsSince1970);
}
else {
    urlString = [NSString stringWithFormat:@"https://currentmillis.com/time/seconds-since-unix-epoch.php"];
    url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    data = [[NSData alloc] initWithContentsOfURL:url];

    if (data!=nil) {

        NSString *dbleStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        double dble = [dbleStr doubleValue]*1000;
        milliSecondsSince1970 = [NSNumber   numberWithDouble:dble];
        NSLog(@"milliSecondsSince1970 currentMillis = %@", milliSecondsSince1970);
    }

    else {
        double dateIntervalInSecondsSince1970 = [NSDate date].timeIntervalSince1970*1000;
        milliSecondsSince1970 = [NSNumber numberWithDouble:dateIntervalInSecondsSince1970] ;

        NSLog(@"milliSecondsSince1970 NSDate = %@", milliSecondsSince1970);
    }

}

Ответ 7

Если вы не хотите использовать другие веб-службы, вы можете проверять квитанцию каждый раз, когда пользователь открывает приложение, Apple вернет вам файл json, который содержит текущий gmt, я использую квитанцию для проверки статуса подписки и извлекаю время из этого файл