4

我正在构建一个应用程序,我也在其中实施离线模式。为此,我使用了 NSURLCache 机制。当应用程序处于前台时,即使设备处于离线模式,缓存机制也会完美运行。当我退出应用程序然后在离线模式下打开它时,问题就出现了。这次 NSCachedURLResponse 为特定请求返回 nil。

下面是我为此使用的代码:

自定义缓存创建:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSURLCache *urlCache = [[NSURLCache alloc] initWithMemoryCapacity:1024*1024 diskCapacity:1024*1024*5 diskPath:nil];
    [NSURLCache setSharedURLCache:urlCache];
}

调用服务器和缓存对象:

-(void)serverCall
{
   NSURLCache *urlCache = [NSURLCache sharedURLCache];

   NSString *urlString = nil;
   NSHTTPURLResponse *response = nil;
   NSError *error = nil;

   urlString = [NSString stringWithFormat:@"%@%@",BASE_URL,url];
   urlString = [urlString stringByReplacingOccurrencesOfString:@" " withString:@"%20"];

   NSURL *finalUrl = [NSURL URLWithString:urlString];
   NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:finalUrl];
   request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;

   NSData *data = nil;

   if ([self checkInternetConnection])
   {
       data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

       NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:data];
       [urlCache storeCachedResponse:cachedResponse forRequest:request];
   }
   else
   {
       NSCachedURLResponse *cachedResponse = [urlCache cachedResponseForRequest:request];
       response = cachedResponse.response;
       data = cachedResponse.data;
   }
}

我可以在应用程序的库路径中看到 caches.db 保存了响应。但是当我试图在离线模式下读取它时(应用程序从后台被杀死后),缓存的响应为零。我已经浏览了以下链接(以及更多链接),但找不到我的问题的解决方案。

NSURLCache 缓存响应问题

离线时如何使用 NSURLCache 返回缓存的 API 响应(iOS 应用)

http://twobitlabs.com/2012/01/ios-ipad-iphone-nsurlcache-uiwebview-memory-utilization/

http://petersteinberger.com/blog/2012/nsurlcache-uses-a-disk-cache-as-of-ios5/

绕过http响应头Cache-Control:如何设置缓存过期?

我检查了 api 响应中的 http 标头字段和缓存的标头,问题不是来自服务器端。

我还尝试在创建自定义缓存时在 diskPath 参数中提供路径,但是当应用程序处于前台并且互联网断开连接时,它甚至不会加载缓存的对象。我也更改了到期日期,但工作仍然相同。

我曾尝试使用 SDURLCache,但我面临着类似的问题。但是,我已经使用 ASIHTTPRequest 成功实现了这一点,但我不想使用它,因为我已经编写了所有服务器操作,并且必须使用 ASIHTTPRequest 方法更改每个请求。

请帮我找到解决方案。提前致谢....

4

0 回答 0