NSURLRequest с кешированием не работает - PullRequest
0 голосов
/ 16 февраля 2012

Я пытаюсь кэшировать свои данные nsurlrequest. До этого я успешно загружал данные с сервера, с тех пор, как я пытался внедрить этот кеш, мое приложение перестало работать. Я надеюсь, что кто-то может взглянуть на код, который у меня есть, и помочь мне его заработать ... Я думаю, что я сделал примерно 95% этого.

- (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 ]

7 голосов
/ 10 мая 2012

Спасибо за код, мне удалось заставить его работать с вашим примером.

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 голосов
/ 12 мая 2016

Свифт:

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!)
0 голосов
/ 31 мая 2012

Перейдите по этой ссылке , чтобы узнать простой простой способ сделать это с помощью метода категорий в NSURLConnection. Он предназначен для асинхронных запросов, но может быть легко адаптирован для синхронных запросов.

Кроме того, я настоятельно рекомендую вам использовать частное свойство или переменную экземпляра для вашего NSOperationQueue, чтобы все ваши запросы использовали одну и ту же очередь операций.

...