iphone - 带有本地镜像文件的 iOS WebView 远程 html

标签 iphone html image uiwebview nsurlprotocol

以前也有人问过类似的问题,但我一直找不到解决方案。

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

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

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

我有 Java 背景。我可以使用 Custom Content Provider 轻松地为 Android 执行此操作。我确信 iOS/Objective-C 必须存在类似的解决方案。我没有足够的 Objective-C 经验来在短时间内自己解决它。

我们将不胜感激。

最佳答案

好的,这是一个如何子类化 NSURLProtocol 的例子并传送已在 bundle 中的图像 (image1.png)。下面是子类的标题、实现以及如何在 viewController(不完整代码)和本地 html 文件(可以轻松地与远程文件交换)中使用它的示例。我调用了自定义协议(protocol):myapp://,如您在底部的 html 文件中所见。

谢谢你的提问!我自己问了这个问题很长时间,弄清楚这个问题所花的时间每一秒都是值得的。

编辑: 如果有人让我的代码在当前 iOS 版本下运行有困难,请查看 sjs 的答案。当我回答这个问题时它正在工作。他指出了一些有用的补充并纠正了一些问题,因此也请支持他。

这是它在我的模拟器中的样子:

enter image description here

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>

关于iphone - 带有本地镜像文件的 iOS WebView 远程 html,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5572258/

相关文章:

html - 无法删除 Bootstrap 进度条中的边框

html - 全宽图像 slider

ios - 如何使用 LaunchScreen.storyboard 为所有设备启用原生分辨率

iphone - 如何将 xml 转换为 sqlite?

javascript - 使用 AJAX 加载站点的所有页面

html - 如何将此图像定位在页面的底部中心?

html - 使图像布局为 'inline-block',底部有悬停标题

php - TCPDF 错误 :Unable to get the size of the image

ios - 在swift中使用objectmapper库的Json解析问题

iphone - 无法在模态视图 Controller 上执行模态