如何从多个URL以并发模式下载数据? [英] How can I download datas from multiple URL in concurrency mode?

查看:152
本文介绍了如何从多个URL以并发模式下载数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试过链接,仅下载一个网址。成功工作暂停和恢复。



现在我想尝试多个网址(即5个网址)。如果第二个URL正在进行,那么如果我开始第三个URL意味着,第二个被停止。



我不知道以并发方式运行所有url。我已经尝试过NSOperationQueue。但我不知道确切的语法,也不知道如何添加队列中的任务。



我的网址链接之间不应有任何中断。如何做?



我的代码:

  var dict = [NSURLSessionTask:Int]()

lazy var session:NSURLSession = {
let config = NSURLSessionConfiguration.ephemeralSessionConfiguration()

config.allowsCellularAccess = false
let session = NSURLSession(configuration:config,delegate:self,delegateQueue:NSOperationQueue.mainQueue())

println(session)
return session

} )

func URLSession(session:NSURLSession,downloadTask:NSURLSessionDownloadTask,didWriteData bytesWritten:Int64,totalBytesWritten writ:Int64,totalBytesExpectedToWrite exp:Int64){
if let numberOfTask = dict [downloadTask]
{
println(which task is this \(dict [downloadTask]))

println(downloaded \(100 * writ / exp))
taskTotalBytesWritten = Int(writ)
taskTotalBytesExpectedToWrite = Int(exp)
percentageWritten = Float(taskTotalBytesWritten)/ Float(taskTotalBytesExpectedToWrite)

downLoadTblVw.delegate = self
downLoadTblVw .reloadData()
}
}

func URLSession(session:NSURLSession,downloadTask:NSURLSessionDownloadTask,didResumeAtOffset fileOffset:Int64,expectedTotalBytes:Int64){


//在这个例子中不使用
}

func URLSession(session:NSURLSession,task:NSURLSessionTask,didCompleteWithError error:NSError?){
println :error:\(error))
}

//这是唯一需要的NSURLSessionDownloadDelegate方法

