Cocoa 如何将WebView与动态创建的HTML一起使用

Cocoa 如何将WebView与动态创建的HTML一起使用,cocoa,webview,Cocoa,Webview,我有一个应用程序,可以创建HTML页面并在WebView中显示它们。那部分效果很好 我的应用程序具有允许用户查看不同数据的控件。我可以将新的HTML字符串加载到WebView中。同样,这很好 我有两个相关的问题:首先,我动态创建的HTML页面包含对标记中图像的引用,这些图像实际上被压缩并存储在本地专有文件中。我可以根据请求将它们加载到某种Cocoa图像对象中,也可以将它们解压缩到文件中,并允许WebView加载它们。后者可能很简单,但我正在寻找实现前者的方法。我想我需要对webView:reso

我有一个应用程序,可以创建HTML页面并在
WebView
中显示它们。那部分效果很好

我的应用程序具有允许用户查看不同数据的控件。我可以将新的HTML字符串加载到
WebView
中。同样,这很好

我有两个相关的问题:首先,我动态创建的HTML页面包含对
标记中图像的引用,这些图像实际上被压缩并存储在本地专有文件中。我可以根据请求将它们加载到某种Cocoa图像对象中,也可以将它们解压缩到文件中,并允许
WebView
加载它们。后者可能很简单,但我正在寻找实现前者的方法。我想我需要对
webView:resource:willSendRequest:redirectResponse:fromDataSource:
消息作出响应/反应,并以某种方式将其发送到手
webView
图像。有什么提示吗

第二,如果用户选择了一个链接,我需要拦截对该链接的处理并自己处理。如果链接实际引用了页面上的某个位置,我可以简单地将用户滚动到同一页面上的某个位置,或者(更频繁地)我希望加载一个完全不同的页面——同样,由我的应用程序动态创建,并使用
loadHtmlString:baseUrl:
将其作为字符串加载到
WebView
。我只想得到URL的通知,这样我就可以决定如何使用它(就像我在iOS中使用UIWebView一样),但我不确定最好/最简单的方法是什么


我把这些问题放在一起,因为可能有一种通用的方式来看待我所遗漏的整个问题。例如,似乎应该有一种方法来取代正常的页面加载过程,以便
WebView
向我的应用程序请求它通常会到Web请求的字节。我得到的印象是,
WebView
做自己的事情,只告诉我它正在从Web加载页面/资源。我需要它来实际请求我的数据。

最好的方法是实现自己的
NSURLProtocol
子类,它可以返回您需要的资源。这样,您就可以使用自己的内部URL,URL加载系统将通过调用
NSURLProtocol
子类上的方法来获取它们

这真的很容易做到;您需要实现
+canInitWithRequest:
来检查您的特殊URL方案,例如

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
  NSString *scheme = [[request URL] scheme];
  return [scheme caseInsensitiveCompare:@"app"] == NSOrderedSame;
}
然后让您的
-starting
方法返回正确的数据,例如:

- (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];
}
-(无效)惊人的负载
{
NSURLRequest*req=[自我请求];
id client=[self client];
NSCachedURLResponse*cachedResponse=[自cachedResponse];
如果(缓存响应){
[客户端URL协议:自缓存响应验证:缓存响应];
返回;
}
//支持应用程序:空白
if([[[req URL]资源说明符]isEqualToString:@“blank”]){
NSData*数据=[NSData数据];
NSURLResponse*响应
=[[NSURLResponse alloc]initWithURL:[req URL]
MIMEType:@“text/html”
expectedContentLength:[数据长度]
text编码名称:@“UTF-8”];
[客户端URL协议:self]
接收方回复:回复
cacheStoragePolicy:NSURLCacheStorageNotAllowed];
[客户端URLProtocol:self-didLoadData:data];
[客户端URLProtocoldFinishLoading:self];
返回;
}
//找不到
NSError*error=[NSError errorWithDomain:NSURErrorDomain
代码:NSURErrorFileDoesNotExist
用户信息:无];
[客户端URL协议:自身错误:错误];
}