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

标签 ios swift nsurlsession

我有一个与 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 - NSAttributedString 背景色渲染 iOS 10 VS iOS 11

ios - Xcode Swift Parse Framework 安装问题(命令 PhaseScriptExecution 失败)

swift - URLSession 数据任务超时错误

Swift 向请求添加参数

php - 在 App 中推送通知

iOS:没有 iTunes 的文件共享?

ios - 管理 iOS 应用程序的多个版本

java - 类将java中的HashMap转换为swift中的NSDictionary

ios - 检查 3D 数组中是否存在元素 Swift

ios - NSURLSession 不返回 http/https 的数据