草庐IT

ios - 来自后台推送的后台网络调用

coder 2023-09-16 原文

我有一个与 Apple Watch 通信的应用程序。当主 iOS 应用程序收到远程通知时,它会使用 URLSession 触发网络请求,然后将结果发送到 watch 。

问题是,当 iOS 应用程序在后台并收到推送通知时,永远不会进行网络调用。我可以通过断点看到执行了代码,但没有执行接收数据时的代码。

我确实设置了内容可用标志,我也尝试过使用 URLSessionConfiguration.background 但没有成功。

var config:URLSessionConfiguration!
var session:URLSession?

private func configureSession()
{
        self.config = URLSessionConfiguration.background(withIdentifier: "backgroundFetch")
        //self.config = URLSessionConfiguration.default
        self.config.sessionSendsLaunchEvents = true
        self.config.timeoutIntervalForRequest = 15.0
        self.config.timeoutIntervalForResource = 15.0

        self.session = URLSession(configuration: self.config, delegate: self, delegateQueue: nil)
}

你可以在上面看到我在默认和后台模式下都试过了。

func getCoordinatesForID(_ trackID:String, withPassCode passCode:String, andMyID myID:String)
{
    let url = self.WEB_DOMAIN+"getcoord"
    let hash = SecurityModel.sha256(myID+trackID+passCode)!
    var request = URLRequest(url: URL(string: url)!)

    request.httpMethod = "POST"
    request.setValue("application/x-www-form-urlencoded;charset=utf-8", forHTTPHeaderField: "Content-Type")

    let postDataStr = "auth=\(hash)&id=\(myID)&trk=\(trackID)&code=\(passCode)"

    let requestBodyData = postDataStr.data(using: String.Encoding.utf8)
    request.httpBody = requestBodyData

    let postDataTask = self.session!.dataTask(with: request)
    postDataTask.taskDescription = "getCoordinates"
    postDataTask.resume()
}

上述函数是在后台调用的,但这就是事情停止的地方。什么也没有收到。在前台工作正常。

我确实实现了下面的代码,但在后台时都不会调用。

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)

更新:

根据 Edward 的评论,我确实更新了功能以包括“后台获取”,尽管有关在通知后下载的文档并未表明这是必要的。这似乎奏效了,但只是部分奏效,因此问题仍然存在。

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) 

上面的代码被调用但抛出错误:“与后台传输服务失去连接”。在后台状态而非前台状态下 100% 的时间发生。

 func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)

我需要并在它上面的方法之前首先调用的上面,根本没有被调用。所以总体上事情已经取得了一些进展,但仍然不像在前台时那样工作。

解决方案:

解决方案是删除 timeoutIntervalForRequesttimeoutIntervalforResource 尽管事实上我从来没有等到我设置的 15 秒才出现问题,删除这些允许进程工作正确地在后台。此外,我能够使用标准的 URLSessionConfiguration.default 而不是 .background。

所以最后添加“后台获取”功能并删除超时解决了这个问题。

最佳答案

在对上述想法进行更多测试后,我发现事情并没有始终如一地运作。问题是我使用的是 URLSessionDataTask,事实证明,后台不支持它。根据 Apple 的文档:

Data tasks request a resource, returning the server’s response as one or more NSData objects in memory. They are supported in default, ephemeral, and shared sessions, but are not supported in background sessions.

为了解决这个问题,我必须创建一个 URLSessionDownloadTask 并使用其关联的委托(delegate)

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)

当应用程序处于后台时,通过上述网络调用可以正常工作。

关于ios - 来自后台推送的后台网络调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40054133/

有关ios - 来自后台推送的后台网络调用的更多相关文章

  1. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  2. 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返回它复制的字节数,但是当我还没有下

  3. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

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

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

  5. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  6. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  7. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  8. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  9. 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使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  10. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

随机推荐