我有一个应用程序可以创建HTML页面并在WebView
中显示它们。那部分效果很好。
我的应用程序具有允许用户查看不同数据的控件。我可以将新的HTML字符串加载到WebView
中。再次,这很好。
我有两个相关的问题:首先,我动态创建的HTML页面包含对<img>
标签中图像的引用,这些标签实际上是压缩的并存储在专有文件中。我可以根据请求将这些加载到某种Cocoa图像对象中,或者我可以将它们解压缩到一个文件中并允许WebView
加载它们。后者可能很简单,但我正在寻找实现前者的方法。我想我需要以某种方式对webView:resource:willSendRequest:redirectResponse:fromDataSource:
消息作出回应/做出反应,以便WebView
一张图片。任何提示?
其次,如果用户选择了一个链接,我需要拦截链接的处理并自己处理。如果链接实际引用页面上的某个位置,我可能只是将用户滚动到同一页面上的某个位置,或者(更频繁地)我想要加载一个完全不同的页面 - 再次,由我的应用程序动态创建并加载为使用WebView
的{{1}}字符串。我想简单地通知URL,以便我可以决定如何处理它(就像我在iOS中使用UIWebView一样),但我不确定最好/最简单的方法。
我把这些问题放在一起,因为可能有一种普遍的方式来看待我错过的整个问题。例如,似乎应该有一种方法来取代正常的页面加载过程,以便loadHtmlString:baseUrl:
向我的应用程序询问它通常要发送到Web请求的字节数。我得到的印象是WebView
做了自己的事情,只有建议我正在从网上加载页面/资源。我需要它来实际请求我的数据。
答案 0 :(得分:2)
最好的方法是实现自己的NSURLProtocol
子类,它可以返回您需要的资源。这样您就可以使用自己的内部URL,URL加载系统将通过调用NSURLProtocol
子类上的方法来获取它们。
这样做非常容易;您需要实施+canInitWithRequest:
来检查您的特殊网址方案,例如
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
NSString *scheme = [[request URL] scheme];
return [scheme caseInsensitiveCompare:@"app"] == NSOrderedSame;
}
然后让您的-startLoading
方法返回正确的数据,例如:
- (void)startLoading
{
NSURLRequest *req = [self request];
id<NSURLProtocolClient> client = [self client];
NSCachedURLResponse *cachedResponse = [self cachedResponse];
if (cachedResponse) {
[client URLProtocol:self cachedResponseIsValid:cachedResponse];
return;
}
// support app:blank
if ([[[req URL] resourceSpecifier] isEqualToString:@"blank"]) {
NSData *data = [NSData data];
NSURLResponse *response
= [[NSURLResponse alloc] initWithURL:[req URL]
MIMEType:@"text/html"
expectedContentLength:[data length]
textEncodingName:@"UTF-8"];
[client URLProtocol:self
didReceiveResponse:response
cacheStoragePolicy:NSURLCacheStorageNotAllowed];
[client URLProtocol:self didLoadData:data];
[client URLProtocolDidFinishLoading:self];
return;
}
// Not found
NSError *error = [NSError errorWithDomain:NSURLErrorDomain
code:NSURLErrorFileDoesNotExist
userInfo:nil];
[client URLProtocol:self didFailWithError:error];
}