UIWebView使用本地图像和javascript文件加载远程html页面 [英] UIWebView load remote html page with local images and javascript files

查看:144
本文介绍了UIWebView使用本地图像和javascript文件加载远程html页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建的应用程序将使用本地图像和javascript / css文件在UIWebView上显示远程页面,以加快加载速度。我想避免使用缓存,因为要使其工作,必须首先加载所有内容。我在网上寻找可能的解决方案。以下是我的内容:

Im creating application that will display remote page on the UIWebView using local images and javascript/css files for faster loading. I want to avoid using cache because for this to work it must first load all the content. I was searching online for possible solution. Here is what I have:

 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已定义,我将文件移至应用包。

urlString is defined and I moved files to the app bundle.

代码工作,因为我可以看到远程页面但没有图像或javascript文件。

Code works as I can see the remote page but no images nor javascript files are present.

推荐答案

我通过继承NSURLCache来解决这个问题。

I solve this problem by inheriting NSURLCache.

首先,创建NSURLCache的继承

Firstly, create a inheritance of 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

然后,替换默认的NSURLCache在app delegate中

Then, replace the default NSURLCache in app delegate

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];

然后,您可以在应用包中加载文件。

Then, you could load file in your app bundle.

例如,

这将显示您的应用图标。
你也可以用它加载css。

That will show your app icon. You could also load css with it.

这篇关于UIWebView使用本地图像和javascript文件加载远程html页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