ASIHTTPRequest和ASIWebPageRequest加载本地html文件错误

时间:2011-06-01 19:41:45

标签: iphone http-status-code-404 asihttprequest

我正在尝试使用ASIWebPageRequest来加载本地html文件,以便我可以在ASIWebPageRequest中使用内置缓存。我知道这可能听起来有点无意义但是我想在我的本地文件中使用远程图像,每周只更新一次。如果这是有道理的。

以下是我在代码中所做的事情:

//OUTPUT: file:///Users/ledixonuk/Library/Application%20Support/iPhone%20Simulator/4.3.2/Applications/FDF21331-CC80-4ECB-9A33-16AEC073D117/Documents/ItemOne.html
NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:[FileSystemHelper dataFilePathInDocuments:@"ItemOne.html"]];

// Assume request is a property of our controller
// First, we'll cancel any in-progress page load
[[self webRequest] setDelegate:nil];
[[self webRequest] cancel];

[self setWebRequest:[ASIWebPageRequest requestWithURL:fileUrl]];
[[self webRequest] setDelegate:self];
[[self webRequest] setDidFailSelector:@selector(webPageFailed:)];
[[self webRequest] setDidFinishSelector:@selector(webPageFinished:)];

// Tell the request to replace urls in this page with local urls
//[[self webRequest] setUrlReplacementMode:ASIReplaceExternalResourcesWithLocalURLs];

// Tell the request to embed external resources directly in the page
[[self webRequest] setUrlReplacementMode:ASIReplaceExternalResourcesWithData];

// It is strongly recommended you use a download cache with ASIWebPageRequest
// When using a cache, external resources are automatically stored in the cache
// and can be pulled from the cache on subsequent page loads
[[self webRequest] setDownloadCache:[ASIDownloadCache sharedCache]];

// Ask the download cache for a place to store the cached data
// This is the most efficient way for an ASIWebPageRequest to store a web page
[[self webRequest] setDownloadDestinationPath:[[ASIDownloadCache sharedCache] pathToStoreCachedResponseDataForRequest:[self webRequest]]];

[[self webRequest] startAsynchronous];

这是我得到的错误:

  

  404未找到   

     

未找到

     

请求的URL / Users / ledixonuk / Library / Application Support / iPhone Simulator / 4.3.2 / Applications / FDF21331-CC80-4ECB-9A33-16AEC073D117 / Documents / ItemOne.html是>在此服务器上找不到。

     

显然,ASIWebPageRequest无法在应用程序文档文件夹中找到ItemOne.html文件,但我已经仔细检查过,文件肯定在那里。

还有其他人有类似的问题吗?这让我很生气,试图解决它!

2 个答案:

答案 0 :(得分:1)

ASIWebPageRequest是ASIHTTPRequest的子类,不幸的是ASIHTTPRequest不支持获取文件:URL - 仅限http和https。

基本上你拥有所需的所有代码,你只需找到一种方法将它连接在一起。您可以创建ASIHTTPRequest的子类,它可以加载文件:URL(本质上提供您自己的startAsyncronous实现,而不是在设置正确的数据文件后回调代理),或者创建ASIWebPageRequest的子类来执行它。我还没有详细考虑过,所以我不知道哪种方式最好。

(我认为你正在看到404页面,因为ASIHTTPRequest正在设法联系某个地方的网络服务器 - 也许它正试图从http://127.0.0.1/Users/ledixonuk/Library/获取....)

答案 1 :(得分:0)

请参阅下面我添加到ASIHTTPRequest子类的简单实现,以支持基于file://的URL。它绝不是完整的,可能会遗漏一些应该设置的属性,它不会调用所有代理,但出于我自己的目的,这已经足够了。

- (void)startRequest
{        
    if ([url isFileURL])
    {
        // ASIHTTPRequest does not support handling file:// URLs, this is my own simple implementation here

        if ([self isCancelled]) {
            return;
        }

        [self performSelectorOnMainThread:@selector(requestStarted) withObject:nil waitUntilDone:[NSThread isMainThread]];

        NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
        NSString *filePath = [url path];
        BOOL isDirectory = NO;

        if ([fileManager fileExistsAtPath:filePath isDirectory:&isDirectory] && !isDirectory)
        {
            responseStatusCode = 200;
            [self setRawResponseData:[NSData dataWithContentsOfFile:filePath]];
            [self setContentLength:rawResponseData.length];
            [self setTotalBytesRead:[self contentLength]];
        }
        else
        {
            responseStatusCode = 404;
            [self setContentLength:0];
            [self setError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIFileManagementError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Cannot open file at path '%@'",filePath],NSLocalizedDescriptionKey,error,NSUnderlyingErrorKey,nil]]];
        }

        complete = YES;
        downloadComplete = YES;

        [self requestFinished];
        [self markAsFinished];
    }
    else
    {
        // let the original implementation deal with all the other URLs
        [super startRequest];
    }
}