How to get particular 'json' value in swift 5? - json

I want the 'success' value in json object but the problem is I'm getting whole json data I want only 'success' value to print
Here is my json`
{
response = {
success = 1;
successmsg = "Successful Connection";
};
}`
Here is my code in swift 5
#IBAction func girisButtonTap(_ sender: Any) {
var txtusername: String
var txtpassword: String
txtusername = usercodeText.text!
txtpassword = passwordText.text!
let Url = String(format: "http://10.10.10.53:8080/sahambl/rest/sahamblsrv/userlogin")
guard let serviceUrl = URL(string: Url) else { return }
let parameters: [String: Any] = [
"request": [
"xusercode" : "\(txtusername)",
"xpassword": "\(txtpassword)"
]
]
var request = URLRequest(url: serviceUrl)
request.httpMethod = "POST"
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else {
return
}
request.httpBody = httpBody
request.timeoutInterval = 20
let session = URLSession.shared
struct ResponseJSON: Codable {
let response: Response
}
struct Response: Codable {
let success: Int
let successmsg: String
}
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONDecoder().decode(ResponseJSON.self, from: data)
print(json)
let successful = json.response.success == 1
} catch {
print(error)
}
}
}.resume()
}
}
I would be grateful for any progress.

Use a model struct and Codable for parsing:
struct ResponseJSON: Codable {
let response: Response
}
struct Response: Codable {
// depending on what your JSON actually looks like, this could also be
// let success: Bool
let success: Int
let successmsg: String
}
session.dataTask(with: request) { data, response, error in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONDecoder().decode(ResponseJSON.self, from: data)
print(json)
// access the success property:
let successful = json.response.success == 1
// leave off the "== 1" if it's a Bool
} catch {
print(error)
}
}
}.resume()

Related

Unable to get JSON response with Decodable in Swift

