2017-04-19 4 views
0

J'ai un appel à une fermeture dans une tâche URLSession.shared.dataTask. Le truc c'est que quand je mets un point d'arrêt à l'intérieur de ma fermeture, il ne terminera pas l'exécution.fermeture à l'intérieur du gestionnaire d'achèvement de URLSession.shared.dataTask

func query(url: String, args: [String:String], completion: @escaping (_ data: Data) -> Void) { 
// Create request url in order to query API. 
let url = makeGetRequestUsing(url: url, args: args) 
let task = URLSession.shared.dataTask(with: url!) { data, response, error in 
    guard let data = data, error == nil else { 
     print("error:", error ?? "") 
     return 
    } 
    completion(data) 
} 

task.resume() 

Et voici comment je l'appelle.

self.comments = [] 
api.query(url: url, args: args) { data in 
    let jsonData = try! JSONSerialization.jsonObject(with: data) 
    print(String(data: data, encoding: .utf8)) 
    if let jsonArray = jsonData as? [[String: Any]] { 
     // Create comments from the json received. 
     for i in 0..<jsonArray.count { 
      do { 
       self.comments.append(try Comment(json: jsonArray[i])) 
      } catch { 
       print(error) 
      } 
     } 
     DispatchQueue.main.async { 
      self.refreshComments() 
     } 
    } 
} 

J'ai mis un point de rupture dans le gestionnaire d'achèvement, et il semble que l'erreur vient de la classe init Commentaire.

init(json: [String: Any]) throws { 
// Get the comment text. 
guard let comment = json[Comment.commentText] as? String else { 
    throw SerializationError.missing(Comment.commentText) 
} 

// Get userImage. 
guard let userId = json[Comment.userId] as? Int, 
    let userImage = APIData.shared.getImage(url: "/userImageForId", args: ["id": String(userId)]) else { 
    throw SerializationError.missing(Comment.userId) 
} 

// Get userename. 
guard let resp = APIData.shared.getQuery(url: "/userNameForId", args: ["id": String(userId)]) as? [String: String], 
    let username = resp[Comment.username] else { 
    throw SerializationError.missing(Comment.username) 
} 

self.comment = comment 
self.username = username 
self.userImage = userImage 

}

Le getImage et getQuery sont les mêmes que le premier code. Je lance une tâche et j'attends jusqu'à ce que j'obtienne le résultat en utilisant un sémaphore.

+0

Vous n'appelez pas task.resume() n'importe où –

+0

Je le fais après le code ci-dessus. Je pensais qu'il n'était pas nécessaire de l'inclure ici. – user2232305

+1

jsonData est un nom très trompeur pour un dictionnaire ou un tableau –

Répondre

0

Vous dites que votre fermeture ne terminera pas l'exécution et vous avez également mentionné que vous utilisez un sémaphore quelque part dans le code que vous n'avez pas posté. Il est fort probable que vous n'utilisiez pas correctement le sémaphore et que cela bloque votre thread.

Il n'y a rien dans le problème que je puisse voir qui justifie l'utilisation d'un sémaphore en premier lieu. En introduisant des sémaphores et des exceptions, vous semblez rendre le code beaucoup plus complexe que nécessaire.

Je vous suggère de lire sur la façon d'unité de code de test et de construire votre logique un peu à la fois. On dirait que vous mordez plus que vous ne pouvez mâcher en ce moment.