UIWebView委托获取MIME类型
UIWebView不会自动支持处理Passbook .pkpass文件。UIWebView委托获取MIME类型
在此technical note中,Apple建议通过UIWebViewDelegate方法执行检查以嗅出MIME类型并相应地处理它。
要使用一个UIWebView添加通行证,实施适当的 UIWebViewDelegate方法来识别当与 MIME类型的应用/ vnd.apple.pkpass
然而视图负载的数据,我在能够提供MIME类型的UIWebView Delegate Protocol Reference内找不到任何内容。
我可以直接使用NSURLConnection
委托直接成功下载和处理文件,但是我希望实现的是如果用户在UIWebView中浏览时单击添加到存折按钮,就可以正确处理通行证。由于我不知道链接,许多提供商不会将其链接后缀为.pkpass扩展名,所以遵循Apple关于检查MIME类型的建议似乎是最好的选择。
我曾尝试加入以下
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)newRequest
navigationType:(UIWebViewNavigationType)navigationType
{
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[newRequest URL]];
// Spoof iOS Safari headers for sites that sniff the User Agent
[req addValue:@"Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25" forHTTPHeaderField:@"User-Agent"];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:newRequest delegate:self];
return YES;
}
我NSURLConnection
代表:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSString *mime = [response MIMEType];
if ([mime isEqualToString:@"application/vnd.apple.pkpass"] && ![_data length]) {
_data = nil; // clear any old data
_data = [[NSMutableData alloc] init];
[_webPanel stopLoading];
}
}
-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
[_data appendData:data];
NSLog(@"Size: %d", [_data length]);
}
-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{
if ([_data length]) {
PKAddPassesViewController *pkvc = [PassKitAPI presentPKPassFileFromData:_data];
pkvc.delegate = self;
[self presentViewController:pkvc
animated:YES
completion:nil];
}
}
的NSURLConnection
代表正常工作时的连接直接调用,无需UIWebView
。但是,当我尝试从UIWebView
委托中启动NSURLConnection
时,传递下载失败,因为只有80%左右的.pkpass正在下载(我在_data变量和Content-Length标头中出现了随机的字节不匹配)。
所以,我的问题:
- 是否有更简单的方式来获得一个
MIME
型的保持,直接从UIWebView
委托方法? - 如果不是,那么我是否会以正确的方式开放并行NSURLConnection?或者有更好的方法吗?
- 如果NSURLConnection是要走的路,那么可能导致它停止下载完整文件?
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL *url = request.URL;
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:req delegate:self];
[conn start];
return YES;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSString *mime = [response MIMEType];
NSLog(@"%@",mime);
}
虽然这可行,但由于每次请求都下载了两次,所以开销很大。你的代码也停在MIME类型 - 我的问题是,MIME类型application/vnd.apple.pkpass不直接被UIWebView支持,所以我需要有条件地(有效地)通过NSURLConnection下载这些文件,而不是不加区分地下载所有东西在平行下。 – PassKit 2013-09-08 01:40:01
你能解释以上两点1)下载两次,2)停止MIME类型。在我的代码中,所有这些代表只打一次电话。 shouldStartLoadWithRequest,didReceiveResponse,webViewDidStartLoad,webViewDidFinishLoad。 – Zeeshan 2013-09-08 22:51:06
当这些委托方法触发时,UIWebView也在下载文件(但最终会抛弃它,因为它不知道如何自然处理它)。使用NSURLConnection需要两个独立的请求到服务器的相同的资源(原始从UIWebView +第二种形式NSURLConnection)。 .pkpass文件需要CPU密集型生成,最多可以重达500kb。理想情况下,我应该能够访问原始UIWebView请求中的数据,但错误委托会丢弃此数据。 – PassKit 2013-09-09 02:23:47
你可以尝试继承NSURLProtocol和处理响应信息解析在那里。
看
- (void)URLProtocol:(NSURLProtocol *)protocol didReceiveResponse:(NSURLResponse *)response cacheStoragePolicy:(NSURLCacheStoragePolicy)policy
不要忘了还利用这些钩子约子资源。
你能提供一些更详细的方法吗?似乎唯一避免双重加载资源的方法是独占地使用UIWebview或NSURLConnection,但要像后面那样做很多工作。 – PassKit 2013-10-08 00:48:12
在你的NSURLProtocol中,你会得到每一个子资源制作的请求。你也可以点击每一个响应。您可以根据mainDocumentURL和请求的URL(有时)检查您是否是子资源。响应信息有一个MIMEType属性,您可以查看。 – cynistersix 2013-10-09 15:47:01
只需用js
let contentType = webView.stringByEvaluatingJavaScript(from: "document.contentType;")
你找到了一个解决方案?如果是,你可以分享吗? – 2013-09-29 14:09:11
不 - 我在WWDC与Apple工程师讨论过,他们告诉我没有解决方案。我有一些针对文档和UIWebView代表的开放bug报告。 – PassKit 2013-09-29 16:29:30
你有没有想过这一个?我将不得不进行此操作,并且希望不必再次手动打开服务器。 – MrTristan 2014-09-07 19:23:17