in postman response structure like this:
{
"categories": [
{
"id": 48,
"name": "Round-The-Clock",
"description": "24 hours round the clock menu",
"status": "enabled",
"products": [
{
"id": 280,
"name": ".Tea",.....
for this i have created Decodable model like this
struct Categories: Codable {
let categories: [Category]?
let featuredProducts: [Product]?
//coding keys..
}
struct Category: Codable {
let id: Int?
let name, categoryDescription: String?
let products: [Product]?
}
struct Product: Codable {
let id: Int?
let name, productDescription: String?
}
Parsing code: with this code break point hits with this if let jsonData = try? decoder.decode(Categories.self, from: respData) line but not hitting print("the categories are: (jsonData)") line and nothing comes in console, why? where am i wrong.. how to get response
class FoodMenuViewController: UIViewController {
private var catData: Categories? {
didSet{ }
}
func foodMenuServicecall(){
let urlStr = "http://54.149.84.126/categories?shop=1"
let url = URL(string: urlStr)
var req = URLRequest(url: url!)
req.httpMethod = "GET"
req.addValue("X-Requested-With", forHTTPHeaderField: "Content-Type")
req.addValue("XMLHttpRequest", forHTTPHeaderField: "X-Requested-With")
URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
guard let respData = data else {return}
guard error == nil else {
print("error")
return
}
do{
let decoder = JSONDecoder()
if let jsonData = try? decoder.decode(Categories.self, from: respData) {
print("the categories are: \(jsonData)")
self.catData = jsonData
}
}
catch {print("catch error")}
}).resume()
}
EDIT: if i test like this i am getting response but here
func foodMenuServicecall(){
if let url = URL(string: "http://54.149.84.126//categories?shop=1"){
var req = URLRequest(url: url)
req.allHTTPHeaderFields = ["X-Requested-With" : "XMLHttpRequest"]
URLSession.shared.dataTask(with: req) { data, _, err in
guard let safeData = data else{return}
print(String(data: safeData, encoding: .utf8) ?? "")
}.resume()
}
}
o/p in consol:
Your decodable model expects a key of "categoryDescription", your JSON has a key of "description".

Issue with Codable object to JSON conversion

Apologies if this is a basic question, I am new using Apis and JSON in Swift. I am attempting to submit a post request but am receiving:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__SwiftValue)'.
I believe that this is due to a incorrect/unconvertible type but I have tried multiple different permutations of the variables I am passing and it continues to fail.
Here is my ContentView:
struct ContentView: View {
#State var town: Space = Space(title: "test city", description: "is this working")
var body: some View {
Button(action: {
Api.postRequest(param: ["space" : town], urlString: Api.spacePostUrl) { (update) in
print("\(update)")
}
}) {
Text("Post Request")
}
}
}
The underlying data struct:
struct Space: Codable {
var title: String
var description: String
}
And my attempted API call:
class Api {
static let spacePostUrl = "http://localhost:3001/spaces"
static let spaceGetUrl = "http://localhost:3001/"
static func postRequest(param: [String : Codable], urlString: String, completion: #escaping (Int) -> ()) {
guard let url = URL(string: urlString) else { return }
let body = try? JSONSerialization.data(withJSONObject: param)
var request = URLRequest(url: url)
request.httpBody = body
request.httpMethod = "POST"
URLSession.shared.dataTask(with: request) { (data, request, error) in
guard let update = data else { return }
do {
let update = try JSONDecoder().decode(Int.self, from: update)
DispatchQueue.main.async {
completion(update)
}
}
catch {
print(error)
}
}
}
}
class Api {
static let spacePostUrl = "http://localhost:3001/spaces"
static let spaceGetUrl = "http://localhost:3001/"
static func postRequest(param: [String : Codable], urlString: String, completion: #escaping (Int) -> ()) {
guard let url = URL(string: urlString) else { return }
let body = try? JSONSerialization.data(withJSONObject: param)
var request = URLRequest(url: url)
request.httpBody = body
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request) { (data, request, error) in
guard let update = data else { return }
do {
let update = try JSONDecoder().decode(Space.self, from: update)
DispatchQueue.main.async {
completion(update)
}
}
catch {
print(error)
}
}
task.resume()
}
}

How else can I format the data? swift parse json - The data couldn’t be read because it isn’t in the correct format

The JSON data is
[
{"id":0,"temperature":77,"humidity":0.22,"timeCaptured":"2020-09-25T19:33:27.9733333"},
{"id":0,"temperature":77,"humidity":0.22,"timeCaptured":"2020-09-25T20:38:53.3"},
{"id":0,"temperature":85,"humidity":0.25,"timeCaptured":"2020-09-25T20:38:53.3"},
{"id":0,"temperature":88,"humidity":0.22,"timeCaptured":"2020-09-28T15:30:00"},
// ...
]
My structs look like this
struct TemperatureDataModel: Codable{
let id: Int?
let temperature: Double?
let humidty: Double?
let timeCaptured: String?
}
My function looks like this
func getTemperData(){
//Create the URLs
let temperatureDataUrl = URL(string: "https://weatherstationapi.azurewebsites.net/api/TemperatureSensor/GetData")
// let WindDataUrl = URL(string: "https://weatherstationapi.azurewebsites.net/api/WindData/GetAllData")
guard let requestURLTemp = temperatureDataUrl else { fatalError() }
//Create URL request
var request = URLRequest(url: requestURLTemp)
//Specifiy HTTP Method to use
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiaWxpci50YWlyaUB0dHUuZWR1IiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZWlkZW50aWZpZXIiOiI4MjEzYzhhMy1iODgxLTQ4NmUtOGUyMC1mZmNlMDlmNGY0ZjgiLCJuYmYiOiIxNjAyNTI2NDI1IiwiZXhwIjoiMTYwNTExODQyNSJ9.t1qnYyXLpRRJ3YQfhgLrylBqL_pdKOnKVMgOfG9IuVc", forHTTPHeaderField: "Authorization")
//Send HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data else {return}
print(data)
//Use parseJSON to convert data
let TemperatureData = parseJSON(data: data)
// for singleValue in TemperatureData {
// print(singleValue.temperautre)
// }
//read list
guard let TemperatureDataModel = TemperatureData else {return}
print("Temperature is : \(TemperatureDataModel.temperature)")
// Check if error took place
if let error = error {
print("Error took place \(error)")
return
}
//Read HTTP Response Status Code
// if let data = data, let dataString = String(data: data, encoding: .utf8) {
// print("Response data string:\n \(dataString)")
// }
}
task.resume()
}
and then my JSON decoder function looks like this
func parseJSON(data: Data) -> TemperatureDataModel? {
var returnValue: TemperatureDataModel?
do {
let returnValue = try JSONDecoder().decode([TemperatureDataModel].self, from: data)
} catch {
print("Error took place \(error).")
}
return returnValue
}
I've looked at 6+ stack overflow posts now and still cannot figure It out. Ive tried putting my model in [] for an array, moving where the function is called, changing the jsondecoder function and more and nothing works.
I think you have to give a format to the date before you parse the data
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
Your issue there is that you are creating another returnValue that is not being returned. You need also change the return type to [TemperatureDataModel]
func parseJSON(data: Data) -> [TemperatureDataModel]? {
do {
return try JSONDecoder().decode([TemperatureDataModel].self, from: data)
} catch {
print("Error took place \(error).")
return nil
}
}

i am trying to parse json with swift 4, please tell me what is wrong in it?

I am trying to parse JSON using the following method, but XCode is giving me an error where I have declared "data" .
I am new, I don't understand what is wrong. Please help me.
import UIKit
struct Contacts: Decodable {
let id: Int
let name: String
let email: String
}
class ViewController: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
let urlString = "https://api.androidhive.info/contacts/"
guard let url = URL(string: urlString) else {return}
URLSession.shared.dataTask(with: url) { (data, response, error) in
}
guard let data = data else {return}
//let datastring = String(data: data, encoding: .utf8)
do
{
let contact = try JSONDecoder().decode([Contacts].self, from: data)
print(contact.name)
} catch let jsonErr {
print("Error deserializing json:", jsonErr)
}
}
}
Three major issues.
You are ignoring the root object which is a dictionary containing the contacts array.
The value for key id is String, not Int.
A hard rule is : Everything in double quotes is String even "12" and "false"
You have to resume the task and put the code to parse the JSON into the completion handler.
struct Root : Decodable {
let contacts : [Contact]
}
struct Contact : Decodable { // It's recommended to name this kind of struct in singular form
let id, name, email: String
}
...
override func viewDidLoad()
{
super.viewDidLoad()
let urlString = "https://api.androidhive.info/contacts/"
guard let url = URL(string: urlString) else {return}
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error { print(error); return }
do {
let result = try JSONDecoder().decode(Root.self, from: data!)
let contacts = result.contacts
for contact in contacts {
print(contact.name)
}
} catch {
print("Error deserializing json:", error)
}
}.resume()
}
//
// ViewController.swift
// PostMethodTest
//
// Created by HABIB UR REHMAN on 12/11/2018.
// Copyright © 2018 HABIB UR REHMAN. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
struct Resturant: Decodable {
var name: String
var deliveryCharges: String
var email: String
init(_ dictionary: [String: Any]) {
self.name = dictionary["name"] as? String ?? ""
self.deliveryCharges = dictionary["deliveryCharges"] as? String ?? ""
self.email = dictionary["email"] as? String ?? ""
}
}
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: "your Link Here ") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request) {(data, response, error) in
guard let dataResponse = data,
error == nil else {
print(error?.localizedDescription ?? "Response Error")
return }
do{
//here dataResponse received from a network request
let jsonResponse = try JSONSerialization.jsonObject(with:
dataResponse, options: [])
print(jsonResponse) //Response result
} catch let parsingError {
print("Error", parsingError)
}
}
task.resume()
}
}
Please Try this its working for me.
func getContactListsApiCalling() {
var request = URLRequest(url: URL(string: "https://api.androidhive.info/contacts/")!)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
do {
if let Data = data {
let responseJSON = try JSONSerialization.jsonObject(with: Data) as? Dictionary<String, AnyObject> ?? [:]
if let contacts = responseJSON["contacts"] as? [[String :AnyObject]] {
for contact in contacts {
let id = contact["id"] as? String ?? ""
let name = contact["name"] as? String ?? ""
let email = contact["email"] as? String ?? ""
let address = contact["address"] as? String ?? ""
let gender = contact["gender"] as? String ?? ""
print(id,name,email,address,gender)
}
}
}
} catch {
print("error")
}
})
task.resume()
}
}

