xcode 使用 Web 视图下载文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28947892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 06:47:41  来源:igfitidea点击:

Downloading a file using web view

iosxcodeswiftdownload

提问by Utku Dalmaz

In a project, i want to download mp3 files in a http page loaded in web view. Downloaded files could be opened by apps like phone drive or dropbox.

在一个项目中,我想在 web 视图中加载的 http 页面中下载 mp3 文件。下载的文件可以通过手机驱动器或保管箱等应用程序打开。

When user click to the link in web view it should download it to iphone.

当用户点击网页视图中的链接时,它应该将其下载到 iphone。

In server side, mp3 files are located outside of webroot. So, the link for download is something like "download.php?id=554"

在服务器端,mp3 文件位于 webroot 之外。因此,下载链接类似于“download.php?id=554”

Anyone can help me on this subject ? I wonder is there a way to achieve this. Thanks

任何人都可以帮助我解决这个问题吗?我想知道有没有办法实现这一目标。谢谢

EDIT

编辑

I added this delegate

我添加了这个代表

func webView(webView: UIWebView!, shouldStartLoadWithRequest request: NSURLRequest!, navigationType: UIWebViewNavigationType) -> Bool {

        var urlm = request.URL.absoluteURL?.absoluteString

        if urlm?.rangeOfString("filename") != nil{

            print(urlm)

            //code to download (I NEED IT TOO) 

            return false
        }


    return true
    }

But still don't know how to download ?

但是还是不知道怎么下载?

采纳答案by Utku Dalmaz

SwiftHTTP (https://github.com/daltoniam/swiftHTTP) made it possible to me!

SwiftHTTP ( https://github.com/daltoniam/swiftHTTP) 使我成为可能!

回答by Adam Fallon

It is this simple my friend,

我的朋友就是这么简单,

NSString *stringURL = @"http://www.somewhere.com/thefile.png";
NSURL  *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if ( urlData )
{
  NSArray       *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString  *documentsDirectory = [paths objectAtIndex:0];  

  NSString  *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"filename.png"];
  [urlData writeToFile:filePath atomically:YES];
}

it advisable to execute the code in a separate thread.

建议在单独的线程中执行代码。

For large downloads:

对于大下载:

-(IBAction) downloadButtonPressed:(id)sender;{
    //download the file in a seperate thread.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"Downloading Started");
        NSString *urlToDownload = @"http://www.somewhere.com/thefile.png";
        NSURL  *url = [NSURL URLWithString:urlToDownload];
        NSData *urlData = [NSData dataWithContentsOfURL:url];
        if ( urlData )
        {
            NSArray       *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString  *documentsDirectory = [paths objectAtIndex:0];

            NSString  *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"filename.png"];

            //saving is done on main thread
            dispatch_async(dispatch_get_main_queue(), ^{
                [urlData writeToFile:filePath atomically:YES];
                NSLog(@"File Saved !");
            });
        }

    });

}

回答by Trident

I did not get your actual requirement, but you can download the files from a URL using below code.

我没有得到您的实际要求,但您可以使用以下代码从 URL 下载文件。

NSString *stringURL = @"http://www.somewhere.com/Untitled.mp3";
NSURL  *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];

you can get the mp3 file urls(read from NSURLRequest object) when you press the links on webpage, from UIWebView delegate method

当您按下网页上的链接时,您可以从 UIWebView 委托方法获取 mp3 文件网址(从 NSURLRequest 对象中读取)

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    return NO;
}

Creating a UIWebView in Swift,

在 Swift 中创建一个 UIWebView,

override func viewDidLoad() {
    super.viewDidLoad()
    let webV:UIWebView = UIWebView(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height))
    webV.loadRequest(NSURLRequest(URL: NSURL(string: "http://www.somewhere.com")))
    webV.delegate = self;
    self.view.addSubview(webV)
}

When user clicks a link in the web page, the UIWebView will call "shouldStartLoadWithRequest" method automatically, use below code to download the file

