Deserialize JSON in swift - ios

Is there a way to properly deserialize an json in swift that is this structure?
{
Usuario = (
{
"picture_url" = "";
id = 229;
name = "ABC";
}
);}
I tested this with jsonHelper library
let jsonData = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers )
let jsonString = jsonData
var mstemp = [usuario]()
mstemp <-- jsonString
but only worked for jsons this structure
{"name": "myUser", "id": "1","picture_url": ""}
Update
code:
let urlFinal = URLSERVIDOR+"/ws/rest/Geral/consultaUsuario?token=\(validotoken)&email=\(validoEmail)&senha=\(SenhaCriptada)"
let jsonUrl = urlFinal
let session = NSURLSession.sharedSession()
let shotsUrl = NSURL(string: jsonUrl)
let task = session.dataTaskWithURL(shotsUrl!) {data, response, error in
guard data != nil else {
falha()
return
}
do {
let jsonData = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers )
let jsonString = jsonData
var mstemp = [usuario]()
mstemp <-- jsonString
dispatch_async(dispatch_get_main_queue(),{
sucesso(usuarioBaixado: mstemp)
});
} catch _ {
falha()
}
}
task.resume()

Try this:
URLSession.shared.dataTask(with: shotsUrl!) {
(data, response, error) in
guard data != nil else {
return
}
guard let json = try? JSONSerialization.jsonObject(with: data!, options: []) as! [String: AnyObject],
let usuario = json["Usuario"] as! AnyObject else {
return
}
print ("Usuario:\n\t\(usuario["id"] as! Int)")
print ("\t\(usuario["name"] as! String)")
print ("\t\(usuario["picture_url"] as! String)")
}

Related

Converting Data from http request from JSON Dictionary of Dictionaries into one Array of Dictionaries in Swift

When Running my http request I get returned the data in the following way.
I am requesting as follows
do {
if let file = URL(string: "https://myhttprequest....") {
let data = try Data(contentsOf: file)
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let object = json as? [String: Any] {
// json is a dictionary
print(object)
} else {
print("JSON is invalid")
}
} else {
print("no file")
}
} catch {
print(error.localizedDescription)
}
The http request shows like this for example
{"created":[{"id":"-LVEAdIk2KwDmxBj25pK","caption":"Cool watch bro ","creationDate":1546442937.5934439,"imageHeight":1000,"imageUrl":"https://firebasestorage.googleapis.com/..."}],"reshared":[{"id":"-LVEAdIk2KwDmxBj25pK","caption":"Cool watch bro ","creationDate":1546442937.5934439,"imageHeight":1000,"imageUrl":"https://firebasestorage.googleapis.com/..."}]}
I want to be able to put the value of object["created"] and object["reshared"] together to have one array of two dictionaries [[caption:"", creationDate:""...],[caption:"", creationDate:""...]]
I have tried by accessing them individually like object["created"] but its not of type dictionary and I cant seem to figure out how to get it to be one.
UPDATE: So I am now doing the following
guard let uid = Auth.auth().currentUser?.uid else { return }
let url = URL(string: "https://us-central1-flashtrend-bdcd3.cloudfunctions.net/getFeed/\(uid)")!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let firstData = data else { return }
let jsonStr = String(data: firstData, encoding: .utf8)!
guard let data = jsonStr.data(using: .utf8) else {
return
}
do {
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
return
}
guard let created = json["created"], let reshared = json["reshared"] else {
return
}
let result = [created, reshared]
print(result)
} catch {
print(error.localizedDescription)
}
}
task.resume()
But when i print it looks weird
[<__NSSingleObjectArrayI 0x600002de2290>(
{
caption = "Cool watch bro ";
creationDate = "1546442937.593444";
id = "-LVEAdIk2KwDmxBj25pK";
imageHeight = 1000;
imageUrl = "https://firebasestorage.googleapis.com/v0/b/flashtrend-bdcd3.appspot.com/o/posts%2FE346E4B7-31D8-4E9E-89F2-DA7C426C0537?alt=media&token=4936ce58-64bb-4d5a-b913-c3b87705614f";
imageWidth = 750;
swipes = 0;
userid = U9097gARoXOus96vT1uBHAcNPs03;
views = 1;
}
)
, <__NSArray0 0x600002df40c0>(
)
]
I have changed the http request result to json string, sample code for you as follow, works fine on my xcode:
let jsonStr = "{\"created\":{\"caption\":\"Cool watch bro \",\"creationDate\":\"1546442937.593444\",\"id\":\"-LVEAdIk2KwDmxBj25pK\",\"imageHeight\":1000,\"imageUrl\":\"https://firebasestorage.googleapis.com/v0/b/flashtrend-bdcd3.appspot.com/o/posts/E346E4B7-31D8-4E9E-89F2-DA7C426C0537?alt:media&token:4936ce58-64bb-4d5a-b913-c3b87705614f\",\"imageWidth\":750,\"swipes\":0,\"userid\":\"U9097gARoXOus96vT1uBHAcNPs03\",\"views\":1},\"reshared\":{\"caption \":\"Cool watch bro\",\"creationDate \":\"1546442937.593444\",\"id \":\"-LVEAdIk2KwDmxBj25pK \",\"imageHeight\":1000,\"imageUrl\":\"https://firebasestorage.googleapis.com/v0/b/flashtrend-bdcd3.appspot.com/o/posts/E346E4B7-31D8-4E9E-89F2-DA7C426C0537?alt:media&token:4936ce58-64bb-4d5a-b913-c3b87705614f\",\"imageWidth\":750,\"swipes\":0,\"userid\":\"U9097gARoXOus96vT1uBHAcNPs03\",\"views\":1}}"
guard let data = jsonStr.data(using: .utf8) else {
return
}
do {
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
return
}
guard let created = json["created"], let reshared = json["reshared"] else {
return
}
let result = [created, reshared]
print(result)
} catch {
print(error.localizedDescription)
}

