Swift 3 和 NSURLSession 问题
Swift 3 and NSURLSession issue
感谢 Apple,我的 iOS 9 项目 'Swift 2.3' 完全无法用于 iOS 10 的 'Swift 3'...
我修复了几乎所有问题,除了我在使用 NSURLSession
时遇到问题,Xcode 告诉我它已重命名为 URLSession
,如果我将其重命名为 [=32] =] 会告诉我:
use of undeclared type URLSession
基础导入。
这是什么问题?!
比如我就是这样用的...
lazy var defaultSession: URLSession = {
let configuration = URLSessionConfiguration.background(withIdentifier: "reCoded.BGDownload")
configuration.sessionSendsLaunchEvents = true
configuration.isDiscretionary = true
let session = URLSession(configuration: configuration, delegate: self, delegateQueue, queue: nil)
return session
}()
甚至使用委托方法也有同样的问题。
尝试在使用 URLSession
的地方使用 Foundation.URLSession
。
/开始工作/在某些情况下,尝试将代码复制到其他地方,然后删除 class 中使用 URLSession
的所有内容,然后再次键入会话方法并放回复制的代码你应该没事。
我可以解释如何,但经过两天的挫折,我通过尝试代码使它在 SWIFT 3 中工作。我猜SWIFT 3 删除了很多不必要的词。
let task = Foundation.URLSession.shared.dataTask(with: <#T##URL#>, completionHandler: <#T##(Data?, URLResponse?, Error?) -> Void#>)
这是我现在所在的位置。它并不完美,但可能有一半的时间有效。
首先,在定义我的 URLsession 的 class 中:
import Foundation
class Central: NSObject, URLSessionDataDelegate, URLSessionDelegate, URLSessionTaskDelegate, URLSessionDownloadDelegate {
我不认为所有这些都是必要的,但确实如此。然后这是我的后台提取调用的函数:
func getWebData() {
var defaults: UserDefaults = UserDefaults.standard
let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: "myBGconfig")
let backgroundSession = URLSession(configuration: backgroundConfigObject, delegate: self, delegateQueue: nil)
urlString = "https://www.powersmartpricing.org/psp/servlet?type=dayslider"
if let url = URL(string: urlString) {
let rateTask = backgroundSession.downloadTask(with: URL(string: urlString)!)
rateTask.taskDescription = "rate"
rateTask.resume()
}
任务回来时:
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL ) {
if downloadTask.taskDescription == "rate" { // I run 2 web tasks during the session
if let data = NSData(contentsOf: location) {
var return1 = String(data: data as! Data, encoding: String.Encoding.utf8)!
DispatchQueue.global(qos: .userInteractive).asyncAfter(deadline: .now() + 0.2){
var defaults: UserDefaults = UserDefaults.standard
defaults.set(myNumber, forKey: "electricRate") // myNumber is an extract of the text in returned web data
defaults.set(Date(), forKey: "rateUpdate")
defaults.synchronize()
self.calcSetting() //Calls another function defined in the same class. That function sends the user a notification.
let notificationName = Notification.Name("GotWebData")
NotificationCenter.default.post(name: notificationName, object: nil)
} // Closes the Dispatch
}
if session.configuration.identifier == "myBGconfig" {
print("about to invalidate the session")
session.invalidateAndCancel()
}
}
我还没有想出如何在两个任务都完成时终止会话,所以现在我在其中一个完成时终止它,如上所述使用 invalidateAndCancel。
最后,捕捉错误:
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didCompleteWithError: Error?) {
if downloadTask.taskDescription == "rate" {
print("rate download failed with error \(didCompleteWithError)")
}
if downloadTask.taskDescription == "other" {
print("other download failed with error \(didCompleteWithError)")
}
downloadTask.resume() // I'm hoping this retries if a task fails?
}
func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) {
if let error = error as? NSError {
print("invalidate, error %@ / %d", error.domain, error.code)
} else {
print("invalidate, no error")
}
}
更新您的 URLSessin 函数;
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
self.data.append(data as Data)
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if error != nil {
print("Failed to download data")
}else {
print("Data downloaded")
self.parseJSON()
}
}
感谢 Apple,我的 iOS 9 项目 'Swift 2.3' 完全无法用于 iOS 10 的 'Swift 3'...
我修复了几乎所有问题,除了我在使用 NSURLSession
时遇到问题,Xcode 告诉我它已重命名为 URLSession
,如果我将其重命名为 [=32] =] 会告诉我:
use of undeclared type
URLSession
基础导入。
这是什么问题?!
比如我就是这样用的...
lazy var defaultSession: URLSession = {
let configuration = URLSessionConfiguration.background(withIdentifier: "reCoded.BGDownload")
configuration.sessionSendsLaunchEvents = true
configuration.isDiscretionary = true
let session = URLSession(configuration: configuration, delegate: self, delegateQueue, queue: nil)
return session
}()
甚至使用委托方法也有同样的问题。
尝试在使用 URLSession
的地方使用 Foundation.URLSession
。
/开始工作/在某些情况下,尝试将代码复制到其他地方,然后删除 class 中使用 URLSession
的所有内容,然后再次键入会话方法并放回复制的代码你应该没事。
我可以解释如何,但经过两天的挫折,我通过尝试代码使它在 SWIFT 3 中工作。我猜SWIFT 3 删除了很多不必要的词。
let task = Foundation.URLSession.shared.dataTask(with: <#T##URL#>, completionHandler: <#T##(Data?, URLResponse?, Error?) -> Void#>)
这是我现在所在的位置。它并不完美,但可能有一半的时间有效。
首先,在定义我的 URLsession 的 class 中:
import Foundation
class Central: NSObject, URLSessionDataDelegate, URLSessionDelegate, URLSessionTaskDelegate, URLSessionDownloadDelegate {
我不认为所有这些都是必要的,但确实如此。然后这是我的后台提取调用的函数:
func getWebData() {
var defaults: UserDefaults = UserDefaults.standard
let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: "myBGconfig")
let backgroundSession = URLSession(configuration: backgroundConfigObject, delegate: self, delegateQueue: nil)
urlString = "https://www.powersmartpricing.org/psp/servlet?type=dayslider"
if let url = URL(string: urlString) {
let rateTask = backgroundSession.downloadTask(with: URL(string: urlString)!)
rateTask.taskDescription = "rate"
rateTask.resume()
}
任务回来时:
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL ) {
if downloadTask.taskDescription == "rate" { // I run 2 web tasks during the session
if let data = NSData(contentsOf: location) {
var return1 = String(data: data as! Data, encoding: String.Encoding.utf8)!
DispatchQueue.global(qos: .userInteractive).asyncAfter(deadline: .now() + 0.2){
var defaults: UserDefaults = UserDefaults.standard
defaults.set(myNumber, forKey: "electricRate") // myNumber is an extract of the text in returned web data
defaults.set(Date(), forKey: "rateUpdate")
defaults.synchronize()
self.calcSetting() //Calls another function defined in the same class. That function sends the user a notification.
let notificationName = Notification.Name("GotWebData")
NotificationCenter.default.post(name: notificationName, object: nil)
} // Closes the Dispatch
}
if session.configuration.identifier == "myBGconfig" {
print("about to invalidate the session")
session.invalidateAndCancel()
}
}
我还没有想出如何在两个任务都完成时终止会话,所以现在我在其中一个完成时终止它,如上所述使用 invalidateAndCancel。
最后,捕捉错误:
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didCompleteWithError: Error?) {
if downloadTask.taskDescription == "rate" {
print("rate download failed with error \(didCompleteWithError)")
}
if downloadTask.taskDescription == "other" {
print("other download failed with error \(didCompleteWithError)")
}
downloadTask.resume() // I'm hoping this retries if a task fails?
}
func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) {
if let error = error as? NSError {
print("invalidate, error %@ / %d", error.domain, error.code)
} else {
print("invalidate, no error")
}
}
更新您的 URLSessin 函数;
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
self.data.append(data as Data)
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if error != nil {
print("Failed to download data")
}else {
print("Data downloaded")
self.parseJSON()
}
}