草庐IT

ios - 如何处理后台 url session 丢失的互联网连接?

coder 2023-09-13 原文

我有后台下载 zip 文件:

if let url = NSURL(string: urlstring) 
         {            
            let config = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier((NSUUID().UUIDString))
            let session = NSURLSession(configuration: config, delegate: self, delegateQueue: nil)
            let task = session.downloadTaskWithURL(url)
            session.sessionDescription = filepath
            if let sessionId = session.configuration.identifier
            {
                print("start zip session: " + sessionId)
            }

            task.resume()               
            }
        }

如果你有互联网连接,它会很酷,但如果你在下载应用程序期间丢失它,只需等待,并且 URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) 永远不会被调用。 怎么处理?
服务器响应时间之类的东西

最佳答案

这个问题很老了,但仍然没有答案,所以这里有一个解决方法。

先做一些说明

通常 URLSessionConfiguration 有一个名为 waitsForConnectivity 的属性,可以将其设置为 false,其中 URLSessionTask 将然后在连接丢失时直接失败。但是,如果 trueURLSessionTaskDelegate 将在 urlSession(_:taskIsWaitingForConnectivity:) 方法上收到回调。

但是

DownloadTask 等后台任务始终等待连接并忽略 URLSessionConfigurationwaitsForConnectivity 属性。它们还不要触发urlSession(_:taskIsWaitingForConnectivity:) 回调,因此没有正式的方法来监听下载任务中的连接中断。

解决方法

如果您监听下载进度,您会注意到该方法的调用在一秒钟内进行了几次。因此我们可以得出结论,如果进度回调未被调用超过 5 秒,则可能存在连接断开问题。因此,解决方法是为 URLSessionDownloadDelegate 委托(delegate)添加附加属性并存储进度的最后更新。然后有间隔函数定期检查这个属性是否没有很快更新。

类似于:

    class Downloader: NSObject, URLSessionTaskDelegate, URLSessionDownloadDelegate {

        var lastUpdate: Date;
        var downloadTask: URLSessionDownloadTask?;

        public var session : URLSession {
            get {
                let config = URLSessionConfiguration.background(
                withIdentifier: "\(Bundle.main.bundleIdentifier!).downloader");
                config.isDiscretionary = true;

                return URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue());
            }
        }

        override init() {
            self.lastUpdate = Date();
            super.init();
        }

        func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
            // Handle download completition
            // ...
        }

        func urlSession(
            _ session: URLSession,
            downloadTask: URLSessionDownloadTask,
            didWriteData bytesWritten: Int64,
            totalBytesWritten writ: Int64,
            totalBytesExpectedToWrite exp: Int64)
        {
            let progress = 100 * writ / exp;
            // Do something with the progress
            // ...

            self.lastUpdate = Date();
        }
    }

    var downloader = Downloader();
    let url = "http://...";
    var request = URLRequest(url: URL(string: url)!);
    currentWorker.downloadTask = downloader.session.downloadTask(with: request);
    currentWorker.downloadTask!.resume();

    // Schedule timer for every 5 secs
    var timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "CheckInternetDrop", userInfo: nil, repeats: true);

func CheckInternetDrop(){
    let interval = Date().timeIntervalSinceDate(downloader.lastUpdate);
    if (interval > 5) {
        print("connection dropped");
    }
}

非常简单的例子...

关于ios - 如何处理后台 url session 丢失的互联网连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35342911/

有关ios - 如何处理后台 url session 丢失的互联网连接?的更多相关文章

  1. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  2. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  3. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  4. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  5. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  6. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  7. ruby - 如何在 ruby​​ 中运行后台线程? - 2

    我是ruby​​的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp

  8. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  9. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  10. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

随机推荐