Xcode playground - Swift 4 not receiving the JSON data
Clash Royale CLAN TAG#URR8PPP
Xcode playground - Swift 4 not receiving the JSON data
Hi I am working in Xcode playground and trying to use API http-get request using URLSession with the dummy data from jsonplaceholder website.
See code below. The code doesn't return an error but I was expecting data in "usableData" and print it. And the data is :
URL: http://jsonplaceholder.typicode.com/users/1 { Status Code: 200, Headers {n "Access-Control-Allow-Credentials" = (n truen );n "CF-Cache-Status" = (n HITn );n "CF-RAY" = (n "445f3d1003761d3e-MEL"n );n "Cache-Control" = (n "public, max-age=14400"n );n Connection = (n "keep-alive"n );n "Content-Encoding" = (n gzipn );n "Content-Type" = (n "application/json; charset=utf-8"n );n Date = (n "Mon, 06 Aug 2018 05:52:38 GMT"n );n Etag = (n "W/"1fd-+2Y3G3w049iSZtw5t1mzSnunngE""n );n Expires = (n "Mon, 06 Aug 2018 09:52:38 GMT"n );n Pragma = (n "no-cache"n );n Server = (n cloudflaren );n "Transfer-Encoding" = (n Identityn );n Vary = (n "Origin, Accept-Encoding"n );n Via = (n "1.1 ve…"
I was expecting some JSON formated data along the lines of :
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address":
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo":
"lat": "-37.3159",
"lng": "81.1496"
,
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company":
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
At this phase I am only interested in getting the data and not parsing it yet.
What am I doing wrong? Any help is welcome. thank you.
---- START CODE ---------------
import PlaygroundSupport
import Foundation
PlaygroundPage.current.needsIndefiniteExecution = true
let urlString = URL(string:"http://jsonplaceholder.typicode.com/users/1")
if let url = urlString
let task = URLSession.shared.dataTask(with: url) (data, response, error) in
if error != nil
print()
else
if let usableData = data
print(usableData) //JSONSerialization
task.resume()
"509 bytes"
if let usableData
data
correct and I got the 509 bytes. I will try to convert to readable JSON.
– RvE
Aug 6 at 14:19
2 Answers
2
You have to use Foundation class, NSJSONSerialization for converting json data which you get from your api into an object. So you can use line below:
let usableData = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary
print(usableData)
The question is about Swift 4, where we have
Codable
and JSONDecoder
. NSJSONSerialization
should be avoided.– Gereon
Aug 6 at 6:36
Codable
JSONDecoder
NSJSONSerialization
ok, can you give me an example of this in my code? I thought coddle was more to do with parsing once the data is obtained. I am not there yet. @Gereon please give me an example using my code. thx
– RvE
Aug 6 at 8:37
Exactly,
Codable
is for parsing JSON data into actual Swift objects. I've updated my answer with an example.– Gereon
Aug 6 at 9:40
Codable
@RvE How could you accept this answer? It doesn't even compile in Swift 4
– vadian
Aug 6 at 9:46
Your code is fine. If you want to see the JSON data printed as a String, you need to convert the bytes from data
to a String:
data
if let usableData = data
let str = String(bytes: data, encoding: .utf8)
print("(String(describing: str))") // just for debug output
Note that this is not necessary for parsing, you'd do something along the lines of
struct User: Codable
let id: Int
let name, username, email: String
let address: Address
let phone, website: String
let company: Company
struct Address: Codable
let street, suite, city, zipcode: String
let geo: Geo
struct Geo: Codable
let lat, lng: String
struct Company: Codable
let name, catchPhrase, bs: String
if let usableData = data
try
let user = try JSONDecoder().decode(User.self, from: data)
catch
print("(error)"
for that
Please don't suggest tautologic syntax like
print("(String(describing: str))")
. A string from JSON data can never be nil
. print(str!)
is sufficient.– vadian
Aug 6 at 8:05
print("(String(describing: str))")
nil
print(str!)
Well, nothing in the code (nor on the server, as far as I can tell) really ensures there's JSON involved. As such, we don't know anything about what bytes we have in
data
, and therefore the conversion to String may in fact fail, and that's why I'm reluctant to recommend force unwrapping to a beginner.– Gereon
Aug 6 at 9:38
data
Paste
http://jsonplaceholder.typicode.com/users/1
into a browser and have a look. It is json. But I was more concerned about printing a string with string interpolation which was created from a string with the describing
initializer. Besides the OP wrote At this phase I am only interested in getting the data and not parsing it yet– vadian
Aug 6 at 9:42
http://jsonplaceholder.typicode.com/users/1
describing
And Vadian is correct. This gives the result.. if let usableData = data { let str = String(bytes: data!, encoding: .utf8) print("(str!))") // just for debug output
– RvE
Aug 6 at 14:28
Thx all for your help and my trial and erring in my xcode playground. Now the new evolution will be parsing.
– RvE
Aug 6 at 14:30
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
The code should work and print
"509 bytes"
. And optional bindingif let usableData
is redundant. If there is no errordata
can be safely unwrapped.– vadian
Aug 6 at 6:25