带有本地图像文件的iOS WebView远程HTML [英] iOS WebView remote html with local image files

查看:259
本文介绍了带有本地图像文件的iOS WebView远程HTML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以前也有类似的问题,但我永远无法找到解决方案。



这是我的情况 - 我的UIWebView加载一个远程HTML页面。网页中使用的图像在构建时已知。为了加快页面加载速度,我想将图像文件打包到iOS应用程序中,并在运行时取代它们。



<请注意,html是远程的。我总是得到从本地加载html和图像文件的答案 - 我已经做到了这一点]



我得到的最接近的建议是使用自定义url方案,如myapp ://images/img.png在html页面和iOS应用程序中,用NSURLProtocol子类截取myapp:// URL并用本地图像替换图像。理论上听起来不错,但我还没有遇到一个完整的代码示例来证明这一点。



我有Java背景。我可以使用自定义内容提供程序轻松完成Android操作。我相信iOS / Objective-C必须存在类似的解决方案。我没有足够的Objective-C经验在短时间内自己解决它。



任何帮助都将值得赞赏。

解决方案

好的,这里是一个例子如何继承 NSURLProtocol 并提供一个已经在包中的图像( image1.png )。下面是子类的头,实现以及如何在viewController(不完整代码)和本地html文件(可以很容易地与远程交换)中使用它的例子。我已经调用了自定义协议: myapp:// ,您可以在底部的html文件中看到。



并感谢您的问题!我自己问了很长一段时间,弄清楚这一点花费的时间是每秒一次。

编辑:
如果有人在我的代码在当前iOS版本下运行时遇到困难,请查看sjs的答案。当我回答这个问题时,它正在工作。他指出了一些有用的补充,并纠正了一些问题,所以给他一些道具。



这是它在我的模拟器中的外观:





MyCustomURLProtocol.h

  @interface MyCustomURLProtocol:NSURLProtocol 
{
NSURLRequest *请求;
}

@property(nonatomic,retain)NSURLRequest * request;

@end

MyCustomURLProtocol.m

  #importMyCustomURLProtocol.h

@implementation MyCustomURLProtocol

