2012-02-16 109 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!)