How to use if condition from using the console output?

How to use if condition from using the console output?
let myURL = URL(string: "http://www.digi.com/laravel_api_demo/api/demoapipost")
let request = NSMutableURLRequest(url: myURL!)
request.httpMethod = "POST"
let postString = "username=rahul"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
guard let _: Data = data, let _:URLResponse = response, error == nil else {
print("error")
return
}
if let dataString = String(data: data!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
{
print(dataString)
}
}
task.resume()
console output
How to use this output {"status":"No"}
I want to use if condition using status value.
Example:
if status == "YES"
{
print("Entered")
}
else
{
print("Not Entered")
}
Try to convert your String to Dictionary format.
func convertToDictionary(from text: String) -> [String: String]? {
guard let data = text.data(using: .utf8) else { return nil }
let anyResult = try? JSONSerialization.jsonObject(with: data, options: [])
return anyResult as? [String: String]
}
let string1 = "{\"status\":\"No\"}"
let dictionary1 : [String : String] = convertToDictionary(from: string1)!
if dictionary1["status"] == "No"
{
print("No")
}
else
{
print("yes")
}
As per, #moritz suggestion, you having JSON Data, so instead of converting to String, you can directly convert your data to [String : String]
if let respJSON = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String : String]
{
if respJSON["status"] == "No"
{
print("No")
}
else
{
print("yes")
}
}

Can't get data from Dark Sky API

I try to get information about the weather hourly from the Dark Sky API, but the code stops working at the if let data = hourly["data"] as? [String : AnyObject] line (checked with printing stuff after every line). I want to know what is wrong with my code. I think it could be something with the "data" let, but I don't know for sure.
let Task2 = URLSession.shared.dataTask(with: urlRequestDark) { (data, response, error) in
if error == nil {
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String : AnyObject]
if let hourly = json["hourly"] as? [String : AnyObject] {
if let data = hourly["data"] as? [String : AnyObject]{
if let hourNum = data["14"] as? [String : AnyObject] {
if let chanceRain = hourNum["precipProbability"] as? Float{
self.chanceHour1 = String(chanceRain)
}
DispatchQueue.main.sync {
self.ChanceRainLabel.text = self.chanceHour1
}
}
}
}
} catch let jsonError {
print(jsonError.localizedDescription)
}
}
}
Task2.resume() test
The strange part is, this does work:
let urlRequestDark = URLRequest(url: URL (string: "https://api.darksky.net/forecast/(API Key)/(coordinates)")!)
let Task = URLSession.shared.dataTask(with: urlRequestDark) { (data, response, error) in
if error == nil {
do{
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String : AnyObject]
if let currently = json["currently"] as? [String : AnyObject] {
if let chance2 = currently["precipProbability"] as? Float{
print(String(chance2))
self.chance = String(Int(chance2 * 100)) + "%"
self.PreType = currently["precipType"] as? String
}
if let _ = json["error"]{
}
DispatchQueue.main.sync{
self.TypeLabel.text = self.PreType
self.ChanceLabel.text = self.chance
}
}
}catch let jsonError{
print(jsonError.localizedDescription)
}
}
}
Task.resume()
You've made couple mistakes.
First, "data" is an array of dictionaries, so it should be cast to [[String : AnyObject]].
Second, you're trying to subscript array by String, not Int.
Third, using self in escaping closures potentially creates retain cycles.
Let me propose you some fixed and adjusted code.
let task2 = URLSession.shared.dataTask(with: urlRequestDark) { [weak self] (data, response, error) in
guard error == nil else { return }
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String : AnyObject],
let hourly = json["hourly"] as? [String : AnyObject],
let data = hourly["data"] as? [[String : AnyObject]],
data.count > 14,
let chanceRain = data[14]["precipProbability"] as? Float {
self?.chanceHour1 = String(chanceRain)
DispatchQueue.main.sync {
self?.ChanceRainLabel.text = self?.chanceHour1
}
}
} catch let jsonError {
print(jsonError.localizedDescription)
}
}
task2.resume()
Try like this
import UIKit
class WebService: NSObject {
var session = URLSession()
public class var sharedInstance: WebService {
struct Singleton {
static let instance = WebService()
}
return Singleton.instance
}
override init() {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30.0
configuration.timeoutIntervalForResource = 60.0
session = URLSession(configuration: configuration)
}
public func weatherData(coordinate:String,APIkey:String,completion:#escaping (_ responsedata:NSDictionary?,_ error:NSError?) -> Void) {
var Baseurl = "https://api.darksky.net/forecast/\(APIkey)/\(coordinate)"
Baseurl = Baseurl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
let weatherRequestUrl = URL(string: Baseurl)
let request = NSMutableURLRequest(url: weatherRequestUrl!)
let task = session.dataTask(with: request as URLRequest) { (data, response, error) in
guard error == nil && data != nil else {
return
}
if let httpStatus = response as? HTTPURLResponse{
if httpStatus.statusCode != 200 {
print("Something is wrong")
}
}
do {
let WindlocationData = try JSONSerialization.jsonObject(with: data! as Data, options:.allowFragments) as! NSDictionary
print(WindlocationData)
completion(WindlocationData,nil)
}
catch let error as NSError {
completion(nil,error)
}
}
task.resume()
}
}
And call API like this!
func callAPI(latlong:String,APIkeyParm:String) {
WebService.sharedInstance.weatherData(coordinate: latlong,APIkey: APIkeyParm) { (responsData, error) in
if error == nil{
print("Response data is-\(responsData)")
}
}
}
Call the method like this
let latlongStr = "\(latitude),\(longitude)"
self.callAPI(latlong: latlongStr,APIkeyParm: "APIKeyString")
One importent thing you need to pass latlong like this format 23.022504999999999,72.571362100000002