@合成请求;
$ b $(BOOL)canInitWithRequest:(NSURLRequest *)theRequest
{
if([theRequest.URL.scheme caseInsensitiveCompare:@myapp] == NSOrderedSame){
返回YES;
}
return NO;


+(NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)theRequest
{
return theRequest;


- (void)startLoading
{
NSLog(@%@,request.URL);
NSURLResponse * response = [[NSURLResponse alloc] initWithURL:[请求URL]
MIMEType:@image / png
expectedContentLength:-1
textEncodingName:nil];

NSString * imagePath = [[NSBundle mainBundle] pathForResource:@image1ofType:@png];
NSData * data = [NSData dataWithContentsOfFile:imagePath];

[[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
[[self client] URLProtocol:self didLoadData:data];
[[self client] URLProtocolDidFinishLoading:self];
[回应释放];


- (void)stopLoading
{
NSLog(@something went wrong!);


$ end
code
$ b MyCustomProtocolViewController.h

  @interface MyCustomProtocolViewController:UIViewController {
UIWebView * webView;
}

@property(nonatomic,retain)UIWebView * webView;

@end

MyCustomProtocolViewController.m

  ... 

@implementation MyCustomProtocolViewController

@synthesize webView;

- (void)awakeFromNib
{
self.webView = [[[UIWebView alloc] initWithFrame:CGRectMake(20,20,280,420)] autorelease];
[self.view addSubview:webView];
}

- (void)viewDidLoad
{
// ---->重要!!! :)< ----
[NSURLProtocol registerClass:[MyCustomURLProtocol class]];

NSString * localHtmlFilePath = [[NSBundle mainBundle] pathForResource:@fileofType:@html];

NSString * localHtmlFileURL = [NSString stringWithFormat:@file://%@,localHtmlFilePath];

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:localHtmlFileURL]]];

NSString * html = [NSString stringWithContentsOfFile:localHtmlFilePath encoding:NSUTF8StringEncoding error:nil];

[webView loadHTMLString:html baseURL:nil];
}

file.html

 < html> 
< body>
< h1>我们正在加载自定义协议< / h1>
< b>图片?< / b>< br />
< img src =myapp://image1.png/>
< body>
< / html>


Similar questions have been asked before, but I could never find a solution.

Here is my situation - my UIWebView loads a remote html page. The images used in the web pages are known at build time. In order to make the page load faster, I want to package the image files in the iOS application and substitue them at runtime.

[Please note that the html is remote. I always get answers for loading both html and image files from local - I have done that already]

The closest recommendation I got was to use a custom url scheme such as myapp://images/img.png in the html page and in the iOS application, intercept the myapp:// URL with NSURLProtocol subclass and replace the image with a local image. Sounded good in theory, but I haven't come across a complete code example demonstrating this.

I have Java background. I could do this easily for Android using a Custom Content Provider. I am sure a similar solution must exist for iOS/Objective-C. I don't have enough experience in Objective-C to solve it myself in the short timeframe I have.

Any help will be appreciated.

解决方案

Ok here is an example how to subclass NSURLProtocol and deliver an image (image1.png) which is already in the bundle. Below is the subclasses' header, the implementation as well as an example how to use it in a viewController(incomplete code) and a local html file(which can be easily exchanged with a remote one). I've called the custom protocol: myapp:// as you can see in the html file at the bottom.

And thanks for the question! I was asking this myself for quite a long time, the time it took to figure this out was worth every second.

EDIT: If someone has difficulties making my code run under the current iOS version, please have a look at the answer from sjs. When I answered the question it was working though. He's pointing out some helpful additions and corrected some issues, so give props to him as well.

This is how it looks in my simulator:

MyCustomURLProtocol.h

@interface MyCustomURLProtocol : NSURLProtocol
{
    NSURLRequest *request;
}

@property (nonatomic, retain) NSURLRequest *request;

@end

MyCustomURLProtocol.m

#import "MyCustomURLProtocol.h"

@implementation MyCustomURLProtocol

@synthesize request;

+ (BOOL)canInitWithRequest:(NSURLRequest*)theRequest
{
    if ([theRequest.URL.scheme caseInsensitiveCompare:@"myapp"] == NSOrderedSame) {
        return YES;
    }
    return NO;
}

+ (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)theRequest
{
    return theRequest;
}

- (void)startLoading
{
    NSLog(@"%@", request.URL);
    NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[request URL] 
                                                        MIMEType:@"image/png" 
                                           expectedContentLength:-1 
                                                textEncodingName:nil];

    NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"image1" ofType:@"png"];  
    NSData *data = [NSData dataWithContentsOfFile:imagePath];

    [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    [[self client] URLProtocol:self didLoadData:data];
    [[self client] URLProtocolDidFinishLoading:self];
    [response release];
}

- (void)stopLoading
{
    NSLog(@"something went wrong!");
}

@end

MyCustomProtocolViewController.h

@interface MyCustomProtocolViewController : UIViewController {
    UIWebView *webView;
}

@property (nonatomic, retain) UIWebView *webView;

@end

MyCustomProtocolViewController.m

...

@implementation MyCustomProtocolViewController

@synthesize webView;

- (void)awakeFromNib
{
    self.webView = [[[UIWebView alloc] initWithFrame:CGRectMake(20, 20, 280, 420)] autorelease];
    [self.view addSubview:webView];
}

- (void)viewDidLoad
{   
    // ----> IMPORTANT!!! :) <----
    [NSURLProtocol registerClass:[MyCustomURLProtocol class]];

    NSString * localHtmlFilePath = [[NSBundle mainBundle] pathForResource:@"file" ofType:@"html"];

    NSString * localHtmlFileURL = [NSString stringWithFormat:@"file://%@", localHtmlFilePath];

    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:localHtmlFileURL]]];

    NSString *html = [NSString stringWithContentsOfFile:localHtmlFilePath encoding:NSUTF8StringEncoding error:nil]; 

    [webView loadHTMLString:html baseURL:nil];
}

file.html

<html>
<body>
    <h1>we are loading a custom protocol</h1>
    <b>image?</b><br/>
    <img src="myapp://image1.png" />
<body>
</html>

这篇关于带有本地图像文件的iOS WebView远程HTML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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