0

J'utilise le mode de délégation NSURLSession pour obtenir une requête http get pour obtenir des données json d'un serveur. Je finis par passer dans le NSData reçu dans mon NSURLSessionDataDelegate à un modèle objet de mettre à jour un tableau comme ceci:nsjsonserialization.jsonobjectwithdata tronquer les données reçues

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) { 
    networkDelegate?.updateGameList(data) 
    dataTask.resume() 
} 

Une fois les données fait son chemin dans la fonction updateGameList, des trucs bizarres qui se passe si j'essaie d'utiliser NSJSONSerialization. JSONObjectWithData. Si je ne cherche pas à utiliser NSJSONSerialization et simplement convertir le NSData à une chaîne, il semble que la bonne réponse, je me attends, quelque chose comme ceci:

Optional([{"id":"a19610e4-675e-40b3-8335-085b61bfb0e3","name":"tttt","status":"PLAYING"}, 
{"id":"3be2e411-0086-46fd-8fc9-38d11831d0fb","name":"LWP TEST","status":"PLAYING"}, 
{"id":"b5d97d73-1ce2-4e5b-8b38-805835e2a21d","name":"asd","status":"PLAYING"}, 
{"id":"8a15575c-4c2c-4b46-ad5b-51b4b2680416","name":"MsGame","status":"WAITING"}, 
{"id":"b54531b8-5323-4630-929c-6eb2cfebde63","name":"423","status":"PLAYING"}, 
{"id":"5a7cfaa0-e2a4-41f6-bda2-a854a2d00a57","name":"4234","status":"PLAYING"}]) 

Cependant, une fois que j'essaie d'utiliser le NSData avec NSJSONSerialization.JSONObjectWithData faire un NSArray, il commence à lancer des erreurs parce que les données semble être tronquée soit au début ou à la fin, comme ceci:

Optional([{"id":"a19610e4-675e-40b3-8335-085b61bfb0e3","name":"tttt","status":"PLAYING"},{"id":"3be2e411-0086-46fd-8fc9-38d11831d0fb","name":"LWP TEST","status":"PLAYING"},  
{"id":"6d4e9731-61be-4191-bb9a-a30b6395a4a2","name":"RANDOMBOT","status":"PLAYING"},{"id":"c31b363c-f565-4f4a-a6f1-1ac219425f40","name":"Testament ","status":"PLAYING"}, 
{"id":"af14d8bc-37a0-4ec3-88de-ee364344d720","name":"Testament ","status":"PLAYING"}, 
{"id":"29439dd9-357d-445b-856c-39862e19c2fc","name":"Testament ","status":"PLAYING"},{"id":"cc29046f-4e80-422d-a103-5be175e799c9","name":"matt7","status":"PLAYING"}, 
{"id":"ff75c546-0e9b-4560-8efb-d0fa5be61cde","name":"u","status":"DONE"},{"id":"3d88df55-6f84-469c-a18e-27e463dc30eb","name":"test","status":"PLAYING"},{"id":"40eb1b13-21c3-4c8d-a379-e6b85329374b","name":"test","status":"PLAYING"}, 
{"id":"4e7519dd-79d3-4229-8d0e-47ca112dc08f","name":"test","status":"PLAYING"},{"id":"32ce49cc-17aa-47ca-8b9f-1c35dbdb78e6","name":"test","status":"PLAYING"}, 
{"id":"f5d5c961-17eb-421d-86b1-fbbadfb795da","name":"test","status":"PLAYING") 

update game list error Error Domain=NSCocoaErrorDomain Code=3840 
"Unexpected end of file while parsing object." 
UserInfo={NSDebugDescription=Unexpected end of file while parsing object.} 

est ici la fonction updateGameList, quand je commente le do prises accessoires bloquer avec le code JSONSerialization dedans, le dataString imprime la réponse correcte, quand je le décomment, il court multip le temps, presque comme si on essayait de traiter les données un morceau à la fois au lieu de tout à la fois. Si je supprime l'option .AllowFragments, il me dit de le mettre, quand je l'ai mis, il arrive à l'erreur réelle des données json ne démarre pas ou se termine pas correctement.

func updateGameList(gameListData:NSData) { 
    let dataString = NSString(data: gameListData, encoding: NSUTF8StringEncoding) 
    print(dataString) 

    do { 
     let gameList:NSArray = try NSJSONSerialization.JSONObjectWithData(gameListData, options: [.AllowFragments]) as! NSArray 
    } 
    catch { 
     print("update game list error \(error)") 
    } 

} 
+0

Je viens de réaliser qu'il est littéralement en train de couper le NSData en morceaux à une certaine limite de caractères. Ainsi, les premières données imprimées sont le début et se terminent incorrectement, puis les secondes données imprimées continuent à partir de là et commencent incorrectement. Donc, il essaie de le traiter en morceaux, mais je ne sais pas pourquoi. – uRockNinja

+0

S'il vous plaît ne pas poster de contenu ou de code dans les commentaires. Utilisez le bouton [Modifier] pour modifier votre question à la place. Je vous remercie! :) – Moritz

Répondre

1

Je cite la documentation:

Cette méthode déléguée peut être appelée plus d'une fois, et chaque appel fournit uniquement des données reçues depuis l'appel précédent. L'application est responsable de l'accumulation de ces données si nécessaire.

Alors, que vous observez est une caractéristique: les données sont reçues en morceaux (très probablement parce que le serveur d'origine utilise Transfer-Encoding: chunked), et donc vous ne pouvez pas attendre de pouvoir analyser individuellement chaque morceau - vous aurez avoir à accumuler tous les morceaux à partir d'une réponse, que vous pouvez ensuite essayer d'analyser.