gpt4 book ai didi

ios - swift :URLSessionConfiguration

转载 作者:搜寻专家 更新时间:2023-10-31 22:56:33 24 4
gpt4 key购买 nike

我有 FirstViewController,带有要在 SecondTableViewController 中移动的按钮。在 SecondTableViewController 中,我有单元格,如果我点击单元格下载开始。

问题:如果我从 FirstViewController 移入 SecondTableViewController 开始下载并在 FirstViewController 中返回,然后移入 SecondTableViewController 我明白了:

A background URLSession with identifier com.example.DownloadTaskExample.background already exists!

而且我无法下载我的文件。如何解决?

我在 SecondTableViewController 中的代码:

var backgroundSession: URLSession!
var index = 0

override func viewDidLoad() {
super.viewDidLoad()
let sessionConfig = URLSessionConfiguration.background(withIdentifier: "com.example.DownloadTaskExample.background")
backgroundSession = URLSession(configuration: sessionConfig, delegate: self, delegateQueue: OperationQueue())
}

下载文件代码:

let url = URL(string: "link")!
let downloadTaskLocal = ViewController.backgroundSession.downloadTask(with: url)
downloadTaskLocal.resume()

新代码:

class Networking {
static let shared = Networking()
var backgroundSession = URLSession(configuration: URLSessionConfiguration.background(withIdentifier: "com.example.DownloadTaskExample.background"), delegate: URLSession() as? URLSessionDelegate, delegateQueue: OperationQueue())
}

class ViewController: UITableViewController, URLSessionDownloadDelegate {

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

let url = URL(string: "link")!
let downloadTaskLocal = Networking.shared.backgroundSession.downloadTask(with: url)
downloadTaskLocal.resume()
}
}

UPD

class BackgroundSession: NSObject {

static let shared = BackgroundSession()

static let identifier = "com.example.DownloadTaskExample.background"

var session: URLSession!

private override init() {
super.init()

let configuration = URLSessionConfiguration.background(withIdentifier: BackgroundSession.identifier)
session = URLSession(configuration: configuration, delegate: self as? URLSessionDelegate, delegateQueue: OperationQueue())
}


}

class ViewController: UITableViewController, URLSessionDownloadDelegate{

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let url = URL(string: "http:link\(indexPath.row + 1)")!
let downloadTaskLocal = BackgroundSession.shared.session.downloadTask(with: url)
downloadTaskLocal.resume()
}
}

最佳答案

如果你真的在使用后台 session ,你应该确保只实例化它一次。您需要使这个单个 URLSession 实例不仅可用于第二个 View Controller 的多个实例,而且您还需要让您的应用委托(delegate)能够引用它(例如 handleEventsForBackgroundURLSession 必须保存完成处理程序,将被调用但 session 委托(delegate)的 urlSessionDidFinishEvents(forBackgroundURLSession:) )。

一种方法是让应用程序委托(delegate)对其进行实例化,然后将其传递。更简单的是,您可以使用单例模式(如 https://stackoverflow.com/a/44140059/1271826 所示)。

诀窍在于,在将此后台 session 与第二个 View Controller 的任何特定实例解耦时,您希望如何将来自后台 session 的事件通知给第二个 View Controller 。您可能想使用 NotificationCenter .或者你可以给你的后台 session 一些关闭属性,第二个 View Controller 可以设置(并为每个新实例重置)。在不知道第二个 View Controller 在做什么的情况下很难准确地说。

但关键是要确保在应用程序的生命周期内只有一个后台 session 实例。


顺便提一下另外两个问题。考虑:

session = URLSession(configuration: configuration, delegate: self as? URLSessionDelegate, delegateQueue: OperationQueue())
  1. 您从未遵循 URLSessionDelegate(并且您使用 as? 条件类型转换隐藏了这个问题)。删除 as? URLSessionDelegate。显然,还要添加与扩展的一致性:

    extension BackgroundSession: URLSessionDelegate { ... }

    显然,在里面,实现任何URLSessionDelegate您需要的方法(如果有)。

    您可能还想符合 URLSessionTaskDelegateURLSessionDownloadDelegate如果你也想实现这些方法中的任何一个,也可以在它们自己的扩展中使用。

  2. 我们通常希望URLSession 使用串行队列。作为the documentation说:

    The queue should be a serial queue, in order to ensure the correct ordering of callbacks. If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls.

    所以,最简单的方法是将 nil 作为第三个参数传递,然后将为您创建一个串行队列。但是通过传递 OperationQueue(),当您真正需要一个串行队列时,您提供了一个并发队列。

因此该行代码应替换为:

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

关于ios - swift :URLSessionConfiguration,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45785458/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com