2011-02-02 4 views
4

로컬 이미지와 javascript/css 파일을 사용하여 UIWebView에 원격 페이지를 표시하는 응용 프로그램을보다 빠르게로드 할 수 있습니다. 이 기능을 사용하려면 먼저 모든 콘텐츠를로드해야하므로 캐시를 사용하지 않는 것이 좋습니다. 가능한 해결책을 온라인에서 찾고있었습니다. 다음은 내가 가지고있는 것입니다.UIWebView 로컬 이미지 및 javascript 파일이 포함 된 원격 HTML 페이지로드

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이 정의되어 있고 파일을 응용 프로그램 번들로 이동했습니다.

코드는 작동하지만 원격 페이지는 볼 수 있지만 이미지 나 자바 스크립트 파일은 존재하지 않습니다.

+0

'file : // % @ /'을 baseURL로 전달해야합니다. – Alex

+0

슬래시를 변경하려고했으나 작동하지 않았습니다. 그냥 리소스가없는 일반 html을 보여줍니다. – BlueNile

답변

3

이 문제는 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]; 

그런 다음 응용 프로그램 위임의 기본 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 
의 상속을 작성, 당신은 당신의 응용 프로그램 번들에 파일을로드 할 수 있습니다.

예 :

그러면 앱 아이콘이 표시됩니다. 또한 css를로드 할 수 있습니다.

관련 문제