我创建的应用程序将使用本地图像和javascript / css文件在UIWebView上显示远程页面,以加快加载速度。我想避免使用缓存,因为要使其工作,必须首先加载所有内容。我在网上寻找可能的解决方案。这就是我所拥有的:
NSURLRequest *urlrequest = [ [NSURLRequest alloc] initWithURL: [NSURL URLWithString:urlString] ];
NSData *returnData = [ NSURLConnection sendSynchronousRequest:urlrequest returningResponse: nil error: nil ];
NSString *HTMLData = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
resourcePath = [resourcePath stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
resourcePath = [resourcePath stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
[webView loadHTMLString:HTMLData baseURL:
[NSURL URLWithString:
[NSString stringWithFormat:@"file:/%@//",resourcePath]
]];
定义了urlString,我将文件移动到app bundle。
代码正常工作,因为我可以看到远程页面,但不存在图像或javascript文件。
答案 0 :(得分:3)
我通过继承NSURLCache来解决这个问题。
首先,创建NSURLCache
的继承#import "VURLCache.h"
#import <MobileCoreServices/UTType.h>
@implementation VURLCache
-(NSString*)mimeTypeForExtension:(NSString*)ext
{
NSAssert( ext, @"Extension cannot be nil" );
NSString* mimeType = nil;
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
(CFStringRef)ext, NULL);
if( !UTI ) return nil;
CFStringRef registeredType = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType);
if( !registeredType ) // check for edge case
{
if( [ext isEqualToString:@"m4v"] )
mimeType = @"video/x-m4v";
else if( [ext isEqualToString:@"m4p"] )
mimeType = @"audio/x-m4p";
// handle anything else here that you know is not registered
} else {
mimeType = NSMakeCollectable(registeredType);
}
CFRelease(UTI);
return mimeType;
}
-(void)parseBundleURL:(NSURL*)url
name:(NSString**)name
ext:(NSString**)ext
bundleDirectory:(NSString**)bundleDirectory {
NSString* path = [url path];
NSUInteger nameStart = NSNotFound;
// locate the last '/'
NSRange pathStop = [path rangeOfString:@"/" options:NSBackwardsSearch];
if( 0 == pathStop.location ) {
nameStart = 1;
} else if ( NSNotFound != pathStop.location ) {
// there is a path
nameStart = pathStop.location+1;
NSRange pathRange = NSMakeRange(0, nameStart);
*bundleDirectory = [path substringWithRange:pathRange];
}
NSRange fileRange = NSMakeRange(nameStart, path.length - nameStart);
if( fileRange.length > 0 ) {
NSRange extStop = [path rangeOfString:@"." options:0 range:fileRange];
if( NSNotFound != extStop.location ) {
NSUInteger sep = extStop.location;
NSRange nameRange =
NSMakeRange( nameStart, sep - nameStart);
*name = [path substringWithRange:nameRange];
NSRange extRange =
NSMakeRange( sep+1, path.length -(sep+1));
*ext = [path substringWithRange:extRange];
}
}
}
-(NSCachedURLResponse*)bundleResourceForRequest:(NSURLRequest *)request {
NSURL* url = [request URL];
NSString* name = nil;
NSString* ext = nil;
NSString* bundleDirectory = nil;
NSString* path = nil;
[self parseBundleURL:url name:&name ext:&ext bundleDirectory:&bundleDirectory];
if( name && ext ) {
NSBundle* bundle = [NSBundle mainBundle];
if( nil == bundleDirectory ) {
path = [bundle pathForResource:name ofType:ext];
} else {
path = [bundle pathForResource:name ofType:ext inDirectory:bundleDirectory];
}
}
NSCachedURLResponse* rep = nil;
if( path ) {
NSData* content = [NSData dataWithContentsOfFile:path];
NSString* mime = [self mimeTypeForExtension:ext];
NSString* encoding = nil;
NSURLResponse* response =
[[NSURLResponse alloc]
initWithURL:request.URL
MIMEType:mime
expectedContentLength:[content length]
textEncodingName:encoding];
rep = [[NSCachedURLResponse alloc] initWithResponse:response data:content];
}
return rep;
}
#pragma mark NSURLCache
-(NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
NSURL* url = [request URL];
if( [[url absoluteString] hasPrefix:VBUNDLE_URL_PREFIX] ) {
return [self bundleResourceForRequest:request];
}
return [super cachedResponseForRequest: request];
}
@end
然后,替换app delegate中的默认NSURLCache
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *path = docDir; // the path to the cache file
NSUInteger discCapacity = 0;
NSUInteger memoryCapacity = 5120*1024;
VURLCache *cache = [[VURLCache alloc] initWithMemoryCapacity:memoryCapacity diskCapacity:discCapacity diskPath:path];
[NSURLCache setSharedURLCache:cache];
[cache release];
然后,您可以在应用包中加载文件。
例如,
这将显示您的应用图标。 你也可以用它加载css。