How to get value from json in iOS Swift? - arrays

I have JSON with dynamic data of all key values. Right now I am trying to get value by finding "type = object" if an object exists then in values I will check the contentType exists in values.
How to find the value matched inside JSON and convert it into an array?
Here is my code:
switch response.result {
case .success:
guard let data = response.value else {
return
}
if let JSON = response.value {
let json = JSON as? [String: AnyObject]
print("json view docue",json)
if let castedDict = json as? [String: String] {
print("Converted successfully: \(castedDict)")
} else {
print("Failed to cast the dictionary")
}
let vc = self.stringify(json: json)
print("new json converted into string:::", vc.count)
}
self.view.removeLoading()
case .failure(let error):
print("Error:", error)
self.view.removeLoading()
}
Here is my JSON:
{
image1: {
type = Object;
value = "{\"contentType\":\"image/jpeg\",\"url\":\"https://www.pexels.com/photo/neon-advertisement-on-library-glass-wall-9832438/",\"fileName\":\"9832438.jpg\"}";
valueInfo = {
objectTypeName = "com.google.gson.JsonObject";
serializationDataFormat = "application/json";
};
},
image2: {
type = Object;
value = "{\"contentType\":\"image/jpeg\",\"url\":\"https://www.pexels.com/photo/neon-advertisement-on-library-glass-wall-9832438/",\"fileName\":\"9832438.jpg\"}";
valueInfo = {
objectTypeName = "com.google.gson.JsonObject";
serializationDataFormat = "application/json";
};
}
}
Any much appreciated pls...

Related

how convert JSON response to Array in swift?

func llamadaApiDos(postData: (Data),empresa: String,boundary: String) -> [String] {
var request = URLRequest(url: URL(string: "https://www.something.com")!,timeoutInterval: Double.infinity)
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
var success = false
var serviceResponse = [""]
let semaphore = DispatchSemaphore(value: 0)
let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
if let error = error {
print("Error while trying to re-authenticate the user: \(error)")
} else if let response = response as? HTTPURLResponse,
300..<600 ~= response.statusCode {
print("Error while trying to re-authenticate the user, statusCode: \(response.statusCode)")
} else if let data = data {
let loginDataModel = try! JSONDecoder().decode(responseLogin.self,from: data)
serviceResponse = JSONDecoder.decode(loginDataModel)
success = true
}else{
success = true
}
semaphore.signal()
})
task.resume()
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
if success
{
return serviceResponse
}else
{
return ["Error"]
}
}
Cannot assign value of type '(T.Type, Data) throws -> T' to type '[String]'
I need to convert the JSON response into an array that can be validated in another function, but I don't know what type of data I should return, I'm sorry if it's not well understood, my English isn't very good either.
To convert the JSON response to an array in Swift, you can use the JSONSerialization class to convert the response data to a dictionary, then access the array stored in the dictionary using the key for the array.
Here's an example:
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let array = json["keyForArray"] as? [String] {
// Use the array here
}
In your code, you can use this approach to convert the JSON response to an array, then return the array from the llamadaApiDos function.
Here's how your function would look like with this change:
func llamadaApiDos(postData: (Data),empresa: String,boundary: String) -> [String] {
var request = URLRequest(url: URL(string: "https://www.something.com")!,timeoutInterval: Double.infinity)
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
var success = false
var serviceResponse = [""]
let semaphore = DispatchSemaphore(value: 0)
let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
if let error = error {
print("Error while trying to re-authenticate the user: \(error)")
} else if let response = response as? HTTPURLResponse,
300..<600 ~= response.statusCode {
print("Error while trying to re-authenticate the user, statusCode: \(response.statusCode)")
} else if let data = data {
// Convert the JSON response to an array
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let array = json["keyForArray"] as? [String] {
// Use the array here
serviceResponse = array
success = true
}
}else{
success = true
}
semaphore.signal()
})
task.resume()
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
if success
{
return serviceResponse
}else
{
return ["Error"]
}
}

Swift Accessing array values within dictionary

