2016-04-26 3 views
0

У меня проблема. Я пытаюсь сделать несколько загрузок с помощью NSURLSession, но я не понял, что я делаю неправильно? Этот класс инициализируется один раз в классе X. startDownload (realm.objects (Music) [indexPath.row]) может быть вызван много раз в одном классе. Проблемы в классе «Загрузка», я это точно знаю. Если вам нужна дополнительная информация, пожалуйста, напишитеКак загрузить несколько файлов с помощью NSURLSession

class Download: NSObject, NSURLSessionDelegate { 
var progress: Float = 0.0 
var progressBar: UIProgressView? 
var addButton: UIButton? 


private var downloadTask: [NSURLSessionDownloadTask] = [] 
private var backgroundSession: [NSURLSession] = [] 
private let realm = try! Realm() 

private var downloadObject:[Music] = [] 
private var queueObjects:[Music] = [] 


func startDownload(object: Music? = nil) { 
    if (object != nil) { 
     self.queueObjects.append(object!) 
    } 
    let url = queueObjects[queueObjects.startIndex].url 

    if downloadTask.count < 3 { 
     let backgroundSessionConfiguration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("backgroundSession"+String(queueObjects.count)) 
     backgroundSession.append(NSURLSession(configuration: backgroundSessionConfiguration, delegate: self, delegateQueue: NSOperationQueue.mainQueue())) 
     let sessionIndex = backgroundSession.endIndex-1 
     backgroundSession[sessionIndex].sessionDescription = String(sessionIndex) 

     downloadTask.append(backgroundSession[sessionIndex].downloadTaskWithURL(NSURL(string: url)!)) 
     let taskIndex = downloadTask.endIndex-1 
     downloadTask[taskIndex].taskDescription = String(taskIndex) 
     downloadTask[taskIndex].resume() 

     downloadObject.append(queueObjects[queueObjects.startIndex]) 
     queueObjects.removeAtIndex(queueObjects.startIndex) 
    } 
} 

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

    let index = Int(downloadTask.taskDescription!)! 
    print("Index "+String(index)) 
    let range = downloadObject[ index ].url.rangeOfString("?")!.startIndex.advancedBy(0) 
    let url = downloadObject[ index ].url[downloadObject[index].url.startIndex..<range] 
    let theFileName = (url as NSString).lastPathComponent 
    let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) 
    let directoryPath:String = path[0] 
    let fileManager = NSFileManager() 
    let destinationURLForFile = NSURL(fileURLWithPath: directoryPath.stringByAppendingString("/"+theFileName)) 

    if fileManager.fileExistsAtPath(destinationURLForFile.path!){ 
     print(destinationURLForFile.path!) 
     saveObject(downloadObject[index], path: destinationURLForFile.path!) 
    } 
    else{ 
     do { 
      try fileManager.moveItemAtURL(location, toURL: destinationURLForFile) 
      print(destinationURLForFile.path!) 
      saveObject(downloadObject[index], path: destinationURLForFile.path!) 
     } catch { 
      print("An error occurred while moving file to destination url") 
     } 
    } 
    if addButton != nil { 
     addButton?.hidden = true 
    } 
    downloadTask.cancel() 
    session.invalidateAndCancel() 

    self.backgroundSession[Int(session.sessionDescription!)!].invalidateAndCancel() 
    self.backgroundSession.removeAtIndex(Int(session.sessionDescription!)!) 
    self.downloadTask[Int(downloadTask.taskDescription!)!].cancel() 
    self.downloadTask.removeAtIndex(Int(downloadTask.taskDescription!)!) 
} 

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { 
    progress = Float(totalBytesWritten)/Float(totalBytesExpectedToWrite) 
    if progressBar != nil { 
     progressBar?.progress = progress 
    } 
} 

private func saveObject(object: Music, path: String) { 
    let downloadMusic = DownloadMusic() 
    downloadMusic.id = object.id 
    downloadMusic.owner_id = object.owner_id 
    downloadMusic.artist = object.artist 
    downloadMusic.title = object.title 
    downloadMusic.duration = object.duration 
    downloadMusic.path = path 

    try! realm.write() { 
     realm.add(downloadMusic) 
     downloadObject.removeAtIndex(downloadObject.endIndex-1) 
     if self.queueObjects.count > 0 { 
      self.startDownload() 
     } 
     print(queueObjects.count) 
     print(downloadObject.count) 
     print(downloadMusic) 
    } 
} 

}

Спасибо

+0

Очень сложно отлаживать несколько страниц кода, просто глядя на него, когда вы даже не знаете, как он себя ведет при запуске. Что делает этот код, чего вы не ожидаете? Пожалуйста, опишите, подробно, как оно себя ведет и как это поведение отличается от того, что вы ожидаете. –

ответ

0

Во-первых, не делать это таким образом. Пусть сеанс ограничивает параллелизм для вас. Просто сразу отбросьте все запросы.

Во-вторых, не воссоздавайте конфигурацию фоновой сессии, если только ваше приложение не запустилось. Вы должны создать его ровно один раз и никогда больше. Поведение нескольких объектов NSURLSession, указывающих на один и тот же идентификатор, - это IIRC, undefined.

В-третьих, не аннулируйте сеанс, пока не закончите с ним. Вы отменяете все свои невыполненные запросы, как только заканчивается первый.

В-четвертых, вы не должны отменять задачи, если не хотите остановить выполнение задачи. Если задача уже завершена, ее отмена ничего не делает.

Помимо этого, я соглашусь с людьми, которые сказали, что вам нужно объяснить, что делает код, прежде чем я смогу помочь дальше. :-)