WatchOS 3 WKApplicationRefreshBackgroundTask didReceiveChallenge

久未见 提交于 2019-12-21 06:28:40

问题


I have finally (ignoring the sample code which I never saw work past "application task received, start URL session") managed to get my WatchOS3 code to start a background URL Session task as follows:

 func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {

    for task in backgroundTasks {
        if let refreshTask = task as? WKApplicationRefreshBackgroundTask {
            // this task is completed below, our app will then suspend while the download session runs
            print("application task received, start URL session")

            let request = self.getRequestForRefresh()
            let backgroundConfig = URLSessionConfiguration.background(withIdentifier: NSUUID().uuidString)
            backgroundConfig.sessionSendsLaunchEvents = true
            backgroundConfig.httpAdditionalHeaders = ["Accept":"application/json"]
            let urlSession = URLSession(configuration: backgroundConfig, delegate: self, delegateQueue: nil)
            let downloadTask = urlSession.downloadTask(with: request)

            print("Dispatching data task at \(self.getTimestamp())")
            downloadTask.resume()

            self.scheduleNextBackgroundRefresh(refreshDate: self.getNextPreferredRefreshDate())
            refreshTask.setTaskCompleted()
        }
        else if let urlTask = task as? WKURLSessionRefreshBackgroundTask {
            //awakened because background url task has completed
            let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: urlTask.sessionIdentifier)
            self.backgroundUrlSession = URLSession(configuration: backgroundConfigObject, delegate: self, delegateQueue: nil) //set to nil in task:didCompleteWithError: delegate method

            print("Rejoining session ", self.backgroundUrlSession as Any)
            self.pendingBackgroundURLTask = urlTask //Saved for .setTaskComplete() in downloadTask:didFinishDownloadingTo location: (or if error non nil in task:didCompleteWithError:) 

        } else {
            //else different task, not handling but must Complete all tasks (snapshot tasks hit this logic)
            task.setTaskCompleted()
        }
    }
}

However, the issue I am now seeing is that my delegate method urlSession:task:didReceiveChallenge: is never being hit, so I cannot get my download to complete. (I have also added the session level urlSession:didReceiveChallenge: delegate method and it is also not being hit).

Instead I immediately hit my task:didCompleteWithError: delegate method which has the error:

"The certificate for this server is invalid. You might be connecting to a server that is pretending to be ... which could put your confidential information at risk."

Has anyone gotten the background watch update to work with the additional requirement of hitting the didReceiveChallenge method during the background URL session?

Any help or advice you can offer is appreciated.


回答1:


As it turns out the server certificate error was actually due to a rare scenario in our test environments. After the back end folks gave us a work around for that issue this code worked fine in both our production and test environments.

I never hit urlSession:task:didReceiveChallenge: but it turned out I did not need to.

Made a minor un-related change:
Without prints/breakpoints I was sometimes hitting task:didCompleteWithError Error: like a ms before I hit downloadTask:didFinishDownloadingTo location:.

So I instead set self.pendingBackgroundURLTask completed in downloadTask:didFinishDownloadingTo location:. I only set it completed in task:didCompleteWithError Error: if error != nil.

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

    //Complete task only if error, if no error it will be completed when download completes (avoiding race condition)
    if error != nil {
        self.completePendingBackgroundTask()
    }

}

func completePendingBackgroundTask()
{
    //Release the session
    self.backgroundUrlSession = nil

    //Complete the task
    self.pendingBackgroundURLTask?.setTaskCompleted()
    self.pendingBackgroundURLTask = nil
}

Hope someone else finds this helpful.



来源:https://stackoverflow.com/questions/40404749/watchos-3-wkapplicationrefreshbackgroundtask-didreceivechallenge

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!