I am very new to Swift coming from Obj C background. I am struggling to access a couple of key value pairs in a dictionary that comes from some JSON returned from an API endpoint. I can get as far as "data" but not sure how to get access to the arrays below that key. Specifically I am trying to return values for "id" and "price" as follows:
id = 1;
price = "20160.67609688202"
I would appreciate any help you might offer. Thank you.
Swift:
#IBAction func buttonAction(_ sender: Any) {
// Create the URL
let query = txt_Symbol.text
let api = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?CMC_PRO_API_KEY=myKey&symbol="
let endpoint = query!
let url = URL(string: api + endpoint)
guard let requestUrl = url else { fatalError() }
// Create URL Request
var request = URLRequest(url: requestUrl)
// Specify HTTP Method to use
request.httpMethod = "GET"
// Send HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
// Check if Error took place
if let error = error {
print("Error took place \(error)")
return
}
// Read HTTP Response Status code
if let response = response as? HTTPURLResponse {
print("Response HTTP Status code: \(response.statusCode)")
}
// Convert HTTP Response Data to a simple String
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:\n \(dataString)")
do {
if let convertedJsonIntoDict = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary {
// Print out entire dictionary
print("convertedJsonIntoDict:")
print(convertedJsonIntoDict)
// UI API called on a background thread
// Call this on the main thread
DispatchQueue.main.async {
//Do UI Code here.
self.txtarea_JSON.text = convertedJsonIntoDict.description
// Get a value by key
let coinData = convertedJsonIntoDict["data"]
print(coinData ?? "coin could not be read")
// how do I access these key value pairs?
// id = 1;
// price = "20160.67609688202"
}
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
task.resume()
}
JSON:
{
data = {
BTC = {
"circulating_supply" = 19138912;
"cmc_rank" = 1;
"date_added" = "2013-04-28T00:00:00.000Z";
id = 1;
"is_active" = 1;
"is_fiat" = 0;
"last_updated" = "2022-09-02T03:39:00.000Z";
"max_supply" = 21000000;
name = Bitcoin;
"num_market_pairs" = 9718;
platform = "<null>";
quote = {
USD = {
"fully_diluted_market_cap" = "423374198034.52";
"last_updated" = "2022-09-02T03:39:00.000Z";
"market_cap" = "385853405678.7285";
"market_cap_dominance" = "39.0616";
"percent_change_1h" = "0.83296442";
"percent_change_24h" = "0.16774456";
"percent_change_30d" = "-11.73989491";
"percent_change_60d" = "5.58985077";
"percent_change_7d" = "-6.59123025";
"percent_change_90d" = "-31.87091684";
price = "20160.67609688202";
tvl = "<null>";
"volume_24h" = "29753736862.94145";
"volume_change_24h" = "-7.2446";
};
};
"self_reported_circulating_supply" = "<null>";
"self_reported_market_cap" = "<null>";
slug = bitcoin;
symbol = BTC;
tags = (
mineable,
pow,
"sha-256",
"store-of-value",
"state-channel",
"coinbase-ventures-portfolio",
"three-arrows-capital-portfolio",
"polychain-capital-portfolio",
"binance-labs-portfolio",
"blockchain-capital-portfolio",
"boostvc-portfolio",
"cms-holdings-portfolio",
"dcg-portfolio",
"dragonfly-capital-portfolio",
"electric-capital-portfolio",
"fabric-ventures-portfolio",
"framework-ventures-portfolio",
"galaxy-digital-portfolio",
"huobi-capital-portfolio",
"alameda-research-portfolio",
"a16z-portfolio",
"1confirmation-portfolio",
"winklevoss-capital-portfolio",
"usv-portfolio",
"placeholder-ventures-portfolio",
"pantera-capital-portfolio",
"multicoin-capital-portfolio",
"paradigm-portfolio"
);
"total_supply" = 19138912;
"tvl_ratio" = "<null>";
};
};
status = {
"credit_count" = 1;
elapsed = 35;
"error_code" = 0;
"error_message" = "<null>";
notice = "<null>";
timestamp = "2022-09-02T03:41:38.218Z";
};
}
You could decode the api response into a set of models (struct) instead of a dictionary.
Here is an example code that shows how to decode the api response and use it.
(you will need to adjust the models according to the server documentations)
Once you have the data decoded into the models, it is far easier to deal with than a dictionary of nested (key,value) pairs.
let formatter: DateFormatter = {
let frmt = DateFormatter()
frmt.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
return frmt
}()
if let data = data {
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
let decoded = try decoder.decode(APIResponse.self, from: data)
// print("\n---> decoded: \n \(decoded)")
if let coinData = decoded.data.first?.value {
print("\n---> coinData: \n \(coinData)")
print("\n---> coinData name: \n \(coinData.name)")
print("\n---> coinData quote: \n \(coinData.quote)")
print("\n---> coinData quote usd: \n \(coinData.quote.usd)")
}
} catch {
print("==> decoding error: \(error)")
}
}
Where the models are declared as follows:
struct APIResponse: Codable {
let data: [String : CoinData]
let status: Status
}
struct CoinData: Identifiable, Codable {
let id: Int
let name, symbol, slug: String
let isActive, isFiat, circulatingSupply, totalSupply: Int
let maxSupply: Int
let dateAdded: Date
let numMarketPairs, cmcRank: Int
let lastUpdated: Date
let tags: [String]
let platform, selfReportedCirculatingSupply, selfReportedMarketCap: String?
let quote: Quote
enum CodingKeys: String, CodingKey {
case id, name, symbol, slug
case isActive = "is_active"
case isFiat = "is_fiat"
case circulatingSupply = "circulating_supply"
case totalSupply = "total_supply"
case maxSupply = "max_supply"
case dateAdded = "date_added"
case numMarketPairs = "num_market_pairs"
case cmcRank = "cmc_rank"
case lastUpdated = "last_updated"
case tags, platform
case selfReportedCirculatingSupply = "self_reported_circulating_supply"
case selfReportedMarketCap = "self_reported_market_cap"
case quote
}
}
struct Quote: Codable {
let usd: Usd
enum CodingKeys: String, CodingKey {
case usd = "USD"
}
}
struct Usd: Codable {
let price, volume24H, volumeChange24H, percentChange1H: Double
let percentChange24H, percentChange7D, percentChange30D, marketCap: Double
let marketCapDominance: Int
let fullyDilutedMarketCap: Double
let lastUpdated: Date
enum CodingKeys: String, CodingKey {
case price
case volume24H = "volume_24h"
case volumeChange24H = "volume_change_24h"
case percentChange1H = "percent_change_1h"
case percentChange24H = "percent_change_24h"
case percentChange7D = "percent_change_7d"
case percentChange30D = "percent_change_30d"
case marketCap = "market_cap"
case marketCapDominance = "market_cap_dominance"
case fullyDilutedMarketCap = "fully_diluted_market_cap"
case lastUpdated = "last_updated"
}
}
struct Status: Codable {
let timestamp: Date
let errorCode: Int
let errorMessage: String
let elapsed, creditCount: Int
enum CodingKeys: String, CodingKey {
case timestamp
case errorCode = "error_code"
case errorMessage = "error_message"
case elapsed
case creditCount = "credit_count"
}
}
From the JSON response you showed in your question here is the way to get values from it:
do {
guard let response = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
print("JSONSerialization Not possible")
return
}
guard let data = response["data"] as? [String: Any] else { return }
guard let btc = data["BTC"] as? [String: Any] else { return }
guard let quote = btc["quote"] as? [String: Any], let usd = quote["USD"] as? [String: Any] else { return }
let id = btc["id"] as? Int ?? 0
let price = usd["price"] as? String ?? ""
print(id) //1
print(price) //20160.67609688202
} catch let error {
print(error.localizedDescription)
}

