gpt4 book ai didi

html - 如何将内容保存在 UIWebView 中以便在下次启动时更快地加载?

转载 作者:太空狗 更新时间:2023-10-29 14:40:11 25 4
gpt4 key购买 nike

我知道最近iphone sdk中引入了一些缓存类,three20的库中还有一个TTURLRequest可以让你缓存一个请求到一个URL。但是,因为我是通过调用UIWebView的loadRequest来加载UIWebView中的网页,所以那些技术并不是很适用。

有什么想法可以保存网页,以便在下次应用启动时,我不必再次从网络上获取整个页面吗?页面本身已经有一些自动更新自身部分的 ajax 机制。

最佳答案

有很多关于 UIWebView 缓存工作方式的文章,全局的感觉是,即使某些机制在 MacOS X 下似乎工作正常,但相同的方法在 iPhone 下可能会有奇怪的行为。


但是, 我正在通过使用任何 NSURLConnectionUIWebView 访问的全局缓存来实现这一点。 在我的例子中,它有效 ;)。

你需要了解的是全局流:

  • 您 -> UIWebView 上的 loadRequest
  • 这会进入 NSURLCache 询问“是否有为此请求缓存的内容?”:
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request

由此,在我这边,这是我处理磁盘缓存以加速 UIWebView 加载的方法:

  • 子类化 NSURLCache 并覆盖对 -(NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request 选择器的控制
  • 以这样的方式重新实现这个选择器,如果没有为这个请求在 FS 上写入任何内容(没有缓存),那么在你这边执行请求并将内容存储在 FS 上。否则,返回之前缓存的内容。
  • 创建您的子类的实例并将其设置到系统,以便您的应用程序使用它

现在的代码:

MyCache.h

@interface MyCache : NSURLCache {
}
@end

MyCache.m

@implementation MyCache

-(NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(@"CACHE REQUEST S%@", request);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray* tokens = [request.URL.relativePath componentsSeparatedByString:@"/"];
if (tokens==nil) {
NSLog(@"ignoring cache for %@", request);
return nil;
}
NSString* pathWithoutRessourceName=@"";
for (int i=0; i<[tokens count]-1; i++) {
pathWithoutRessourceName = [pathWithoutRessourceName stringByAppendingString:[NSString stringWithFormat:@"%@%@", [tokens objectAtIndex:i], @"/"]];
}
NSString* absolutePath = [NSString stringWithFormat:@"%@%@", documentsDirectory, pathWithoutRessourceName];
NSString* absolutePathWithRessourceName = [NSString stringWithFormat:@"%@%@", documentsDirectory, request.URL.relativePath];
NSString* ressourceName = [absolutePathWithRessourceName stringByReplacingOccurrencesOfString:absolutePath withString:@""];
NSCachedURLResponse* cacheResponse = nil;
//we're only caching .png, .js, .cgz, .jgz
if (
[ressourceName rangeOfString:@".png"].location!=NSNotFound ||
[ressourceName rangeOfString:@".js"].location!=NSNotFound ||
[ressourceName rangeOfString:@".cgz"].location!=NSNotFound ||
[ressourceName rangeOfString:@".jgz"].location!=NSNotFound) {
NSString* storagePath = [NSString stringWithFormat:@"%@/myCache%@", documentsDirectory, request.URL.relativePath];
//this ressource is candidate for cache.
NSData* content;
NSError* error = nil;
//is it already cached ?
if ([[NSFileManager defaultManager] fileExistsAtPath:storagePath]) {
//NSLog(@"CACHE FOUND for %@", request.URL.relativePath);
content = [[NSData dataWithContentsOfFile:storagePath] retain];
NSURLResponse* response = [[NSURLResponse alloc] initWithURL:request.URL MIMEType:@"" expectedContentLength:[content length] textEncodingName:nil];
cacheResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:content];
} else {
//trick here : if no cache, populate it asynchronously and return nil
[NSThread detachNewThreadSelector:@selector(populateCacheFor:) toTarget:self withObject:request];
}
} else {
NSLog(@"ignoring cache for %@", request);
}
return cacheResponse;
}

-(void)populateCacheFor:(NSURLRequest*)request {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//NSLog(@"PATH S%@", paths);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray* tokens = [request.URL.relativePath componentsSeparatedByString:@"/"];
NSString* pathWithoutRessourceName=@"";
for (int i=0; i<[tokens count]-1; i++) {
pathWithoutRessourceName = [pathWithoutRessourceName stringByAppendingString:[NSString stringWithFormat:@"%@%@", [tokens objectAtIndex:i], @"/"]];
}
NSString* absolutePath = [NSString stringWithFormat:@"%@/myCache%@", documentsDirectory, pathWithoutRessourceName];
//NSString* absolutePathWithRessourceName = [NSString stringWithFormat:@"%@%@", documentsDirectory, request.URL.relativePath];
//NSString* ressourceName = [absolutePathWithRessourceName stringByReplacingOccurrencesOfString:absolutePath withString:@""];
NSString* storagePath = [NSString stringWithFormat:@"%@/myCache%@", documentsDirectory, request.URL.relativePath];
NSData* content;
NSError* error = nil;
NSCachedURLResponse* cacheResponse = nil;
NSLog(@"NO CACHE FOUND for %@", request.URL);
//NSLog(@"retrieving content (timeout=%f) for %@ ...", [request timeoutInterval], request.URL);
content = [NSData dataWithContentsOfURL:request.URL options:1 error:&error];
//NSLog(@"content retrieved for %@ / error:%@", request.URL, error);
if (error!=nil) {
NSLog(@"ERROR %@ info:%@", error, error.userInfo);
NSLog(@"Cache not populated for %@", request.URL);
} else {
NSURLResponse* response = [[NSURLResponse alloc] initWithURL:request.URL MIMEType:@"" expectedContentLength:[content length] textEncodingName:nil];
cacheResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:content];
//the store is invoked automatically.
[[NSFileManager defaultManager] createDirectoryAtPath:absolutePath withIntermediateDirectories:YES attributes:nil error:&error];
BOOL ok;// = [[NSFileManager defaultManager] createDirectoryAtPath:absolutePath withIntermediateDirectories:YES attributes:nil error:&error];
ok = [content writeToFile:storagePath atomically:YES];
NSLog(@"Caching %@ : %@", storagePath , ok?@"OK":@"KO");
}
[pool release];
}
@end

以及在您的应用程序中使用它:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* diskCachePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory, @"myCache"];
NSError* error;
[[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath withIntermediateDirectories:YES attributes:nil error:&error];
MyCache* cacheMngr = [[MyCache alloc] initWithMemoryCapacity:10000 diskCapacity:100000000 diskPath:diskCachePath];
[NSURLCache setSharedURLCache:cacheMngr];

这段代码值得大量清理..但主要的东西应该在那里。我遇到了很多麻烦才能使它正常工作,希望这对您有所帮助。

关于html - 如何将内容保存在 UIWebView 中以便在下次启动时更快地加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1343515/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com