2016-06-14 15 views
8

Dank an Apple mein iOS 9 Projekt ‚Swift 2.3‘ ist völlig unbrauchbar mit iOS 10 des ‚Swift 3‘ ...Swift 3 und NSURLSession Ausgabe

ich außer fast alles festgelegt, dass ich Problem habe mit NSURLSession verwenden, Xcode sagt mir, dass es zu URLSession umbenannt wurde, wenn ich es umbenennen Xcode wird mir sagen:

Verwendung von Schwarz Typ URLSession

Foundation importiert wird.

Was ist das Problem ?! Ich kann es auf diese Weise

Zum Beispiel bin mit ...

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 
}() 

und sogar mit den Delegatmethoden das gleiche Problem.

+0

@EricD Ich habe die Beschreibung aktualisiert, wenn Sie es bitte sehen können. – Raffi

+1

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

+0

@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

Antwort

2

/In einigen Fällen versuchen Sie, Ihren Code woanders zu kopieren, dann entfernen Sie alles in Ihrer Klasse, die URLSession verwendet, geben Sie dann die Session-Methoden erneut und setzen Sie Ihren kopierten Code zurück, sollten Sie in Ordnung sein.

+0

Es funktionierte für mich auf diese Weise. Es scheint, die Compiler Verwirrung irgendwie zu entfernen @Droppy – Raffi

+0

Jede Chance, die Sie Ihre komplette endgültige Lösung teilen können? Ich bemühe mich, meine Hintergrund-URLSession zuverlässig auszuführen. Die Dokumentation ist verwirrend, und vieles davon ist alt und nicht für Swift 3. –

+0

Zeig mir deinen Code, der dich beunruhigt und dann werde ich versuchen zu helfen – Raffi

6

Verwenden Sie Foundation.URLSession wo immer Sie URLSession verwenden.

+2

könnten Sie bitte erklären warum? –

0

Ich kann erklären, wie, aber indem ich mit dem Code herumspielte, bekam ich das in SWIFT 3 nach zwei Tagen der Frustration arbeiten. Ich schätze, SWIFT 3 hat viele unnötige Wörter entfernt.

let task = Foundation.URLSession.shared.dataTask(with: <#T##URL#>, completionHandler: <#T##(Data?, URLResponse?, Error?) -> Void#>) 
0

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") 
    } 
} 
+0

Ich kann sehen, warum Ihre Aufgabe nicht immer funktioniert, wenn Sie eine Hintergrundsitzung erstellen, legen Sie die Eigenschaft isDiscretionary auf false und Ihre Aufgabe wird immer sofort funktionieren. Lesen Sie hier [isDiscretionary reference] (https://developer.apple.com/reference/foundation/urlsessionconfiguration/1411552-isdiscretionary) und zum Abbrechen von Sitzungen lesen Sie hier die Antwort [Cancelling NSURLSession] (http://stackoverflow.com/questions/21414823/How-do-wissen-wann-das-nsurlsession-Objekt-wurde-durch-ios-invalidiert worden – Raffi

+0

Diese Referenz besagt, dass der Standardwert von isDiscretionary falsch ist. Ich werde es trotzdem versuchen, aber es sollte egal sein. Um eine Sitzung abzusagen, bin ich nah dran. Ich benutze eine Flagge, aber es gab ein Timing-Problem, weil meine Flagge während eines Versands gesetzt wurde. Die Entwertungsentscheidung wird zu schnell getroffen, bevor das Task-Flag auf "Fertig" gesetzt wird. Arbeiten daran. –

+0

Probieren Sie es aus und sagen Sie mir, was passiert. Aus irgendeinem Grund funktioniert es für mich so. – Raffi

1

Aktualisieren Sie Ihre URLSessin Funktionen mit;

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() 
    } 
}