how to get array from dictionary in swift 3

I don't understand how to get array from dictionary, i have tried in this code but i want get array only content and type
This is my array
{
wsResponse = {
aarti =(
{
content = "";
identifier = "slok_one";
title = 1;
type = "\U092d\U0915\U094d\U0924\U093e\U092e\U0930";
},
{
content = "";
identifier = "slok_two";
title = 2;
type = "\U092d\U0915\U094d\U0924\U093e\U092e\U0930";
},
{
content = "";
identifier = "slok_three";
title = 3;
type = "\U092d\U0915\U094d\U0924\U093e\U092e\U0930";
}
}
);
};
Here is my code
Alamofire.request(url, method: .get, parameters: nil, encoding: JSONEncoding.default)
.responseJSON { response in
if let status = response.response?.statusCode {
switch(status){
case 201:
print("example success")
default:
print("error with response status: \(status)")
}
}
//to get JSON return value
if let array = response.result.value
{
let JSON = array as! NSDictionary
print("\(JSON)")
let response = JSON["wsResponse"] as! NSDictionary
let data = response["aarti"]
}
}
i want array from this ,like content,title,type
thank you in advance
According to the JSON this prints all values in the aarti array:
if let JSON = response.result.value as? [String:Any] {
if let response = JSON["wsResponse"] as? [String:Any],
let aarti = response["aarti"] as? [[String:Any]] {
for item in aarti {
let content = item["content"] as! String
let identifier = item["identifier"] as! String
let title = item["title"] as! Int
let type = item["type"] as! String
print(content, identifier, title, type)
}
}
}
Basically do not use NSDictionary / NSArray in Swift.
If you want to put all content values in an array use flatMap. The line can replace the whole repeat loop.
let contentArray = aarti.flatMap { $0["content"] as? String }
PS: If you are going to create multiple arrays from the values don't do that: Use a custom struct or class
if someone want to get dictionary of array and use it in tableview
declaration:
var list:[Any] = []
and initialisation :
self.list = (self.ListDic?["data"] as! NSArray!) as! [Any]
and use:
let dictObj = self.list[indexPath.row] as! NSDictionary
print("object value: ",dictObj["text"] as! String)

