来自后台推送的后台网络呼叫

时间:2016-10-15 01:42:57

标签: ios swift nsurlsession

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

问题是当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?)

更新

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

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

上面的内容被调用但是引发错误:"Lost connection to background transfer service"。在处于背景状态但不是前景的情况下,100%的时间都会发生。

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

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

解决方案:

解决方案是删除timeoutIntervalForRequesttimeoutIntervalforResource尽管事实上我从未等待我在问题产生之前设置的15秒,但删除这些允许该过程在后台正常工作。另外,我能够使用标准URLSessionConfiguration.default而不是.background。

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

1 个答案:

答案 0 :(得分:1)

我发现经过上述观点的更多测试后发现事情并不一致。问题是我正在使用URLSessionDataTask,事实证明,后者不支持URLSessionDownloadTask。根据Apple的文档:

  

数据任务请求资源,将服务器的响应作为一个返回   或更多内存中的NSData对象。它们默认支持,   短暂的和共享的会话,但在后台不受支持   会话。

要解决此问题,我必须创建一个func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)并使用其关联的委托

1 21 321 4321 54321

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