ASIHTTPRequest - 缓存中的数据始终为空

时间:2011-06-25 13:50:27

标签: ios caching asihttprequest

我正在我的iPhone / iPad应用程序中下载图像 - 因为它们在大多数时间保持不变,我想将它们缓存在磁盘上:

ASIDownloadCache *cache = [ASIDownloadCache sharedCache];
[asiRequest setDownloadCache:cache];
[asiRequest setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
[asiRequest setCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
[asiRequest setSecondsToCache:60*60*24*30]; // Cache for 30 days
[asiRequest setDelegate:self]; // A delegate must be specified
[asiRequest setDidFinishSelector:@selector(requestFinished:)];
[asiRequest startAsynchronous];

在我的requestFinished方法中,我们认识到缓存是成功的,但是我的request-object中的数据是empyt;我错过了什么?

- (void) requestFinished:(ASIHTTPRequest *)request {
   if ([request didUseCachedResponse]) {
       NSLog(@"cache, size: %i", [[request responseData] length]); // is always zero
       [self buildImageWithData:[request responseData]];
   }
   [...];
}

非常感谢!

编辑1:我的完整代码无法正常工作:第一次,我得到“not cached”语句,从那时起,“cache,size:0”...我有不明白为什么:(

- (void)viewDidLoad {
    [super viewDidLoad];

    for (int i = 0; i < 10; i++) {
        asiRequest = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.myimageserver.com/myimage.jpg"]];

        ASIDownloadCache *cache = [ASIDownloadCache sharedCache];
        [asiRequest setDownloadCache:cache];
        [asiRequest setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
        [asiRequest setCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
        [asiRequest setSecondsToCache:60*60*24*30]; // Cache for 30 days
        [asiRequest setDelegate:self]; // A delegate must be specified
        [asiRequest setDidFinishSelector:@selector(requestFinished:)];
        [asiRequest startAsynchronous];
    }
}

- (void) request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders {
    self.imageDataLoadedFromURL = [NSMutableData data];
}

- (void) request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data {
    [imageDataLoadedFromURL appendData:data];
}

- (void) requestFinished:(ASIHTTPRequest *)request {
    if ([request didUseCachedResponse]) {
        NSLog(@"cache, size: %i", [[request responseData] length]); // is always zero
    } else {
        NSLog(@"not cached");
    }
}

编辑2:似乎缓存已包含0字节图像;所以这不是从缓存中读取而是写入它的问题......

enter image description here

编辑3 :您可以从http://tinyurl.com/68wuwj2下载小型测试项目

5 个答案:

答案 0 :(得分:2)

您可以设置断点,清除缓存(例如删除您的应用),然后单步执行这段代码(ASIDownloadCache.m,第184行,方法storeResponseForRequest):

if ([request responseData]) {
    [[request responseData] writeToFile:dataPath atomically:NO];
} else if ([request downloadDestinationPath] && ![[request downloadDestinationPath] isEqualToString:dataPath]) {
    NSError *error = nil;
    [[[[NSFileManager alloc] init] autorelease] copyItemAtPath:[request downloadDestinationPath] toPath:dataPath error:&error];
}

检查遵循的路径,并检查request.responseData。

的大小

** 编辑 **

您的问题是您使用didReceiveData:

- (void) request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data {
    [imageDataLoadedFromURL appendData:data];
}

引用asi http请求文档:

  

如果您需要将响应处理为   它进来(例如,你想要   使用流解析器来解析   在它还在的时候回应   已下载),请您的代表   实现请求:didReceiveData :(见   ASIHTTPRequestDelegate.h)。 请注意   当你这样做时,ASIHTTPRequest会   不填充responseData或写入   响应downloadDestinationPath -   你必须自己存储回复   如果你需要。

最后一句似乎也适用于缓存数据。

这可能是asihttprequest中的一个错误,实际上它不应该在这种情况下不将数据写入缓存,或者应该确保它正在写入有效数据 - 目前看起来它写的是无效的缓存条目。你需要在数据到达时处理它吗?如果不只是删除'didReceiveBytes'并且只使用requestFinished中request.responseData中提供的数据。

答案 1 :(得分:1)

您的代码对我来说似乎是正确的。

我唯一能想到的是你的缓存中可能有一些“损坏的”数据,比如存储了零腿数据。您可以尝试删除缓存一次或仅使用ASIDoNotReadFromCacheCachePolicy策略一次(以便“清除”缓存)。

如果这没有帮助,我会在你的requestFinished:中设置一个断点,并从那里检查ASIHTTP中发生的事件,当据称从缓存中检索到数据时。这比听起来容易。

答案 2 :(得分:1)

注释掉这种方法:

(void) request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data
{
   [imageDataLoadedFromURL appendData:data];
}

答案 3 :(得分:0)

尝试使用它并告诉我你得到了什么:

- (void) requestFinished:(ASIHTTPRequest *)request {
    NSLog(@"Size of received data: %d bytes",[[request responseData] length]); //THIS LINE

if ([request didUseCachedResponse]) {
    NSLog(@"cached");        
} else {
        NSLog(@"not cached");
    }
}

然后尝试将此方法更改为:

- (void) request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders {
    [self.imageDataLoadedFromURL setLength:0];
}

并确保您使用self.imageDataLoadedFromURL作为NSMutableData

答案 4 :(得分:0)

我试过运行你的应用。亚历山大的建议是对的。

注释掉这种方法:

(void) request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data

在注释掉这个方法时,被调用的requestDone方法将拥有整个请求内容,从而具有大小。