当前位置: 首页 > 面试题库 >

带有请求块的URLSession.datatask未在后台调用

管和志
2023-03-14
问题内容

URLSession当应用程序在后台运行并被dataTask请求卡住时,数据任务块未调用。
当我打开应用程序时,将调用该块。顺便说一下,我正在使用https请求。
这是我的代码:

    let request = NSMutableURLRequest(url: URL(string: url as String)!,

                                      cachePolicy: .reloadIgnoringCacheData,

                                      timeoutInterval:20)

    request.httpMethod = method as String

    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

    let session = URLSession.shared

    let data = params.data(using: String.Encoding.utf8.rawValue)

    request.httpBody = data

    session.dataTask(with: request as URLRequest,completionHandler:

        {(data, response, error) -> Void in

         if error == nil

            {

                do {

                    let result = try JSONSerialization.jsonObject(with: data!, options:

                        JSONSerialization.ReadingOptions.mutableContainers)

                    print(result)

                     completionHandler(result as AnyObject?,nil)

                }

                catch let JSONError as NSError{

                    completionHandler(nil,JSONError.localizedDescription as NSString?)

                }

            }

            else{

                completionHandler(nil,error!.localizedDescription as NSString?)

            }

    }).resume()

当应用程序处于活动状态时,可以完美运行。我的代码有什么问题吗?请指出我


问题答案:

如果要在应用程序不再处于前台状态后继续下载,则必须使用后台会话。在后台下载文件中概述了后台会话的基本限制,主要包括:

  1. 使用基于委托的URLSession背景URLSessionConfiguration

  2. 仅使用上传和下载任务,没有完成处理程序。

  3. 在iOS中,实施application(_:handleEventsForBackgroundURLSession:completionHandler:)应用程序委托,保存完成处理程序并启动后台会话。

实现urlSessionDidFinishEvents(forBackgroundURLSession:)你的URLSessionDelegate,呼吁救完成处理程序,让OS知道你在做处理后台请求完成。

因此,将其组合在一起:

func startRequest(for urlString: String, method: String, parameters: String) {
    let url = URL(string: urlString)!
    var request = URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 20)
    request.httpMethod = method
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.httpBody = parameters.data(using: .utf8)
    BackgroundSession.shared.start(request)
}

哪里

class BackgroundSession: NSObject {
    static let shared = BackgroundSession()

    static let identifier = "com.domain.app.bg"

    private var session: URLSession!

    #if !os(macOS)
    var savedCompletionHandler: (() -> Void)?
    #endif

    private override init() {
        super.init()

        let configuration = URLSessionConfiguration.background(withIdentifier: BackgroundSession.identifier)
        session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
    }

    func start(_ request: URLRequest) {
        session.downloadTask(with: request).resume()
    }
}

extension BackgroundSession: URLSessionDelegate {
    #if !os(macOS)
    func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
        DispatchQueue.main.async {
            self.savedCompletionHandler?()
            self.savedCompletionHandler = nil
        }
    }
    #endif
}

extension BackgroundSession: URLSessionTaskDelegate {
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        if let error = error {
            // handle failure here
            print("\(error.localizedDescription)")
        }
    }
}

extension BackgroundSession: URLSessionDownloadDelegate {
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        do {
            let data = try Data(contentsOf: location)
            let json = try JSONSerialization.jsonObject(with: data)

            print("\(json)")
            // do something with json
        } catch {
            print("\(error.localizedDescription)")
        }
    }
}

iOS应用程序委托执行以下操作:

func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
    BackgroundSession.shared.savedCompletionHandler = completionHandler
}


 类似资料:
  • 问题内容: 我有以下指令: 这是我如何调用它: 首次初始化指令时,则为空。稍后,通过ajax对其进行检索,并填充其值。 问题是,我怎么看待更新的价值?当我从链接方法执行此操作时: 初始化指令时,仅调用一次,然后该值为空。通过ajax(来自)检索值时,不会再次调用此watch函数。但是,在我要显示的页面的其他部分,该值在获取ajax请求时会更新。因此,我认为问题与在ajax请求之后执行无关。 编辑:

  • 问题内容: 简短,简单的介绍了出色的Python 请求模块。 我似乎在文档中找不到变量“代理”应包含的内容。当我发送带有标准“ IP:PORT”值的字典时,它拒绝要求2个值。所以,我猜(因为文档中似乎没有涵盖),第一个值是ip,第二个值是端口? 文档只提到了这一点: 代理–(可选)字典到代理URL的映射协议。 所以我尝试了这个……我该怎么办? 在将它们放入字典之前,我应该将它们转换为某种类型吗?

  • 我对prestashop 1.7中select2中的ajax有问题。当我尝试写一些东西时,调用是200,但我得到错误“控制器Psb2BAjaxModuleAdmin丢失或无效。” 我在模块modules/psb2b/src/Controller/psb2bajaxmoduledmincontroller中创建了用于测试的控制器。php 在admin目录admin*********/themes/d

  • 我正在使用数据消息,正如Firebase文档所建议的,但没有成功...

  • 问题内容: 我尝试了python 请求库文档中提供的示例。 使用,我得到了响应代码,但是我想获得所请求的每个页面的内容。例如,这不起作用: 问题答案: 注意 下面的答案是不适用于请求v0.13.0 +。编写此问题后,异步功能已移至。但是,你可以将其替换为下面的内容,它应该可以工作。 我已经留下了这个答案,以反映原始问题,即有关使用请求的问题。 要异步执行多个任务,你必须: 为每个对象定义一个函数(