downloadTaskWithRequest令人困惑的行为(swift,IOS)

时间:2015-10-27 14:49:28

标签: ios swift download background nsurlsession

我不理解以下内容并希望有人这样做: - )

我正在从网址下载文件(10分钟下载时间),下载完成后工作正常。

BUT: 当我在一分钟后模拟崩溃或互联网中断并再次重启应用程序时,它对我来说很奇怪。 在这种情况下,重新启动我的应用程序以使用相同的sessionid再次下载时,似乎2个下载任务并行工作。我认为这有一个跳跃进度条从10%到0%然后回来。一个,从头开始,一个,我想连续旧的转移。 (不确定)。我可以重新启动,然后队列中还有一个。

有人可以确认此行为并让别人知道我可以: - 仅继续中断的下载任务(首选:-)) - 或者我怎样才能从头开始。

这是我的下载代码,无需任何中断即可正常工作。

func download_file(sURL: String, sToLocation: String) {

    println("start downloading ...");
    println("sURL : " + sURL + " sToLocation : " + sToLocation);
    bytesDownloaded=0;

    var delegate = self;
    delegate.storePath=sToLocation;
    delegate.progressView=progressView;
    struct SessionProperties {
        static let identifier : String! = "url_session_background_download"
    }
    var configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(SessionProperties.identifier)
    var backgroundSession = NSURLSession(configuration: configuration, delegate: delegate, delegateQueue: nil)
    //myURLSession = NSURLSession(configuration: configuration, delegate: delegate, delegateQueue: nil)
    var url = NSURLRequest(URL: NSURL(string: sURL)!)
    var downloadTask = backgroundSession.downloadTaskWithRequest(url)

    //downloadTask.cancel()

    downloadTask.resume()

}

更新 当我使用不同的sessionid时,下载从头开始。先前启动的下载任务仍在后台运行。所以我想知道为什么我不能通过使用旧的sessionid恢复以前的下载任务,而无需并行开始新的下载?

2 个答案:

答案 0 :(得分:1)

使用下载任务的重点是,即使您的应用未运行或崩溃,下载仍可继续。您不需要恢复下载。它实际上发生在一个单独的后台守护进程中。您只需使用相同的ID重新创建会话。

重新创建会话后,任何现有下载都会自动与新会话关联,并且只要任务完成,就会调用您的委托方法。

如果你的应用程序在下载完成后没有运行,那么你需要实现处理后台启动的一些魔力。有关详细信息,请参阅URL Session Programming Guide

答案 1 :(得分:1)

除了dgatwood所说的,还记得必须让你的app委托实现application:handleEventsForBackgroundURLSession:completionHandler:,如果下载完成并且你的应用程序当时没有运行,则会调用它。调用此方法时(同样,只有在应用程序未运行时下载完成),您应该(a)保存completionHandler; (b)使用相同的标识符实例化后台会话; (c)让你的NSURLSessionDownloadDelegate方法被调用(在didFinishDownloadingToURL:被调用的时候)和何时调用(d)URLSessionDidFinishEventsForBackgroundURLSession,如果你有completionHandler调用handleEventsForBackgroundURLSession时,这是调用此已保存completionHandler的适当时间。

基本思路如下:如果您的应用程序在下载完成后尚未运行,则操作系统会在后台无缝启动您的应用程序(最终用户不知道),提供对此completionHandler的引用,然后让应用程序执行将下载的文件移动到新位置所需的所有操作,完成所有操作后,调用已保存的completionHandler让操作系统知道您已完成处理后台执行中下载的文件和应用程序可以安全地再次暂停(即避免应用程序在后台运行,对用户的UX和电池产生负面影响)。

显然,如果应用程序正在运行并且NSURLSession已经实例化,那么您将看不到这些与背景相关的事件。如果应用程序在下载完成时正在运行,则其行为与前景NSURLSession非常相似,并且不会调用上述内容。但是,如果您的应用在下载完成后未运行,则需要该逻辑。

请参阅适用于iOS的应用程序编程指南Downloading Content in the Background部分,其中介绍了此过程。另请参阅What’s New in Foundation Networking中的WWDC 2013视频(稍后将在视频中介绍)。