从网络获取日期,returns 无

Getting date from web, returns nil

正在检查以从 Google 获取当前时间和日期。第一个选项虽然不是最好的方法,但它是可行的,因为它使用的是贬值的方法,并等待一切都用同步方法完成,这不是好的用户体验。

-(NSDate*)timeAndDateFromWeb{
    

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
                                    initWithURL:[NSURL URLWithString:@"https://google.co.uk"]];
    [request setHTTPMethod:@"GET"];
    NSHTTPURLResponse *httpResponse = nil;
    [NSURLConnection sendSynchronousRequest:request returningResponse:&httpResponse error:nil];
    NSString *dateString = [[httpResponse allHeaderFields] objectForKey:@"Date"];
    DebugLog(@" *** GOOGLE DATE:  %@ ****",dateString);
    if (httpResponse){
        hasDataConnection = YES;
       
    }
    else{
        hasDataConnection = NO;
       
    }
    
    // Convert string to date object
    NSDateFormatter *dateformatted = [NSDateFormatter new];
    [dateformatted setDateFormat:@"E, d MMM yyyy HH:mm:ss zzz"];
    NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en"];
    [dateformatted setLocale:locale];
    
    return [dateformatted dateFromString:dateString];
}

尽管我为我的日期字符串返回 nil,但尝试调整它几乎就完成了:[dateformatted dateFromString:dateString];

    NSURL *url = [NSURL URLWithString:@"https://google.co.uk"];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSHTTPURLResponse *httpResponse = nil;
    NSString *dateString = [[httpResponse allHeaderFields] objectForKey:@"Date"];
    [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
      if (error) {
          hasDataConnection = NO;
          //NSLog(@"\n\n ----> Not connected Error,%@", [error localizedDescription]);
      }
      else {
          //NSLog(@"\n\n -----> connected:  %@", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
          hasDataConnection = YES;
       
          
      }
    }];
    
    
    // Convert string to date object
    NSDateFormatter *dateformatted = [NSDateFormatter new];
    [dateformatted setDateFormat:@"E, d MMM yyyy HH:mm:ss zzz"];
    NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en"];
    [dateformatted setLocale:locale];

    DebugLog(@" *** GOOGLE DATE:  %@ ****",[dateformatted dateFromString:dateString]);
    
    return [dateformatted dateFromString:dateString];

当您从同步切换到异步时,return 无法像以前一样设置值。

当您调用 sendAsynchronousRequest 方法时,它会启动后台任务,但您的线程会立即继续工作。这就是为什么 httpResponsedateString 都是 null.

因此,您应该将 return 类型更改为 void,因为您无法立即 return 结果,并添加一个回调,这将是 运行 当工作完成时。并在完成任务时处理您的格式:

- (void)timeAndDateFromWeb:(void (^)(NSDate *))completion {
    NSURL *url = [NSURL URLWithString:@"https://google.co.uk"];
    NSURLSessionTask *task = [NSURLSession.sharedSession
     dataTaskWithURL:url
     completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
//            hasDataConnection = NO;
            //NSLog(@"\n\n ----> Not connected Error,%@", [error localizedDescription]);
        }
        else if ([response isKindOfClass:NSHTTPURLResponse.class] ) {
            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
            NSString *dateString = [[httpResponse allHeaderFields] objectForKey:@"Date"];
            
            // Convert string to date object
            NSDateFormatter *dateformatted = [NSDateFormatter new];
            [dateformatted setDateFormat:@"E, d MMM yyyy HH:mm:ss zzz"];
            NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en"];
            [dateformatted setLocale:locale];
            
//            DebugLog(@" *** GOOGLE DATE:  %@ ****",[dateformatted dateFromString:dateString]);
            
            completion([dateformatted dateFromString:dateString]);
            //NSLog(@"\n\n -----> connected:  %@", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
//            hasDataConnection = YES;
            
            
        }
    }];
    [task resume];
}

因此此方法的结果将被 returned 到块中,与后台任务的结果相同。

不要忘记,它会在后台线程上调用,与下载任务完成块相同。所以如果你想改变一些 UI 你需要回到主线程:

[self timeAndDateFromWeb:^(NSDate *date) {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"%@", date);
        // UI changes
    });
}];

或者,您可以将其移动到函数内的主线程,就在 return 计算结果之前:

NSDate *date = [dateformatted dateFromString:dateString];
dispatch_async(dispatch_get_main_queue(), ^{
    completion(date);
});