How to parse JSON using swift 4

I am confusing to getting detail of fruit
{
"fruits": [
{
"id": "1",
"image": "https://cdn1.medicalnewstoday.com/content/images/headlines/271/271157/bananas.jpg",
"name": "Banana"
},
{
"id": "2",
"image": "http://soappotions.com/wp-content/uploads/2017/10/orange.jpg",
"title": "Orange"
}
]
}
Want to parse JSON using "Decodable"
struct Fruits: Decodable {
let Fruits: [fruit]
}
struct fruit: Decodable {
let id: Int?
let image: String?
let name: String?
}
let url = URL(string: "https://www.JSONData.com/fruits")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
guard let data = data else { return }
do{
let fruits = try JSONDecoder().decode(Fruits.self, from: data)
print(Fruits)
}catch {
print("Parse Error")
}
also can you please suggest me cocoapod library for fastly download images
The issue you are facing is because your JSON is returning different data for your Fruits.
For the 1st ID it returns a String called name, but in the 2nd it returns a String called title.
In addition when parsing the JSON the ID appears to be a String and not an Int.
Thus you have two optional values from your data.
As such your Decodable Structure should look something like this:
struct Response: Decodable {
let fruits: [Fruits]
}
struct Fruits: Decodable {
let id: String
let image: String
let name: String?
let title: String?
}
Since your URL doesn't seem to be valid, I created the JSON file in my main bundle and was able to parse it correctly like so:
/// Parses The JSON
func parseJSON(){
if let path = Bundle.main.path(forResource: "fruits", ofType: "json") {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let jsonResult = try JSONDecoder().decode(Response.self, from: data)
let fruitsArray = jsonResult.fruits
for fruit in fruitsArray{
print("""
ID = \(fruit.id)
Image = \(fruit.image)
""")
if let validName = fruit.name{
print("Name = \(validName)")
}
if let validTitle = fruit.title{
print("Title = \(validTitle)")
}
}
} catch {
print(error)
}
}
}
Hope it helps...
// Parse Json using decodable
// First in create Structure depends on json
//
//
//
struct Countory : Decodable {
let name: String
let capital: String
let region: String
}
let url = "https://restcountries.eu/rest/v2/all"
let urlObj = URL(string: url)!
URLSession.shared.dataTask(with: urlObj) {(data, responds, Error) in
do {
var countories = try JSONDecoder().decode([Countory].self, from: data!)
for country in countories {
print("Country",country.name)
print("###################")
print("Capital",country.capital)
}
} catch {
print(" not ")
}
}.resume()
Model sample:
public struct JsonData: Codable{
let data: [Data]?
let meta: MetaValue?
let linksData: LinksValue?
private enum CodingKeys: String, CodingKey{
case data
case meta
case linksData = "links"
}
}
enum BackendError: Error {
case urlError(reason: String)
case objectSerialization(reason: String)
}
struct APIServiceRequest {
static func serviceRequest<T>(reqURLString: String,
resultStruct: T.Type,
completionHandler:#escaping ((Any?, Error?) -> ())) where T : Decodable {
guard let url = URL(string: reqURLString) else {
print("Error: cannot create URL")
let error = BackendError.urlError(reason: "Could not construct URL")
completionHandler(nil, error)
return
}
let urlRequest = URLRequest(url: url)
let session = URLSession.shared
let task = session.dataTask(with: urlRequest) { (data, response, error) in
guard error == nil else {
completionHandler(nil, error)
return
}
guard let responseData = data else {
print("Error: did not receive data")
let error = BackendError.objectSerialization(reason: "No data in response")
completionHandler(nil, error)
return
}
let decoder = JSONDecoder()
do {
let books = try decoder.decode(resultStruct, from: responseData)
completionHandler(books, nil)
} catch {
print("error trying to convert data to JSON")
print(error)
completionHandler(nil, error)
}
}
task.resume()
}
}
To Access:
let apiService = APIServiceRequest()
var dataArray: [String: Any]? //global var
apiService.serviceRequest(reqURLString: endPoint, resultStruct: VariantsModel.self, completionHandler: {dataArray,Error in})
POST Method
func loginWS(endpoint: String, completionHandler: #escaping (Any?) -> Swift.Void) {
guard let sourceUrl = URL(string: endpoint) else { return }
let request = NSMutableURLRequest(url: sourceUrl)
let session = URLSession.shared
request.httpMethod = "POST"
request.addValue(vehiceHeader, forHTTPHeaderField: "X-Vehicle-Type")
request.addValue(contentHeader, forHTTPHeaderField: "Content-Type")
let task = session.dataTask(with: request as URLRequest) { data, response, error in
guard let data = data else { return }
do {
let responseData = try JSONDecoder().decode(JsonData.self, from: data)
print("response data:", responseData)
completionHandler(responseData)
} catch let err {
print("Err", err)
}
}.resume()
}