2012-02-16 80 views
0

我想缓存我的nsurlrequest数据。在此之前,我成功地从服务器下载数据,自从我试图实现这个缓存以来,它一直让我的应用程序崩溃。我希望有人可以看看我到目前为止的代码,并帮助我搞定它。我认为我已经完成了大约95%的工作。NSURLRequest缓存不起作用

- (IBAction)setRequestString:(NSString *)string 
{ 
    //Set database address 
    NSMutableString *databaseURL = [[NSMutableString alloc] initWithString:@"http://127.0.0.1:29/"]; // imac development 


    //PHP file name is being set from the parent view 
    [databaseURL appendString:string]; 

    //call ASIHTTP delegates (Used to connect to database) 
    NSURL *url = [NSURL URLWithString:databaseURL]; 

    //SynchronousRequest to grab the data, also setting up the cachePolicy 
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60.0]; //if request dose not finish happen within 60 second timeout. 

    //This nsdata will be used to put the cache into 
    NSData *cacheData = [[NSData alloc] init]; 
    //Create my own NSCachedURLResponse and add it to the cache 
    NSURLResponse *responseToCache = [[NSURLResponse alloc] initWithURL:url MIMEType:@"text/xml" expectedContentLength:[cacheData length] textEncodingName:nil]; 
    //Set up the cache 
    NSCachedURLResponse *cacheResponse = [[NSCachedURLResponse alloc] initWithResponse:responseToCache data:cacheData]; 
    [[NSURLCache sharedURLCache] storeCachedResponse:cacheResponse forRequest:request]; 

    //check if its really there 
    NSLog(@"cache = %@", [[NSURLCache sharedURLCache] cachedResponseForRequest:request]); 


    //If no cache do this stuff, connect to the db and perform these actions. I think this is what i am supposed to be doing. 
    NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) 
    { 
     if ([data length] > 0 && error == nil){ 
      [self receivedData:data]; 
     }else if ([data length] == 0 && error == nil){ 
      [self emptyReply]; 
     }else if (error != nil && error.code == NSURLErrorTimedOut){ 
      [self timedOut]; 
     }else if (error != nil){ 
      [self downloadError:error]; 
     } 
    }]; 
} 

回答

-3

Follow this link这样做的使用上NSURLConnection的一类方法的死简单的方法。它适用于异步请求,但可以轻松适应同步请求。

此外,我强烈建议您为您的NSOperationQueue使用私有属性或实例变量,以便您的所有请求都使用相同的操作队列。

+5

只包含链接的答案是[认为不好的做法](http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers)。请总结这里的内容(不要复制/粘贴),这样答案就可以独立运作。如果你不这样做,那么你的答案就会被删除,特别是如果链接死亡的话。 – 2012-05-31 09:15:46

+3

猜猜看,链接刚刚死亡(而不是来自塞尔达的链接)。 – 2012-10-11 13:35:42

+1

链接已经死了 – TrekOnTV2017 2013-05-29 17:29:17

7

感谢您的代码,我设法让它与您的示例一起工作。

cacheData是要缓存的数据,而不是缓存的位置。 您必须自己获取并处理缓存。 我给你一个小例子为清楚:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestUrl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; 

NSCachedURLResponse *cachedURLResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request]; 

NSData *responseData; 

//check if has cache 
if(cachedURLResponse && cachedURLResponse != (id)[NSNull null]) 
{ 
    responseData = [cachedURLResponse data]; 
} 
else //if no cache get it from the server. 
{ 
    __autoreleasing NSError *error = nil; 
    NSHTTPURLResponse *response = nil; 
    responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 

    //..handle response and error 

    //cache received data 
    cachedURLResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:responseData userInfo:nil storagePolicy:NSURLCacheStorageAllowed]; 
    //store in cache 
    [[NSURLCache sharedURLCache] storeCachedResponse:cachedURLResponse forRequest:request]; 
} 

//..handle responseData 
+0

你好Juzzz,我总是得到cachedURLResponse对象零,你能帮帮我吗?谢谢 – iBhavik 2015-05-06 06:28:10

+0

@iBhavik这是一个非常古老的(3年)示例代码,你想完成什么?我强烈建议使用像'AFNetworking'这样的框架来处理url/api请求。 – Justin 2015-05-11 10:01:43

0

斯威夫特:

let isReachable = NetworkManager.sharedManager().isInternetReachable()//Reachability- to check internet is available 
     let urlRequestCache:NSURLRequest! 
     if isReachable != 0 { //If ther is intenet then load and caching it 
      urlRequestCache = NSURLRequest(URL: NSURL(string: url)!, cachePolicy: NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 10) 
      let session = NSURLSession.sharedSession() 
        session.dataTaskWithRequest(urlRequestCache, completionHandler: {(data, response, error) in 
         let newCachedResponse = NSCachedURLResponse(response:(response)!, data:(data)!, userInfo:nil, storagePolicy: .Allowed) 
         NSURLCache.sharedURLCache().storeCachedResponse(newCachedResponse, forRequest:urlRequestCache) 

        }).resume() 

     }else{ // check the cache is available 
      urlRequestCache = NSURLRequest(URL: NSURL(string: url)!, cachePolicy: NSURLRequestCachePolicy.ReturnCacheDataElseLoad, timeoutInterval: 60) 
      guard let _ = NSURLCache.sharedURLCache().cachedResponseForRequest(urlRequestCache) else{ //checking cache if false then 
       print(" cache not found:)") 
       return 
      } 
      print(" cache found:)") 
      } 
     browserView?.loadRequest(urlRequestCache!)