Xcode playground - Swift 4 not receiving the JSON data

The name of the pictureThe name of the pictureThe name of the pictureClash 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()





The code should work and print "509 bytes". And optional binding if let usableData is redundant. If there is no error data can be safely unwrapped.
– vadian
Aug 6 at 6:25



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

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard