URLSessionUploadTask obtenir automatiquement annulée instantanément

Je vais avoir cette étrange question qui vient d'être créée URLSessionUploadTask est annulé instantanément. Je ne suis pas sûr si c'est un bug avec la version bêta actuelle de Xcode 8.

Je le soupçonne peut-être un bug, car le code je suis sur le point de publier fonctionnait bien exactement une fois. Aucune modification n'a été apportée par la suite et puis il a tout simplement cessé de fonctionner. Oui, elle a littéralement couru une fois, puis il a cessé de travailler. Je vais poster l'erreur vers la fin.

Je vais poster le code ci-dessous, mais je vais d'abord résumer la logique ici.

Mon test, l'utilisateur ou exposés API (c'est à dire pour une utilisation dans les cours de récréation ou directement sur apps), appelle la authorize méthode. Cette authorize méthode est à son tour appel buildPOSTTask, qui permettra de construire une URL valide et retourner un URLSessionUploadTask à être utilisé par le authorize méthode.

Avec qui a déclaré, le code est ci-dessous:

La session:

internal let urlSession = URLSession(configuration: .default)

Fonction pour créer une importation de tâche:

internal func buildPOSTTask(onURLSession urlSession: URLSession, appendingPath path: String, withPostParameters postParams: [String : String]?, getParameters getParams: [String : String]?, httpHeaders: [String : String]?, completionHandler completion: URLSessionUploadTaskCompletionHandler) -> URLSessionUploadTask {
    let fullURL: URL
    if let gets = getParams {
        fullURL = buildURL(appendingPath: path, withGetParameters: gets)
    } else {
        fullURL = URL(string: path, relativeTo: baseURL)!
    }

    var request = URLRequest(url: fullURL)
    request.httpMethod = "POST"

    var postParameters: Data? = nil

    if let posts = postParams {
        do {
            postParameters = try JSONSerialization.data(withJSONObject: posts, options: [])
        } catch let error as NSError {
            fatalError("[\(#function) \(#line)]: Could not build POST task: \(error.localizedDescription)")
        }
    }

    let postTask = urlSession.uploadTask(with: request, from: postParameters, completionHandler: completion)
    return postTask
}

La fonction d'authentification, qui utilise une tâche créée par la fonction ci-dessus:

    public func authorize(withCode code: String?, completion: AccessTokenExchangeCompletionHandler) {

//I have removed a lot of irrelevant code here, such as the dictionary building code, to make this snippet shorter.

        let obtainTokenTask = buildPOSTTask(onURLSession: self.urlSession, appendingPath: "auth/access_token", withPostParameters: nil, getParameters: body, httpHeaders: nil) { (data, response, error) in
            if let err = error {
                completion(error: err)
            } else {
                print("Response is \(response)")
                completion(error: nil)
            }
        }

        obtainTokenTask.resume()
    }

J'ai rattrapé cette erreur dans un test:

let testUser = Anilist(grantType: grant, name: "Test Session")

let exp = expectation(withDescription: "Waiting for authorization")

testUser.authorize(withCode: "a valid code") { (error) in
    if let er = error {
        XCTFail("Authentication error: \(er.localizedDescription)")
    }
    exp.fulfill()
}
self.waitForExpectations(withTimeout: 5) { (err) in
    if let error = err {
        XCTFail(error.localizedDescription)
    }
}

Il échoue toujours instantanément avec cette erreur:

Erreur de Domaine=NSURLErrorDomain Code=-999 "annulé" UserInfo={NSErrorFailingURLKey=https://anilist.co/api/auth/access_token?client_secret=REMOVED&grant_type=authorization_code&redirect_uri=genericwebsitethatshouldntexist.bo&client_id=ibanez-hod6w&code=REMOVED,
NSLocalizedDescription=annulé,
NSErrorFailingURLStringKey=https://anilist.co/api/auth/access_token?client_secret=REMOVED&grant_type=authorization_code&redirect_uri=genericwebsitethatshouldntexist.bo&client_id=ibanez-hod6w&code=REMOVED}

Voici quelques choses à garder à l'esprit:

  • L'URL utilisée par la session est valide.
  • Toutes les informations d'identification sont valides.
  • Il échoue instantanément avec un "annulé" erreur, qui n'a tout simplement pas se produire avant. Je ne suis pas annuler la tâche n'importe où, donc, c'est d'être annulées par le système.
  • Il échoue également sur les aires de jeux avec indéterminée exécution activé. Ce n'est pas limité à mes tests.

Voici une liste de choses que j'ai essayé:

  • Parce que j'ai l'impression que c'est un bug, j'ai d'abord essayé de nettoyer mon projet, de supprimer des données dérivées, et de réinitialiser tous les simulateurs. Aucun d'entre eux travaillaient.
  • Est même allé aussi loin de redémarrer mon Mac...
  • Sous le petit soupçon que l'importation de tâche a été d'obtenir libéré à cause d'elle de ne pas en avoir de fortes présomptions, et à son tour l'appel de cancel, j'ai également réécrit authorize de retourner à la tâche créée par buildPOSTTask et affecté à une variable dans mon test. La tâche était encore en train annulé.

Choses que je n'ai pas encore essayer (mais j'accepte toutes les autres idées que je travail à travers ces):

  • L'exécuter sur un périphérique physique. En cours de téléchargement iOS 10 sur un iPad que c'est un iOS du projet 10. EDIT: je viens d'essayer et il n'est pas possible de le faire.

Je suis à court d'idées de ce à essayer. Les journaux générés ne semblent pas avoir toutes les infos utiles.

EDIT:

J'ai décidé de publier la totalité du projet ici. La chose sera open source, de toute façon quand c'est fini, et l'API informations d'identification que je possède sont pour une application de test.

ALCKit

  • Bon, désolé, devinez qui est important, haha. Ouais le test n'ont waitForExpectationsWithTimeout appel. Je vais modifier ma question à rajouter. Je n'ai pas essayé dans une application réelle encore (c'est un cadre que je suis en train de construire, mais une application qui consomme sera construit peu de temps après), mais elle ne parviennent pas rapidement aire de jeux avec indéterminée exécution activé.
  • Pouvez-vous essayer: pastebin.com/B7nZFY1n T-il imprimer la réponse? Donne une erreur?
  • Merci pour vos commentaires Brandon. J'ai couru sur un terrain de jeu et il a bien fonctionné. Imprimé de la réponse comme prévu.
  • Écrire un test pour le code que vous m'avez donné fonctionne très bien. Quelque chose doit se passer entre mes appels de méthode.
  • pastebin.com/ijshDH6Q Semble être le même code que vous utilisez. J'ai pu en déduire sur la base de votre code d'erreur.
  • Je suis juste allé à buildPOSTTask et codés en dur le StackOverflow URL-il. Ainsi, au lieu de var request = URLRequest(url: fullURL), j'ai eu var request = URLRequest(url: URL(string: "http://www.stackoverflow.com")!). Il n'a toujours pas. C'est aussi ne pas trop tôt, il n'a pas vraiment l'impression qu'elle arrive à faire la demande. J'ai juste essayé de le faire dans la cour de récréation, et a également été annulé il.

InformationsquelleAutor Andy Ibanez | 2016-07-15