Cannot pass JSON array to array

I am trying to pass my JSON array to an array called array so that I can then query the array with submission_id with value 27 to obtain the safety_rating_id, schedule_job_id, score and submission_id from this JSON https://codeshare.io/UqJMV but I'm being thrown this error
Cannot convert value of type '[JSON]' to expected argument type 'JSON'
Code to pass JSON to array:
var array: [JSON] = []
func getTask(onCompletion: () -> (), onError: ((NSError) -> ())? = nil) {
guard let endPoint = Data.sharedInstance.weeklyEndpoint
else { print("Empty endpoint"); return }
Alamofire.request(.GET, endPoint, encoding: .JSON)
.validate()
.responseJSON { response in
switch response.result {
case .Success:
if let value = response.result.value {
let json = JSON(value)
for (_,subJson):(String, JSON) in json {
if let date = subJson["start_date"].string{
self.date = date
}
if let building = subJson["building_name"].string{
self.building = building
}
if let jobId = subJson["schedule_job_id"].int {
self.jobIdArray.append(jobId)
}
if let tasks = subJson["tasks"].array{
Tasks.sharedInstance.datas = tasks
for building in tasks {
if let ratings = building["safety_ratings"].array{
print(ratings)
self.array.append(ratings)
}
}
}
}
onCompletion()
}
case .Failure(let error):
print("Request failed with error: \(error)")
onError?(error)
}
}
}
append() expects a single element (JSON), but ratings is an array ([JSON]).
That's what the error message says.
To append an array use appendContentsOf:
self.array.appendContentsOf(ratings)

json missing fields swift

So I have a function that pulls data from a json file and parses it. Its throwing me a nil error because some of the json entries don't have the "colors" field/array. How would i account for this and put in "ERROR" as the text for the ones that didn't.
func getData2(){
let dataPath = NSBundle.mainBundle().pathForResource("cardata", ofType: "json")
if let JSONData = NSData(contentsOfFile: dataPath!)
{
do
{
if let dictionariesArray = try NSJSONSerialization.JSONObjectWithData(JSONData, options: NSJSONReadingOptions()) as?
[[String: AnyObject]]
{
for dictionary in dictionariesArray
{
let name = dictionary["name"] as! String
let type = dictionary["type"] as! String
let text = String(dictionary["text"])
if let printingsArray = dictionary["colors"] as? [String]
{
let printingsString = String(printingsArray.joinWithSeparator("-"))
nameColor[name] = printingsString
}
nameType[name] = type
nameText[name] = text
}
}
}
catch
{
print("Could not parse file at")
}
}
struct Card {
let name: String
let type: String
let colorr: String
let textt: String
init(name: String, type: String, textt: String, colorr:String) {
self.name = name
self.type = type
self.textt = textt
self.colorr = colorr
}
}
var goodCard = [Card]()
for (cardName, cardType) in nameType {
let cardText = nameText[cardName]!
let cardColor = nameColor[cardName]! //fatal error: unexpectedly found nil while unwrapping an Optional value
goodCard.append(Card(name: cardName, type: cardType, textt: cardText, colorr: cardColor))
}
if typee != "" {
let redDogs = goodCard.filter {$0.type == typee}
print(redDogs)
}
You should avoid using the forced unwrapping operator ! whenever possible. If you use it and the Optional is nil then when you use the variable it will throw an exception. Instead use optional binding to unwrap the value:
// optional binding
if let cardColor = nameColor[cardName] {
// do something with the value
}

Resources