- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有 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())
您从未遵循 URLSessionDelegate
(并且您使用 as?
条件类型转换隐藏了这个问题)。删除 as? URLSessionDelegate
。显然,还要添加与扩展的一致性:
extension BackgroundSession: URLSessionDelegate { ... }
显然,在里面,实现任何URLSessionDelegate
您需要的方法(如果有)。
您可能还想符合 URLSessionTaskDelegate
和 URLSessionDownloadDelegate
如果你也想实现这些方法中的任何一个,也可以在它们自己的扩展中使用。
我们通常希望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/
我有 FirstViewController,带有要在 SecondTableViewController 中移动的按钮。在 SecondTableViewController 中,我有单元格,如果我
我已经使用默认配置定义了 session 配置,并提供了 tlsMinimumSupportedProtocol 作为 TLSv1.2 我正在使用 Alamofire,但我的应用程序仍然支持较低版本
我得到一个 Error Domain=NSURLErrorDomain Code=-997 "Lost connection to background transfer service" 当我在启动
给定以下 Playground : import Foundation let config = URLSessionConfiguration.default let session = URLSe
从 iOS 11 开始我们可以设置: let sessionConfiguration = URLSessionConfiguration.default sessionConfiguration.m
请注意,我已经尝试了很多解决方案,例如 this但都没有用。 这里是 screenshot和代码; func downloadItems() { let urlE: String = "htt
在我的 iOS 应用程序中,我使用默认配置创建一个 URLSession: // Part #1 let urlSession = URLSession(configuration: .defa
我是一名优秀的程序员,十分优秀!