Parse JSON response with Swift 3

I have JSON looking like this:
{"posts":
[
{
"id":"1","title":"title 1"
},
{
"id":"2","title":"title 2"
},
{
"id":"3","title":"title 3"
},
{
"id":"4","title":"title 4"
},
{
"id":"5","title":"title 5"
}
],
"text":"Some text",
"result":1
}
How can I parse that JSON with Swift 3?
I have this:
let url = URL(string: "http://domain.com/file.php")!
let request = URLRequest(url: url)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print("request failed \(error)")
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String: String], let result = json["result"] {
// Parse JSON
}
} catch let parseError {
print("parsing error: \(parseError)")
let responseString = String(data: data, encoding: .utf8)
print("raw response: \(responseString)")
}
}
task.resume()
}
Use this to parse your data:
let url = URL(string: "http://example.com/file.php")
URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
guard let data = data, error == nil else { return }
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any]
let posts = json["posts"] as? [[String: Any]] ?? []
print(posts)
} catch let error as NSError {
print(error)
}
}).resume()
Use guard to check if you have data and that error is empty.
Swift 5.x version
let url = URL(string: "http://example.com/file.php")
URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
guard let data = data, error == nil else { return }
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:Any]
let posts = json?["posts"] as? [[String: Any]] ?? []
print(posts)
} catch {
print(error)
}
}).resume()
In swift 3.0 for GET method:
var request = URLRequest(url: URL(string: "Your URL")!)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
}
task.resume()
In swift 3.0 for POST method:
var request = URLRequest(url: URL(string: "Your URL")!)
request.httpMethod = "POST"
let postString = "user_name=ABC" // Your parameter
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
}
task.resume()
Because your data structure of test json should be "[String: AnyObject]". The json key "posts" value is Array type.
DISTANCE--DIFFICULT API
========================>
class ViewController: UIViewController {
var get_data = NSMutableData()
var get_dest = NSArray()
var org_add = NSArray()
var row_arr = NSArray()
var ele_arr = NSArray()
var ele_dic = NSDictionary()
var dist_dic = NSDictionary()
var dur_dic = NSDictionary()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
getmethod()
}
func getmethod()
{
let url_str = URL(string: "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&departure_time=1408046331&origins=37.407585,-122.145287&destinations=37.482890,-122.150235")
let url_req = URLRequest(url: url_str!)
let task = URLSession.shared.dataTask(with: url_req) { (data, response, error) in
if let my_data = data
{
print("my data is----->",my_data)
do
{
self.get_data.append(my_data)
let jsondata = try JSONSerialization.jsonObject(with: self.get_data as Data, options: [])as! NSDictionary
print("json data is--->",jsondata)
self.get_dest = jsondata.object(forKey: "destination_addresses")as! NSArray
let get_dest1:String = self.get_dest.object(at: 0) as! String
print("destination is--->",get_dest1)
self.org_add = jsondata.object(forKey: "origin_addresses")as! NSArray
let get_org:String = self.org_add.object(at: 0)as! String
print("original address is--->",get_org)
self.row_arr = jsondata.object(forKey: "rows")as! NSArray
let row_dic = self.row_arr.object(at: 0)as! NSDictionary
self.ele_arr = row_dic.object(forKey: "elements")as! NSArray
self.ele_dic = self.ele_arr.object(at: 0)as! NSDictionary
self.dist_dic = self.ele_dic.value(forKey: "distance")as! NSDictionary
print("distance text is--->",self.dist_dic.object(forKey: "text")as! String)
print("distance value is--->",self.dist_dic.object(forKey: "value")as! Int)
// self.ele_dic = self.ele_arr.object(at: 1)as! NSDictionary
self.dur_dic = self.ele_dic.value(forKey: "duration")as! NSDictionary
print("duration text--->",self.dur_dic.value(forKey: "text")as! String)
print("duration value--->",self.dur_dic.value(forKey: "value")as! Int)
print("status---->",self.ele_dic.object(forKey: "status")as! String)
}
catch
{
print("error is--->",error.localizedDescription)
}
}
};task.resume()
}