当用户点击网页中的链接时,UIWebView 会自动调用“shouldStartLoadWithRequest”方法,使用以下代码下载文件

func webView(webView: UIWebView!,
shouldStartLoadWithRequest request: NSURLRequest!,
navigationType navigationType: UIWebViewNavigationType) -> Bool {
    println("Redirecting URL = \(request.URL)")

    //check if this is a mp3 file url and download
    if(mp3 file)
    {
        let request:NSURLRequest = NSURLRequest(request.URL)
        let queue:NSOperationQueue = NSOperationQueue()
        NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse!, mp3Data: NSData!, error: NSError!) -> Void in
            let documentsPath : AnyObject = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask,true)[0]
            let destinationPath:NSString = documentsPath.stringByAppendingString("/Untitled.mp3")
            mp3Data.writeToFile(destinationPath, atomically: true)

            return false
    })
    return true
}

I hope this helps

我希望这有帮助

回答by Maximilian Litteral

To be able to detect a download from a link like that, you need to first check the request and the navigation type in shouldStartLoadWithRequest.

为了能够从这样的链接中检测到下载,您需要首先检查请求和shouldStartLoadWithRequest.

You will want to check a few things, the request HTTPMethodwill be POST, also the navigation type will be either UIWebViewNavigationTypeFormSubmitted, UIWebViewNavigationTypeFormResubmitted, or UIWebViewNavigationTypeLinkClicked. You will also need to parse the query string of the requests URL, it will have a response-content-disposition, attachment, or dlkey, and if it has one then it is a file download. Then you will need to create a NSURLConnectionfor the request and start it, then return NOin the web view delegate.

您将要检查的几件事情,请求HTTPMethod将POST,也是导航类型将为UIWebViewNavigationTypeFormSubmittedUIWebViewNavigationTypeFormResubmittedUIWebViewNavigationTypeLinkClicked。您还需要解析请求的URL的查询字符串,就会有一个response-content-dispositionattachmentdl键,如果有的话那么它是一个文件下载。然后你需要NSURLConnection为请求创建一个并启动它,然后NO在 web 视图委托中返回。

Here is how I check for downloads in my app. (Goes in shouldStartLoadWithRequest)

这是我在我的应用程序中检查下载的方法。(进去shouldStartLoadWithRequest

NSDictionary *dict = [url parseQueryString];

    if (([[request.HTTPMethod uppercaseString] isEqualToString:@"POST"] &&
        (navigationType == UIWebViewNavigationTypeFormSubmitted ||
         navigationType == UIWebViewNavigationTypeFormResubmitted ||
         navigationType == UIWebViewNavigationTypeLinkClicked)) || [[dict objectForKey:@"response-content-disposition"] isEqualToString:@"attachment"] || [[dict objectForKey:@"dl"] boolValue] == YES) {
        NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
        [connection start];
        return NO;
    }

You will then need to add the NSURLConnectiondelegate method didReceiveResponse. I check for some keys in the header fields and then you can start a download if they pass, or have the web view continue loading if it turns out to not be a download. (Goes in didReceiveResponse)

然后您需要添加NSURLConnection委托方法 didReceiveResponse。我检查标题字段中的某些键,然后如果它们通过,您可以开始下载,或者如果结果不是下载,则继续加载 Web 视图。(进去didReceiveResponse

    if (urlResponse.allHeaderFields[@"Content-Disposition"] ||
                 ([[urlResponse.allHeaderFields[@"Content-Type"] lowercaseString] containsString:@"text/html;"] == NO &&
                  [[urlResponse.allHeaderFields[@"Content-Type"] lowercaseString] containsString:@"charset=utf-8"] == NO )) {
                      // Start a download with NSURLSession with response.URL and connection.currentRequest
            }
            else {
                [self.webView loadRequest:connection.currentRequest];
                [connection cancel];
            }