Получить дату и время с Apple Server
Я разрабатываю приложение, которое можно использовать только в определенное время дня. Я не могу получить время локального устройства, так как пользователь может легко изменить время устройства, тем самым обеспечивая доступ к приложению в любое время суток.
Есть ли способ получить текущую дату и время с сервера Apple (или, если нет), есть ли другой способ?
Ответы
Ответ 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, я использую квитанцию для проверки статуса подписки и извлекаю время из этого файл