问题
I have a programatically crated UIWebView, and it is used to browse a iPhone-style site stored on my server. In this website, there are a few links to files users can download into my application. Right now, I'm trying to detect this with:
- (BOOL) webView:(UIWebView *) webView shouldStartLoadWithRequest:(NSURLRequest *) request navigationType:(UIWebViewNavigationType) navigationType
{
url = [request URL];
NSString *mimeType = [request valueForHTTPHeaderField:@"Content-Type"];
NSLog(@"Content-type: %@", mimeType);
if(mimeType == @"application/zip" || mimeType == @"application/x-zip" || mimeType == @"application/octet-stream")
{
NSLog(@"Downloading file!");
[NSThread detachNewThreadSelector:@selector(download:) toTarget:self withObject:@"/tmp/file.ipa"];
return NO;
}
return YES;
}
However, when this method is called, the content-type header is almost always (null), so I never am able to download a file.
How would you do this correctly?
回答1:
You're trying to detect a Content-Type from an NSURLRequest which has not yet been made. You won't know the Content-Type until after the request is made using NSURLConnection. In this case, I'd probably just look at the file extension of the URL path.
回答2:
So here's the problem: UIWebView doesn't download anything it can't display, and it doesn't know how to display a ZIP file. It will always fail before the Content-Type is filled in.
So, what to do? I don't know if your server-side app runs on more than the iPhone, but you could register a custom URL scheme with links like myapplication://example.com/stuff/yourhexurlgoeshere. You can create a custom URL handler for the myapplication scheme. A couple of seconds of Googling produced this site, which explains how to do it.
This has an additional benefit because if you, say, emailed such a link to another user, they could tap on it in Mail and have it open in your application.
回答3:
----------Swift 4+-------
Example for audio/mp3 detect -
Step 1: Use delegate
class ViewController : WKUIDelegate,WKNavigationDelegate {
Step 2: Setting WebKit
func setWebView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
webView.navigationDelegate = self
view = webView
let myURL = URL(string: "https://www.bossmobi.guru/files/download/type/320/id/197255")//your audio url
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}
Step 3: Get audio MIME type from webkit delegate.
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
print( #function + "url is \(String(describing: webView.url))" + "Mimetype" + "\(navigationResponse.response.mimeType ?? "NotAvailable")")
if let _ = navigationResponse.response.mimeType?.range(of: "audio/mpeg") {
print("MP3 is audio url \(String(describing: webView.url))")
webView.stopLoading()
}
decisionHandler(.allow)
}
---------ObjC----------
WKWebView setup
NSString *urlString = @"https://www.bossmobi.guru/files/download/type/320/id/197255";
WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];
WKWebView *_demoWKWebView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:theConfiguration];
_demoWKWebView.navigationDelegate = self;
_demoWKWebView.UIDelegate = self;
NSURL *nsurl=[NSURL URLWithString:urlString];
NSURLRequest *nsrequest=[NSURLRequest requestWithURL:nsurl];
[_demoWKWebView loadRequest:nsrequest];
[self.view addSubview:_demoWKWebView];
WKWebView delegate
-(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
//NSLog(@"decidePolicyForNavigation---Response %@",webView.URL);
if ([navigationResponse.response.MIMEType isEqualToString:@"audio/mpeg"]) {
NSLog(@"MP3 audio url is %@",webView.URL);
}
decisionHandler(WKNavigationResponsePolicyAllow);
}
来源:https://stackoverflow.com/questions/1555289/detecting-download-in-uiwebview