Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 从Apple服务器获取日期和时间_Ios_Xcode - Fatal编程技术网

Ios 从Apple服务器获取日期和时间

Ios 从Apple服务器获取日期和时间,ios,xcode,Ios,Xcode,我正在开发一款只能在一天中某个特定时间使用的应用程序。我无法获取本地设备时间,因为用户可以轻松更改设备时间,从而允许在一天中的任何时间访问应用程序 有没有办法从苹果服务器上获取当前日期和时间(如果没有,还有其他办法?-(NSDate*)CurrentDate - (NSDate *) CurrentDate { if ([self hasInternetConnectivity]) // this tests Internet connectivity based off Apple'

我正在开发一款只能在一天中某个特定时间使用的应用程序。我无法获取本地设备时间,因为用户可以轻松更改设备时间,从而允许在一天中的任何时间访问应用程序

有没有办法从苹果服务器上获取当前日期和时间(如果没有,还有其他办法?

-(NSDate*)CurrentDate
- (NSDate *) CurrentDate 
{
    if ([self hasInternetConnectivity]) // this tests Internet connectivity based off Apple's Reachability sample code
    {
        NSSURL * scriptUrl = [NSURL URLWithString: @"http:// <yoursite>. Com / <the 2 line php script>. 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];
    }
}
{ if([self hasInternetConnectivity])//此测试基于苹果的可访问性示例代码进行互联网连接测试 { NSSURL*脚本URL=[NSURL URLWithString:@“http://.Com/.Php”]; NSData*data=[NSData datawithcontentsofull:scriptUrl]; 如果(数据!=nil){ NSString*tempString=[NSString stringWithUTF8String:[数据字节]]; NSDate*currDate=[NSDate DATE WithTimeIntervalences1970:[tempString doubleValue]]; NSLog(@“从站点返回的字符串为:%@且日期为:%@”,tempString,[currDate description]); 返回日期; } 否则{ NSLog(@“nsdata下载失败”); 返回[日期]; } } 否则{ NSLog(@“Internet连接失败”); 返回[日期]; } }
我认为您应该使用Internet时间服务器。他们正在使用一种标准化的协议,称为。iOS有,但作为应用程序开发人员,您无法访问。要么自己实现,要么使用开源库,比如或。我自己都没用过。这可能是一个好主意,检查设备的位置,并找出时区,以获得一个真正的防弹解决方案

在这里,你可以阅读更多关于服务器和其他东西的信息;


理想情况下,应用程序中应该有一个服务器列表。如果其中一个失败,您将调用列表中的下一个NTP服务器。

您可以使用该开源从默认NTP服务器获取时间,或者选择您的服务器:

和使用:

NSDate *networkDate = [NSDate networkDate];

Karan的回答有一些拼写错误,并且也没有检查回答“0”而不是“nil”。(我在我的应用程序中实现了它,从弱连接或未经授权的网络中得到了一些误报。)

我在下面对其进行了修改,并为那些不知道Karan指的是什么的人添加了相应的服务器代码。这是作为NSDate扩展中的category方法实现的,因此您可以使用
[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”的形式存储在服务器的根文件夹中


我相信一些返回json数据的web服务可以满足您的要求

其中之一是jsontest.com:。以下是它的回报:

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

“自新纪元起的毫秒数”表示自1970年起的毫秒数,因此使用
Date.init(timeIntervalSince1970:millizes\u-since\u-epoch/1000)
很容易转换为日期。然后我们可以使用
Calendar
类获取本地时间。

这是我的代码,如果其中一个web服务出现故障,请使用两个不同的web服务:

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);
    }

}

如果您不想使用其他web服务,您可以在用户每次打开应用程序时验证收据,苹果将向您返回一个包含当前gmt的json文件,我使用收据检查订阅状态,并从该文件获取时间

我们在这里谈论的是哪种服务器?您需要实现自己的服务器吗?我认为shah提到的是在服务器上托管一个php文件,该文件打印当前日期和时间。上面的代码将读取文本并作为NSDate返回。如果我没有错的话。如果有一个示例服务器实现代码,这个示例将更有帮助。现在它感觉不完整。请记住,这并没有考虑网络请求完成的时间。在大多数情况下,这可能是正常的,尽管当我在我的应用程序中实现它时,这段代码有一个bug,适用于互联网连接薄弱的用户。我在下面我自己的答案中实现了一个修复,并为任何需要的人添加了服务器代码。如果您使用了一个或另一个解决方案,请选择首选答案;-)您是否考虑过用户可能会打开飞行模式,然后更改日期和时间?kraitz我发现了一个开源实现,您可能可以使用它。答案会相应更新。ios-ntp包含很多供应商代码。并且类名不是很好,无法将它们包含在项目中。当前版本的ios ntp有一个严重错误,这会使您得到的网络时间错误。您可以使用
https://github.com/huynguyencong/NHNetworkTime
作为替换,收据是否有当前时间?我所知道的是它给了你购买日期和过期日期。
{
   "time": "02:11:29 AM",
   "milliseconds_since_epoch": 1513563089492,
   "date": "12-18-2017"
} 
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);
    }

}