I get escape characters from jsonSerialization and cannot decode them in Swift - json

I have a project in swift where I post a URL and get the result in json.
The json reply from the url contains many greek letters and for example instead of "Γ" I get "\U0393".
How I can translate the escape characters in swift?
My code is the following:
let url = NSURL(string: "https://www.something.that.creates.a.json.array")!
let task = URLSession.shared.dataTask(with: url as URL) { (data, response, error) -> Void in
if let urlContent = data {
do {
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers)
print(jsonResult)
} catch {
print("Json Serialization error")
}
}
}
task.resume()

The escape characters where indeed appearing correct as rmaddy wrote.
But I had to cast the result as [[String : Any]] in order to access the Dictionary inside the array correctly.
let url = NSURL(string: "https://www.something.that.creates.a.json.array")!
let task = URLSession.shared.dataTask(with: url as URL) { (data, response, error) -> Void in
if let urlContent = data {
do {
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as! [[String : Any]]
print(jsonResult[0]["description"])
} catch {
print("Json Serialization error")
}
}
}
task.resume()

Related

How to extract value from JSON object with dictionary [Swift 4]

I'm trying to make an async API get request to openweathermap.org 's API. The result should be this JSON structure. I'm particularly trying to get the temperature. I was taught to work with it by wrapping the JSON to a dictionary. Thing is I don't know what I can use to specify the object "main" (in the JSON) and get the temperature. Do I have to iterate object by object? This is my code so far (side note: is it worrying that my app uses 50 mb of RAM?)
let url = URL(string: stringURL)
let myQ = DispatchQueue.init(label: "getCityDetails")
myQ.async {
let session = URLSession.shared
let m = session.dataTask(with: url!, completionHandler: {(data, response, error) in
if let error = error {
print(error.localizedDescription)
return
}
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
print("Error with the response, unexpected status code: \(String(describing: response))")
return
}
do {
if let d = data{
let dictionaryObj = try JSONSerialization.jsonObject(with: d, options: []) as! NSDictionary
print(dictionaryObj)
}
}catch{
print(error.localizedDescription)
}
})
m.resume()
The first point is that the default URLSession works in a background thread so you dont need to create a dispatch queue (alos you are not using it correctly). The second point tries to use optional data not to use try/catch. Finally you could try to use Swift 5 together to the protocol Codable to have better code, simple and secure.
let url = URL(string: "https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=439d4b804bc8187953eb36d2a8c26a02")!
URLSession.shared.dataTask(with: url, completionHandler: {(data, response, error) in
if let error = error {
print(error.localizedDescription)
return
}
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
print("Error with the response, unexpected status code: \(String(describing: response))")
return
}
guard let data = data else {
return
}
guard let dictionaryObj = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
return
}
if let main = dictionaryObj["main"] as? [String: Any], let temperature = main["temp"] {
DispatchQueue.main.async {
print("Temperature: \(temperature)")
}
}
}).resume()

how to get data from object type in jsonserialization in swift 5

Want to get this data with json serialization {"id":1,"name":"harry"}
I have tried this method but getting error(Method not allowed) let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
let task = URLSession.shared.dataTask(with: request) {(data, response, error) in
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
print(json)
}
task.resume()
result should be something like this : {"id":1,"name":"harry"}
Instead of using JSONSerialization, try using Codable to parse the JSON response using the below model.
Model:
struct Response: Decodable {
let id: Int
let name: String
}
Parsing:
let task = URLSession.shared.dataTask(with: request) {(data, response, error) in
if let data = data {
do {
let response = try JSONDecoder().decode(Response.self, from: data)
print(response)
} catch {
print(error)
}
}
}
task.resume()
Now, you can use the response object to access the id and name properties.

Load data from server using swift 4

