【问题标题】:Detecting Download in UIWebView在 UIWebView 中检测下载
【发布时间】:2010-12-06 00:46:22
【问题描述】:

我有一个以编程方式创建的 UIWebView,它用于浏览存储在我的服务器上的 iPhone 风格的网站。在这个网站上,有一些用户可以下载到我的应用程序中的文件的链接。现在,我正在尝试通过以下方式检测到这一点:

- (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;
}

但是,当调用此方法时,内容类型标头几乎总是(null),所以我永远无法下载文件。

你会如何正确地做到这一点?

【问题讨论】:

    标签: objective-c iphone uiwebview


    【解决方案1】:

    您正在尝试从尚未生成的 NSURLRequest 中检测 Content-Type。在使用 NSURLConnection 发出请求之前,您不会知道 Content-Type。在这种情况下,我可能只会查看 URL 路径的文件扩展名。

    【讨论】:

    • 问题是 URL 存储在没有文件名的系统中,它显示为example.com/some/stuff/32f3121a234ae32423
    • 我相信如果你使用“HEAD”的httpMethod,那么你只会得到标题。但是,这将需要在初始点击后调用内容。
    【解决方案2】:

    所以问题来了:UIWebView 不下载它无法显示的任何内容,并且它不知道如何显示 ZIP 文件。在填写 Content-Type 之前总是会失败。

    那么,该怎么办?我不知道您的服务器端应用程序是否在 iPhone 上运行,但您可以注册一个自定义 URL 方案,其中包含 myapplication://example.com/stuff/yourhexurlgoeshere 之类的链接。您可以为 myapplication 方案创建自定义 URL 处理程序。几秒钟的谷歌搜索产生了this site,它解释了如何做到这一点。

    这还有一个额外的好处,例如,如果您将此类链接通过电子邮件发送给其他用户,他们可以在 Mail 中点击它并在您的应用程序中打开它。

    【讨论】:

    • 是否有一种方法可以通过 NSURLConnection 之类的方式获取返回的标头?然后我可以自己手动扫描 zip 文件,但我宁愿不必下载整个页面两次,只需检查标题。
    • 不是真的,webView:shouldStartLoadWithRequest: 期望你返回一个值。您必须将整个应用程序冻结几秒钟才能执行同步 NSURLRequest 以获取标头。这是一个非常棘手的问题。
    • 但是,我可以在启动异步后无论如何都返回 YES,然后让它开始下载可能晚几秒钟(这很好)。但是,我怎么才能得到标题?
    • 这是真的。如果您启动一个NSURLConnection,则委托方法connection:didReceiveResponse: 会为您提供一个NSURLResponse,它将具有MIME 类型。卡布姆。
    【解决方案3】:

    ---------Swift 4+--------

    音频/mp3 检测示例 -

    第 1 步:使用委托

    class ViewController : WKUIDelegate,WKNavigationDelegate {
    

    第 2 步: 设置 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)
        }
    

    第 3 步: 从 webkit 委托获取音频 MIME 类型。

     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 设置

      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 委托

    -(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);
    }
    

    【讨论】:

    • @ShivamParmar 很高兴来到这里
    • 你好@jack,谢谢你的“音频/mpeg”。你能告诉我这个 MIMEType 的文档,它会检测所有的音频下载链接吗?谢谢!
    • 我正在获取音频网址,但我可以获得该音频的预览图像,即缩略图吗?谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多