func URLSession(session:NSURLSession,downloadTask:NSURLSessionDownloadTask ,didFinishDownloadingToURL location:NSURL){

let documentsDirectoryURL = NSFileManager()。URLsForDirectory(.DocumentDirectory,inDomains:.UserDomainMask).first as NSURL
println(Finished downloaded! $ b println(documentsDirectoryURL)
var err:NSError?

//这里你可以移动你下载的文件
如果NSFileManager()。moveItemAtURL(location,toURL:documentsDirectoryURL.URLByAppendingPathComponent(downloadTask.response!.suggestedFilename!),error:& err ){
println(File saved)
} else {
如果let err = err {
println(File not saved.\\\
\(err.description ))

}
}

}



@IBAction func startDownload(sender:UIButton ){
var btnPos:CGPoint = sender.convertPoint(CGPointZero,toView:downLoadTblVw)
var indePath:NSIndexPath = downLoadTblVw.indexPathForRowAtPoint(btnPos)!

println(INDE\(indePath.row))

buttonTag = indePath.row

if self.task!= nil {

println(PRESSED TASK NIL)
return
}

switch(buttonTag)
{
case 0:

var myQueue = NSOperationQueue()
myQueue.addOperationWithBlock({

let s =https://developer.apple.com/library/ios/documentation) /UserExperience/Conceptual/MobileHIG/MobileHIG.pdf
let url = NSURL(string:s)!
let req = NSMutableURLRequest(URL:url)
let task = self.session.downloadTaskWithRequest (req)
self.task = task

dict [task] = 0
println(SESSION - > task \(task))

task.resume()
println(PRESSED SECOND TIME)
})
break

case 1:

let s =https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/iphoneappprogrammingguide.pdf
let url = NSURL(string:s)!
let req = NSMutableURLRequest(URL:url)

var myQueue = NSOperationQueue()
myQueue.addOperationWithBlock({

let task = self.session .downloadTaskWithRequest(req)
self.task_1 = task
dict [task_1] = 1
println(SESSION _1-> task \(task))
任务。 resume()

})
break

case 2:

let s =http://manuals.info.apple .com / MANUALS / 1000 / MA1565 / zh_US / iphone_user_guide.pdf
let url = NSURL(string:s)!
let req = NSMutableURLRequest(URL:url)
let task = self.session.downloadTaskWithRequest(req)
self.task_2 = task
dict [task_2] = 2
println(SESSION _2-> task \(task))
task.resume()
break

case 3:

let s =https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/AVFoundationPG.pdf
let url = NSURL(string:s)!
let req = NSMutableURLRequest(URL:url)
let task = self.session.downloadTaskWithRequest(req)
self.task_3 = task
dict [task_3] = 3
println(SESSION _3-> task \(task))
task.resume()

break
默认值:
println(WRONG BUTTON PRESSED)
break
}
}


解决方案

您的下载代码看起来很好。当按下按钮时,下载任务将开始。 (例如,如果我点击button_2和button_3,下载任务2和3将同时下载)



您的代码中的缺陷在



func URLSession(session:NSURLSession,
downloadTask:NSURLSessionDownloadTask,
didWriteData bytesWritten:Int64,
totalBytesWritten writ :Int64,
totalBytesExpectedToWrite exp:Int64)

因为你想跟踪进度每个任务,你必须找到 downloadTask 发送此代理调用。



要跟踪哪个任务激活委托,你可以这样做

  let dict = [NSURLSessionTask:Int]()

let task1 = session.DownloadTaskWithURL(.....)
let task2 = session.DownloadTaskWithURL(.....)

dict [task1] = 0
dict [ task2] = 1

并且在委托调用中,您可以获得与您设置的数字相对应的任务这个

  func URLSession(session:NSURLSession,downloadTask:NSURLSessionDownloadTask,didWriteData bytesWritten:Int64,totalBytesWritten writ:Int64,totalBytesExpectedToWrite exp:Int64 ){
if let numberOfTask = dict [downloadTask] {
progress [numberOfTask] = Float(taskTotalBytesWritten)/ Float(taskTotalBytesExpectedToWrite)
downLoadTblVw.reloadData()
}
}


I have tried this link for download only one URL. Successfully working for pause and resume too.

Now I am trying for multiple URL (i.e, for 5 URL). If 2nd URL is progressing, on that time if I start third URL means, 2nd is stopped.

I don't know to run all url in concurrency. I have tried with NSOperationQueue. But I don't know exact syntax and also I don't know how to add task in Queue.

There should not be any interruption between my URL links. How to do that?

My code:

var dict = [NSURLSessionTask:Int]()

lazy var session : NSURLSession = {
        let config = NSURLSessionConfiguration.ephemeralSessionConfiguration()

        config.allowsCellularAccess = false
        let session = NSURLSession(configuration: config, delegate: self, delegateQueue: NSOperationQueue.mainQueue())

        println(session)
        return session

        }()

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten writ: Int64, totalBytesExpectedToWrite exp: Int64) {
        if let numberOfTask = dict[downloadTask]
    {
        println("which task is this\(dict[downloadTask])")

        println("downloaded \(100*writ/exp)")
        taskTotalBytesWritten = Int(writ)
        taskTotalBytesExpectedToWrite = Int(exp)
        percentageWritten = Float(taskTotalBytesWritten) / Float(taskTotalBytesExpectedToWrite)

        downLoadTblVw.delegate = self
        downLoadTblVw.reloadData()
    }
     }

    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) {


        // unused in this example
    }

    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
        println("completed: error: \(error)")
    }

    // this is the only required NSURLSessionDownloadDelegate method

    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {

        let documentsDirectoryURL =  NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first as NSURL
        println("Finished downloading!")
        println(documentsDirectoryURL)
        var err:NSError?

        // Here you can move your downloaded file
        if NSFileManager().moveItemAtURL(location, toURL: documentsDirectoryURL.URLByAppendingPathComponent(downloadTask.response!.suggestedFilename!), error: &err) {
            println("File saved")
        } else {
            if let err = err {
                println("File not saved.\n\(err.description)")

            }
        }

    }



    @IBAction func startDownload(sender: UIButton) {
        var btnPos: CGPoint = sender.convertPoint(CGPointZero, toView: downLoadTblVw)
        var indePath: NSIndexPath = downLoadTblVw.indexPathForRowAtPoint(btnPos)!

        println("INDE\(indePath.row)")

        buttonTag = indePath.row

        if self.task != nil {

            println("PRESSED TASK NIL")
            return
        }

        switch(buttonTag)
        {
        case 0:

            var myQueue = NSOperationQueue()
            myQueue.addOperationWithBlock({

                let s = "https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/MobileHIG.pdf"
                let url = NSURL(string:s)!
                let req = NSMutableURLRequest(URL:url)
                let task = self.session.downloadTaskWithRequest(req)
                self.task = task

                dict[task] = 0
                println("SESSION -> task \(task)")

                task.resume()
                println("PRESSED SECOND TIME")
            })
            break

        case 1:

  let s = "https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/iphoneappprogrammingguide.pdf"
            let url = NSURL(string:s)!
            let req = NSMutableURLRequest(URL:url)

            var myQueue = NSOperationQueue()
            myQueue.addOperationWithBlock({

                let task = self.session.downloadTaskWithRequest(req)
                self.task_1 = task
                dict[task_1] = 1
                println("SESSION _1-> task \(task)")
                task.resume()

                })
            break

        case 2:

            let s = "http://manuals.info.apple.com/MANUALS/1000/MA1565/en_US/iphone_user_guide.pdf"
            let url = NSURL(string:s)!
            let req = NSMutableURLRequest(URL:url)
            let task = self.session.downloadTaskWithRequest(req)
            self.task_2 = task
            dict[task_2] = 2
            println("SESSION _2-> task \(task)")
            task.resume()
            break

        case 3:

            let s = "https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/AVFoundationPG.pdf"
            let url = NSURL(string:s)!
            let req = NSMutableURLRequest(URL:url)
            let task = self.session.downloadTaskWithRequest(req)
            self.task_3 = task
            dict[task_3] = 3
            println("SESSION _3-> task \(task)")
            task.resume()

            break
        default:
            println("WRONG BUTTON PRESSED")
            break
        }
      }

解决方案

Your download code look fine. When the button is pressed the download task will begin. ( For example, If I click at button_2 and button_3, the download task of 2 and 3 will be downloaded simultaneously )

The flaw in your code is at

func URLSession(session: NSURLSession, 
                downloadTask: NSURLSessionDownloadTask, 
                didWriteData bytesWritten: Int64, 
                totalBytesWritten writ: Int64, 
                totalBytesExpectedToWrite exp: Int64)

Since you want to keep track the progress of each task, you have to find which downloadTask that send this delegate call.

To keep track which task fire the delegate, you can do something like this

let dict = [NSURLSessionTask:Int]()

let task1 = session.DownloadTaskWithURL( ..... ) 
let task2 = session.DownloadTaskWithURL( ..... ) 

dict[task1] = 0
dict[task2] = 1

and in the delegate call, you can get the task correspond to number you set like this

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten writ: Int64, totalBytesExpectedToWrite exp: Int64) {
    if let numberOfTask = dict[downloadTask]{
        progress[numberOfTask] = Float(taskTotalBytesWritten) / Float(taskTotalBytesExpectedToWrite)
        downLoadTblVw.reloadData()
    }
}

这篇关于如何从多个URL以并发模式下载数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