swift Unescaped control character

I'm trying to get a json from a server and deserialize it, but I try probelas with unescaped control characters.
My code is as follows ...
let urlFinal = "http://000.0000.000.000:8080"
let jsonUrl = urlFinal
let session = NSURLSession.sharedSession()
let shotsUrl = NSURL(string: jsonUrl)
let task = session.dataTaskWithURL(shotsUrl!) {data, response, error in
guard data != nil else {
falha()
return
}
//let json = JSON(data: data!)
//print(json["ServicoCliente"][0]["id"])
do {
let jsonData = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers )
let J = jsonData as! NSDictionary
print(jsonData)
let us = J["ServicoCliente"]
print(us)
dispatch_async(dispatch_get_main_queue(),{
sucesso()
});
} catch _ {
falha()
}
}
task.resume()
and I also tried this using Alamofire 3.0:
Alamofire.request(.GET, "http://000.000.000.000/", parameters: nil)
.responseJSON { response in
debugPrint(response) // prints detailed description of all response properties
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
And get this error:
Unescaped control character around character 263
How can I remove characters without escape?
I use X-Code 7.3.1 and Swift 2.3
UPDATE:
Json
{"ServicoCliente":[{"id":"195","cliente":"247","enderecoFavoritos":"48","servicoProfissional":"194","ind_estado_cliente":"A","ind_estado_profissional":"","profissional_id":"240","profissional_nome":"PetMax","servicotipo_nome":"Petshop","servicosubtipo_nome":"Tosa ","dta_inc_alt":"2016-11-05 22:56:19.333","ind_finalizado":"N"}]}
To fix this, you must convert the data for string, remove characters and then convert to dataonly then deserialize
let urlFinal = "http://000.0000.000.000:8080"
let jsonUrl = urlFinal
let session = NSURLSession.sharedSession()
let shotsUrl = NSURL(string: jsonUrl)
let task = session.dataTaskWithURL(shotsUrl!) {data, response, error in
guard data != nil else {
falha()
return
}
var dataToString = String(data: data!, encoding: NSUTF8StringEncoding)
dataToString = stringByRemovingControlCharacters2(dataToString!)
let ndata = dataToString!.dataUsingEncoding(NSUTF8StringEncoding)
do {
let jsonData = try NSJSONSerialization.JSONObjectWithData(ndata!, options: NSJSONReadingOptions.MutableContainers )
let J = jsonData as! NSDictionary
print(jsonData)
let us = J["ServicoCliente"]
print(us)
dispatch_async(dispatch_get_main_queue(),{
sucesso()
});
} catch _ {
falha()
}
}
task.resume()
and add the function
func stringByRemovingControlCharacters2(string: String) -> String {
let controlChars = NSCharacterSet.controlCharacterSet()
var range = string.rangeOfCharacterFromSet(controlChars)
var mutable = string
while let removeRange = range {
mutable.removeRange(removeRange)
range = mutable.rangeOfCharacterFromSet(controlChars)
}
return mutable
}
Swift 5
func string(byRemovingControlCharacters inputString: String) -> String {
let controlChars = CharacterSet.controlCharacters
var range = (inputString as NSString).rangeOfCharacter(from: controlChars)
if range.location != NSNotFound {
var mutable = inputString
while range.location != NSNotFound {
if let subRange = Range<String.Index>(range, in: mutable) { mutable.removeSubrange(subRange) }
range = (mutable as NSString).rangeOfCharacter(from: controlChars)
}
return mutable
}
return inputString
}

Resources