Hier ist, wo ich gerade bin. Es ist nicht perfekt, aber funktioniert vielleicht die Hälfte der Zeit.
Zuerst in der Klasse, wo meine URLsession definiert:
import Foundation
class Central: NSObject, URLSessionDataDelegate, URLSessionDelegate, URLSessionTaskDelegate, URLSessionDownloadDelegate {
Ich glaube nicht, all das notwendig ist, aber es gibt sie. Dann ist hier die Funktion, die durch meinen Hintergrund holen genannt wird:
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()
}
Wenn die Aufgabe kommt zurück:
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()
}
}
Ich habe noch nicht herausgefunden, wie die Sitzung zu töten, wenn beide Aufgaben abgeschlossen haben Jetzt bringe ich es um, wenn eines der beiden vollständig ist, mit invalidateAndCancel wie oben.
Und schließlich zu fangen Fehler:
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")
}
}
@EricD Ich habe die Beschreibung aktualisiert, wenn Sie es bitte sehen können. – Raffi
Kein Problem mit URLSession in Ihrem Code für mich. Scheint lächerlich, ich weiß, aber ... bist du sicher, dass du Xcode 8 benutzt? :) Wenn ja, könnte es irgendwo eine widersprüchliche Erklärung geben ... – Moritz
@EricD Ja, da bin ich mir sicher! Ich werde es noch einmal überprüfen und sehen, was passiert. Wird aktualisiert, wenn ich etwas gefunden habe. Danke Kumpel. – Raffi