0

我正在使用NSURLSession委託方式使http獲取請求從服務器獲取json數據。我結束了傳入的NSData收到我的NSURLSessionDataDelegate的模型對象以更新數組,像這樣:nsjsonserialization.jsonobjectwithdata截斷接收到的數據

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

一旦數據使得它的方式進入updateGameList功能,奇怪的事情發生,如果我嘗試使用NSJSONSerialization。 JSONObjectWithData。如果我不嘗試使用NSJSONSerialization,並且僅僅NSData的轉換爲字符串,它看起來像我期待適當的反應,這樣的事情:

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"}]) 

但是,一旦我嘗試使用NSData的用NSJSONSerialization.JSONObjectWithData做一個NSArray,它開始拋出錯誤,因爲數據似乎被截斷或者在開頭或結尾,就像這樣:

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.} 

這裏是updateGameList功能,當我註釋掉DO-抓阻塞其中的JSONSerialization代碼,dataString打印出正確的響應,當我取消註釋時,它運行multip這幾乎就像它試圖一次處理大塊數據,而不是一次處理所有數據。如果我將.AllowFragments選項取出,它告訴我放入它,當我放入它時,它會得到json數據的真正錯誤,無法正確啓動或結束。

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

我剛剛意識到它的字面意思是在某些字符限制下將NSData切成小塊。因此,打印出的第一個數據是開始和結束不正確的,然後打印出來的第二個數據繼續從那裏開始並且不正確地開始。所以它試圖以大塊的方式處理它,但我不知道爲什麼。 – uRockNinja

+0

請不要在評論中發佈內容或代碼。改爲使用[編輯]按鈕編輯您的問題。謝謝! :) – Moritz

回答

1

從文檔引用:

此委託方法可以被稱爲一次以上,並且每個呼叫 僅提供自上次呼叫接收的數據。該應用程序是 負責積累這些數據,如果需要的話。

那麼您看到的是一個功能:數據塊中收到的(很可能是因爲原始服務器使用Transfer-Encoding: chunked),因此,你不能指望能夠單獨分析每個數據塊 - 你會必須從一個響應中累積所有塊,然後可以嘗試解析。