I try to load the user profile like below
#IBAction func Btn_LoadDataFromDataBase(_ sender: UIButton) {
let myurl = "site.com/profile.php"
LoadURL(url: myurl)
}
func LoadURL(url: String) {
do{
let appURL = URL(string: url)! // convert string to URL
let data = try Data(contentsOf: appURL)
//error here on this line below :
let json1 = try JSONSerialization.jsonObject(with: data ) as! [String: Any]
print(json1)
let query1 = json1["profile"] as! [String: Any]
print(query1)
label_email.text = "Email : (query1["email"]!)"
}catch{
print("error in url")
}
}
if I test the json via webbrowser I get it like this:
{profile : [{"0":"999","id":"999","1":"1","email":"blabla#gmail.com","2":"1111","tel":"00122222222","3":"0" ..........
php code:
print "{profile : ".json_encode($user_profile,JSON_UNESCAPED_UNICODE)."}";
mysql_close($db);
?>
Please read the JSON carefully, there are only two different collection types
{} is dictionary ([String: Any])
[] is array ([Any] but in most cases [[String: Any]])
so the result for query1 (I changed the variable names to something more descriptive) is an array and you need a loop to print all elements:
let profileData = try JSONSerialization.jsonObject(with: data ) as! [String: Any]
let profiles = profileData["profile"] as! [[String: Any]] // could be even [[String:String]]
for profile in profiles {
print("Email :", profile["email"]!")
}
I'm wondering why so many owners of web services send the PHP arrays unnecessarily with both index and key.
And never load data from a remote URL synchronously, use asynchronous URLSession
You're better using URLRequest for async requests. You will need to pass your appURL as a parameter in a URLRequest and handle the answer in its completion handler.
An example:
let urlString = "https://swift.mrgott.pro/blog.json"
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!.localizedDescription)
}
guard let data = data else { return }
// Implement JSON decoding and parsing
do {
let articlesData = try JSONDecoder().decode([OBJECT YOU WANT].self, from: data)
} catch let jsonError {
print(jsonError)
}
}.resume()

Getting API Data within Swift

I'm trying to get some data from an API at the address https://api.coinmarketcap.com/v1/ticker/bitcoin/?convert=AUD
I've started a new playground within Xcode, and my code is as follows
let urlString = "https://api.coinmarketcap.com/v1/ticker/bitcoin/?convert=AUD"
let url = URL(string: urlString)
URLSession.shared.dataTask(with:url!) { (data, response, error) in
if error != nil {
print(error as Any)
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!) as! [String:Any]
let id = parsedData["id"] as! [String:Any]
print(id)
} catch let error as NSError {
print(error)
}
}
}.resume()
However the playground is returning no result. I am quite new to Swift, so some of the syntax may be a little off. Can anyone make a suggestion how to obtain the information obtained at the API address?
Thanks!
You need to import PlaygroundSupport and set needsIndefiniteExecution to true.
Also you have some errors in the code as the result is array and you are casting it into a dictionary [String : Any].
Use the following code:
import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let urlString = "https://api.coinmarketcap.com/v1/ticker/bitcoin/?convert=AUD"
let url = URL(string: urlString)
URLSession.shared.dataTask(with:url!) { (data, response, error) in
if error != nil {
print(error!.localizedDescription)
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!) as! [[String : Any]]
for item in parsedData
{
let id = item["id"] as! String
print(id)
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
}.resume()

Swift 3 Rest API not working

Having trouble with Rest API in Swift 3. Here's my code:
func getData()
{
let urlString = "http://dataservice.accuweather.com/locations/v1/regions?apikey=QVU3TATgJEdRyojFze6zivdrmiln9XlA"
let config = URLSessionConfiguration.default // Session Configuration
let session = URLSession(configuration: config) // Load configuration into Session
let url = URL(string: urlString)!
let task = session.dataTask(with: url, completionHandler: {
(data, response, error) in
if error != nil {
print(error!.localizedDescription)
} else {
do {
print("in do block")
if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]
{
print("if condition is true")
//Implement your logic
print(json)
} else
{
print("Error in json serial")
}
} catch {
print("error in JSONSerialization")
}
}
})
task.resume()
}
After execution I can see the following print statements:
in do block
Error in son serial
Cannot figure out what is wrong with JSON Serialization command here. Expected responses is a JSON array. Any help would be appreciated. Thx
Change the
if let json = try JSONSerialization.jsonObject(with: data!, options:[]) as? [String: Any]
To
if let json = try JSONSerialization.jsonObject(with: data!, options:[]) as? [Any]
beacuse the json you have is "jsonWithArrayRoot" check this for further details.
https://developer.apple.com/swift/blog/?id=37