URLSession.Datatask returns 0 bytes of data
Data will sometimes come back as 0 bytes in the debugger; add a print with debug description to ensure you're getting data. In this case it was a failure of the debugger mixed with a later serialization error that caused it to appear to be broken.
TLDR; don't trust the realtime debugger, use some prints to sanity check.
0 bytes of data from HTTPS URLSession.dataTask
You have a mistake in guard
statement. You wrote ==
instead of !=
in json.count == 0
. It should be like in the code below:
guard json.count != 0 else {
print("Zero bytes of data")
return
}
Tested in the playground with the following code (Removed Encoder):
let baseURL: String = "https://www.burningmeter.com/tournaments.json?page=1"
func retrieveAPIData() {
var request: URLRequest = URLRequest(url: URL(string: baseURL)!)
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpMethod = "GET"
// Request the data
let session: URLSession = URLSession.shared
let task = session.dataTask(with: request) { (data, response, error) in
print(data!.count)
print(response)
// Did we get an error?
guard error == nil else {
print(error!)
return
}
guard let json = data else {
print("No data")
return
}
guard json.count != 0 else {
print("Zero bytes of data")
return
}
print(String(decoding: json, as: UTF8.self))
}
task.resume()
}
retrieveAPIData()
Printed result:
8031
Optional(<NSHTTPURLResponse: 0x7fbce1650fc0> { URL: https://www.burningmeter.com/tournaments.json?page=1 } { Status Code: 200, Headers {
"Access-Control-Allow-Origin" = (
"*"
);
"Cache-Control" = (
"max-age=0, private, must-revalidate"
);
Connection = (
"keep-alive"
);
"Content-Type" = (
"application/json; charset=utf-8"
);
Date = (
"Thu, 08 Nov 2018 15:40:40 GMT"
);
Etag = (
"W/\"5d5a17c8ff6f705d6bb56c6ed8b6a099\""
);
Server = (
Cowboy
);
"Strict-Transport-Security" = (
"max-age=31536000"
);
"Transfer-Encoding" = (
Identity
);
Via = (
"1.1 vegur"
);
"X-Content-Type-Options" = (
nosniff
);
"X-Frame-Options" = (
SAMEORIGIN
);
"X-Request-Id" = (
"0d7f8ae9-92d2-41d8-8678-6c9b2bdb5e3b"
);
"X-Runtime" = (
"0.044064"
);
"X-Xss-Protection" = (
"1; mode=block"
);
} })
JSON result:
{
"page": "1",
"results_per_page": "50",
"tournament_count": 33,
"tournaments": [{
"id": 1872,
"name": "Pinup Biweekly - Nov 1",
"game_id": 90,
"game_iteration_id": 133,
"state": 30,
"starts_at": "2018-11-02T00:00:00.000Z",
"creator_id": 960,
"stream_url": null,
"entrant_count": 6,
"prereg_count": 0,
"path": "/t/1872/pinup-biweekly-nov-1"
}, {
"id": 1874,
"name": "IBTY #45",
"game_id": 21,
"game_iteration_id": 38,
"state": 30,
"starts_at": "2018-11-02T22:03:00.000Z",
"creator_id": 185,
"stream_url": null,
"entrant_count": 11,
"prereg_count": 0,
"path": "/t/1874/ibty-45"
}, {
"id": 1875,
"name": "SFV Weekly 11/2/18",
"game_id": 6,
"game_iteration_id": 14,
"state": 30,
"starts_at": "2018-11-03T00:55:00.000Z",
"creator_id": 957,
"stream_url": null,
"entrant_count": 9,
"prereg_count": 0,
"path": "/t/1875/sfv-weekly-11-2-18"
}, {
"id": 1876,
"name": "Weekly SC6 11/2/18",
"game_id": 106,
"game_iteration_id": 149,
"state": 20,
"starts_at": "2018-11-03T01:04:00.000Z",
"creator_id": 957,
"stream_url": null,
"entrant_count": 6,
"prereg_count": 0,
"path": "/t/1876/weekly-sc6-11-2-18"
}, {
"id": 1879,
"name": "UNIST - WS 11/3",
"game_id": 12,
"game_iteration_id": 23,
"state": 30,
"starts_at": "2018-11-03T18:30:00.000Z",
"creator_id": 949,
"stream_url": null,
"entrant_count": 8,
"prereg_count": 0,
"path": "/t/1879/unist-ws-11-3"
}, {
"id": 1881,
"name": "DBFZ - WS 11/3",
"game_id": 86,
"game_iteration_id": 129,
"state": 30,
"starts_at": "2018-11-03T18:30:00.000Z",
"creator_id": 949,
"stream_url": null,
"entrant_count": 8,
"prereg_count": 0,
"path": "/t/1881/dbfz-ws-11-3"
}, {
"id": 1882,
"name": "SFV - WS 11/3",
"game_id": 6,
"game_iteration_id": 14,
// more
}
// More output here
}
Received length is 8031
URLSession dataTask returns with no error and no data, causing SwiftyStoreKit.ReceiptError error 1
This could possibly depend on the HTTPURLResponse
that you are ignoring in the completion handler of the dataTask
(documentation for URLSession.dataTask
indicates that the response, while of type URLResponse
, is actually of type HTTPURLResponse
- so it would have a statusCode
property that would be helpful to understand the result of your request..
The request may very well have been successful, but with no data returned (ie a 204 No Content response or a 300 Redirect response). These would not have a data response, but would also not have an error response, as the request did not fail.
URLSession returns the size of the data instead of the actual contents of the data
The result of a data task is always a Data
object. It is up to you to work with it however you see fit.
For example, you could convert it into a string and print it to see what the server is sending back.
import UIKit
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let url = URL(string: "http://date.jsontest.com/")!
let session = URLSession.shared
let q = session.dataTask(with: url) { data, response, error in
do {
let string = String(data: data!, encoding: .utf8)!
print("Data as JSON: ")
print(string) // Prints the actual JSON String.
}
catch {
print("Error \(error)")
}
}
q.resume()
Or perhaps more correctly you may want to parse into another object and get its properties:
import UIKit
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
struct JSONTest: Codable {
let date: String
let time: String
}
let url = URL(string: "http://date.jsontest.com/")!
let session = URLSession.shared
let q = session.dataTask(with: url) { data, response, error in
do {
let jsonTest = try JSONDecoder().decode(JSONTest.self, from: data!)
print("Date: \(jsonTest.date)") // Prints the `date` property of your JSON
}
catch {
print("Error \(error)")
}
}
q.resume()
- To shorten the code, this question does not deal with optionals safely. Ensure you safely unwrap optionals if they can be nil.
Related Topics
Swift Compile Error, Subclassing Nsvalue, Using Super.Init(Nonretainedobject:)
Root Class of All Classes in Swift
Compiler Segmentation Fault While Using Set in Swift
Swift: Trunc a Floating Number to Show It in a Label
Swiftui Go Back Programmatically from Representable to View
Why Is This Predicate Format Being Turned into '= Nil'
Cannot Use Mutating Member ... Because Append
Calling Consecutive Animations in Swift with Completion Handler
How to Specify The Name of The Output Executable
How to Implement Applescript Support in a Swift Macos App
Adding Drop Shadow to Table View Cell
How to Change an Inout Parameter from Within a Escaping Closure
Animate UIlabel Width with Fixed Center
Ambiguous Use of Recover Error While Using Promisekit
Http Status 415 When Using Alamofire Multipart Upload