【问题标题】:A background URLSession with identifier backgroundSession already exists具有标识符 backgroundSession 的后台 URLSession 已存在
【发布时间】:2016-03-22 11:40:04
【问题描述】:

我正在使用 NSURLSession 和 NSURLSessionDelegate 从服务器获取 xml 数据。取决于我与服务器连接的某些条件。如果我与服务器连接一切正常,没有任何错误,但如果我没有连接(取决于条件)到服务器并移动到另一个视图控制器(通过使用故事板?.instantiateViewControllerWithIdentifier(id))我得到以下IOS错误:

'标识符为 backgroundSession 的后台 URLSession 已经存在!'

这是我的代码:

class MainClass: UITableViewController, NSURLSessionDelegate {     

   var task_service = NSURLSessionDataTask?()

   override func viewDidLoad() {
      super.viewDidLoad()

      if(condition) {
        getXMLFromServer()
      }

   }

   func getXMLFromServer(){

     task_service = getURLSession().dataTaskWithRequest() {

        (data, response, error) -> Void in

        dispatch_async(dispatch_get_main_queue(), {

         // Fetching data from server 

         // In the end
         self.session.invalidateAndCancel()
       }
    }

  }

 func getURLSession() -> NSURLSession {

    let configuration =      NSURLSessionConfiguration.defaultSessionConfiguration()

    configuration.timeoutIntervalForRequest = 30.0

    session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: NSOperationQueue.mainQueue())

    return session
  }

 func URLSession(session: NSURLSession, task: NSURLSessionTask, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {

    completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)) // Bypassing SSL error
 }   
}

编辑:找到错误原因。

由于在被调用视图控制器中创建 NSURLSession 而发生错误。被调用 VC 包含从服务器下载 PDF 的代码。但我不知道如何解决这个问题。下面是Called VC的代码

class MainFormsController: UIViewController, UIPickerViewDelegate, UITextFieldDelegate, NSURLSessionDownloadDelegate, UIDocumentInteractionControllerDelegate, MFMailComposeViewControllerDelegate{

 var download_task = NSURLSessionDownloadTask?()
 var backgroundSession = NSURLSession()

 override func viewDidLoad() {
    super.viewDidLoad()

     createNSURLSession()
 }               

 /** Error occurred while creating this NSURLSession **/

    func createNSURLSession() { 

        let backgroundSessionConfiguration =  NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("backgroundSession")

       backgroundSession = NSURLSession(configuration:   backgroundSessionConfiguration, delegate: self, delegateQueue:   NSOperationQueue.mainQueue())
    }

  func downloadPDF() {

     //Download PDF
     download_task = backgroundSession.downloadTaskWithURL(url)
     download_task?.resume()
  }

}

【问题讨论】:

标签: ios swift


【解决方案1】:

在您的 MainFormsController 中添加此代码:

deinit {
        self.backgroundSession.finishTasksAndInvalidate();
    }

【讨论】:

    【解决方案2】:

    您的代码可能不止一次调用 createNSURLSession(),这会使 NSURLSession 行为无效,如文档所述:

    "您必须为每个标识符创建一个会话(指定时 您创建配置对象)。多人的行为 共享相同标识符的会话未定义。”

    https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/UsingNSURLSession.html

    确保在应用的生命周期内只调用一次 createNSURLSession(单调)。

    【讨论】:

    • 这对我有用,谢谢。我有被暂停和恢复的 URLSessions。每次需要恢复下载时,我都在重新创建会话。解决方案是存储会话,然后创建一个新任务。
    • @LukeVanIn 能否提供代码示例供参考?
    【解决方案3】:

    我想你已经有了一个标识符为 backgroundSession 的 URLSession。第一次通话

    - (void)invalidateAndCancel
    

    关于那个。然后尝试使用您的代码。

    【讨论】:

    • 感谢您的回复。我试过这个,但没有运气。我已经编辑了我的问题。
    • 假设您正在从 A 视图控制器移动到 B 视图控制器。现在可能您正在从当前视图控制器(即 B)调用 invalidateAndCancel 表单,并且会话是在第一个视图控制器(即 A)中创建的。由于 B 视图控制器不会拥有该会话的所有权,因此它不能调用该会话的 invalidateAndCancel 方法.请检查。谢谢。
    • 我在 VC A 中创建了会话并从同一个 VC 连接服务器。在获取数据的最后,我写了“self.session.invalidateAndCancel()”。毕竟,当我调用 VC B(单击按钮)时,没有任何问题,但是如果我没有连接到服务器并且当我调用 VC B 时,我得到了那个错误。希望你能理解。
    • 你可以尝试在 getURLSession 方法中使用'(backgroundSessionConfigurationWithIdentifier(_: )'为配置对象提供一些唯一标识符
    猜你喜欢
    • 2019-05-14
    • 2014-07-15
    • 2020-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-02
    相关资源
    最近更新 更多