How to display JSON data from API? [duplicate] - ios

This question already has an answer here:
Expected to decode Array<Any> but found a dictionary instead
(1 answer)
Closed 4 years ago.
I am developing in Swift 4 and currently using Walmart's API in order to display their products and certain information about the products (example: name of product, price of product). I have read and watched many tutorials regarding parsing JSON data however I continue to get the same error. If anyone could tell me why im getting an error it would be highly appreciated seeing I have been stuck on this issue for days.
Here is the JSON data I am getting from the API call:
{
query: "ipod",
sort: "relevance",
format: "json",
responseGroup: "base",
totalResults: 3570,
start: 1,
numItems: 10,
items: [
{
itemId: 15076191,
parentItemId: 15076191,
name: "Apple iPod Touch 4th Generation 32GB with Bonus Accessory Kit",
salePrice: 189
}
I just want to display the name and salePrice data but I am unable to do so at the moment, instead I get this error: typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))
Here is my data model:
struct Product: Codable {
let name: String
let salePrice: String
}
Here is the code in my ViewController class:
class ViewController: UIViewController {
import Foundation
import UIKit
var products: [Product]?
override func viewDidLoad() {
super.viewDidLoad()
let urlString = "http://api.walmartlabs.com/v1/search?query=sauce&format=json&apiKey=xyz"
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 {
//Decode retrived data with JSONDecoder and assing type of Article object
let productData = try JSONDecoder().decode([Product].self, from: data)
print(productData)
} catch let jsonError {
print(jsonError)
}
}.resume()
}
}

It will be like this,
struct Item: Codable {
let query: String
let sort: String
let responseGroup: String
let totalResults: Int
let start: Int
let numItems: Int
let items: [Product]
}
struct Product: Codable {
let name: String
let salePrice: CGFloat
}
Try using this,
let productData = try JSONDecoder().decode(Item.self, from: data)

Your json data is a dictionary not an array you either parse it and get the array , or try this
struct Item: Codable {
let query: String
let sort: String
let format: String
let responseGroup: String
let totalResults: Int
let start: Int
let numItems: Int
let items: [Product]
}
struct Product: Codable {
let itemId: Double
let parentItemId: Double
let name: String
let salePrice: Int
}
let productData = try JSONDecoder().decode(Item.self, from: data)

Related

JSON Decoding error pops up, dunno what else to try

guys, I would really appreciate some help with JSON decoding. I am trying get API from this link: http://newsapi.org/v2/top-headlines?apiKey=a16b15f863454928804e218705d0f019+&country=us
I might have made some really amateur mistakes. First time uploading a problem here. TY for help!
Here is my DataManager
protocol NewsManagerDelegate {
func didUpdateNews(news: NewsModel)
}
import Foundation
struct NewsManager{
var delegate: NewsManagerDelegate?
let url = "https://newsapi.org/v2/top-headlines?apiKey=a16b15f863454928804e218705d0f019"
func fetchNews(_ countryName: String){
let newsUrlString = "\(url)+&country=\(countryName)"
performRequest(newsUrlString)
}
func performRequest(_ urlString: String){
if let url = URL(string: urlString){
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil {
print("networking error \(error!)")
return
}
if let safeData = data{
if let news = parseJSON(safeData){
delegate?.didUpdateNews(news: news)
}
}
}
task.resume()
}
}
func parseJSON(_ newsData: Data) -> NewsModel?{
do{
let decodedData = try JSONDecoder().decode(NewsData.self, from: newsData)
let sourceName = decodedData.articles[5].source.name
let titleName = decodedData.articles[5].title
let linkToImage = decodedData.articles[5].urlToImage
let news = NewsModel(sourceName: sourceName, titleName: titleName, linkToImage: linkToImage )
return news
}catch{
print(error)
return nil
}
}
}
and my Data
import Foundation
struct NewsData: Codable {
let totalResults: Int
let articles: [Articles]
}
struct Articles: Codable{
let author: String?
let title: String
let description: String
let urlToImage: String
let source: Source
}
struct Source: Codable{
let name: String
}
I am receiving this error
valueNotFound(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "articles", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "description", intValue: nil)], debugDescription: "Expected String value but found null instead.", underlyingError: nil))
I tried to make some of the constants optional but after that no info would show up at all.
I would just change the property name to articleDescription and make it optional. If you would like to parse the publishedAt date all you need is to set decoder dateDecodingStrategy property to .iso8601. Besides that you are not constructing your url correctly. You should always use URLComponents when composing your url and change your urls properties types from String to URL:
struct Root: Codable {
let status: String
let totalResults: Int
let articles: [Article]
}
struct Article: Codable {
let source: Source
let author: String?
let title: String
let articleDescription: String?
let url, urlToImage: URL
let publishedAt: Date
let content: String?
enum CodingKeys: String, CodingKey {
case source, author, title, articleDescription = "description", url, urlToImage, publishedAt, content
}
}
struct Source: Codable {
let id: String?
let name: String
}
Playground testing:
func fetchNews(_ countryCode: String) {
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = "newsapi.org"
urlComponents.path = "/v2/top-headlines"
urlComponents.queryItems = [.init(name: "apiKey", value: "a16b15f863454928804e218705d0f019"),
.init(name:"country", value: countryCode)]
if let url = urlComponents.url {
performRequest(url)
}
}
func performRequest(_ url: URL) {
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else {
print("networking error", error ?? "nil")
return
}
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let root = try decoder.decode(Root.self, from: data)
let articles = root.articles
for article in articles {
print("article:", article, terminator: "\n")
}
} catch {
print(error)
}
}.resume()
}
fetchNews("us")
This will print:
article: Article(source: __lldb_expr_111.Source(id: Optional("cnn"), name: "CNN"), author: Optional("Oliver Darcy, CNN Business"), title: "Tucker Carlson backlash tells us something important about some Trump supporters - CNN", articleDescription: nil, url: https://www.cnn.com/2020/11/21/media/tucker-carlson-fox-news-traitor/index.html, urlToImage: https://cdn.cnn.com/cnnnext/dam/assets/201105014450-tucker-carlson-fox-news-presidential-election-fraud-super-tease.jpg, publishedAt: 2020-11-21 16:11:00 +0000, content: nil)
article: Article(source: __lldb_expr_111.Source(id: Optional("usa-today"), name: "USA Today"), author: Optional("Joel Shannon, Grace Hauck"), title: "Coronavirus updates: Donald Trump Jr. tests positive; model estimates 471k US deaths by March; Cuomo to receive International Emmy - USA TODAY", articleDescription: Optional("Donald Trump Jr. tests positive for the coronavirus. Model predicts more deaths. Thanksgiving during a pandemic happened before. Latest COVID news."), url: https://www.usatoday.com/story/news/health/2020/11/21/covid-news-donald-trump-jr-positive-thanksgiving-travel-not-advised/6367181002/, urlToImage: https://www.gannett-cdn.com/presto/2020/11/21/NSTT/caa3ba8a-8e3c-4b49-82e2-2810caf33d05-Testing3.jpg?crop=1574,886,x0,y80&width=1600&height=800&fit=bounds, publishedAt: 2020-11-21 15:56:15 +0000, content: Optional("A coronavirus vaccine might not be widely available until several months into 2021.\r\nUSA TODAY\r\nThe U.S reported a record high of more than 195,000 new daily cases of COVID-19 Friday, the same week t… [+11662 chars]"))
article: Article(source: __lldb_expr_111.Source(id: nil, name: "CBS Sports"), author: Optional(""), title: "Clemson vs. Florida State game postponed hours before kickoff as teams disagreed about whether to play - CBS Sports", articleDescription: Optional("A Clemson player's late positive test for COVID-19 is the reason for the abrupt postponement"), url: https://www.cbssports.com/college-football/news/clemson-vs-florida-state-game-postponed-hours-before-kickoff-as-teams-disagreed-about-whether-to-play/, urlToImage: https://sportshub.cbsistatic.com/i/r/2019/01/31/3cfd9702-8ef4-4f0d-9cc6-2601f4b3ad9c/thumbnail/1200x675/d00f9bb392291c844de43984526b773e/clemson.jpg, publishedAt: 2020-11-21 15:28:00 +0000, content: Optional("No. 4 Clemson and Florida State were set to kick off at noon ET in Tallahassee, Florida, a game that would have marked Tigers quarterback Trevor Lawrence's return to action following a positive COVID… [+3139 chars]")) ......
articles - description
"Expected String value but found null instead."
Change
let description: String
to
let description: String?
It says there is no value at the first value, can you post the json response what you're getting as that would be useful. Another possibility could be that the json response is in a different order than what you are decoding.
You could just change description to an optional as that would get rid of the problem but then you wouldn't have a description so it doesn't fully solve the problem
let description: String?

Issues with Swift valueNotFound during API Call

I am looking for some help working with a Swift project. I am building an app that pulls aviation weather data from an API and this situation is common:
User wants data from airport weather station KDAB - current report says:
Wind 10 kt
Scattered Clouds 2500 ft
Visibility 10 SM
Light Rain
User wants data from airport weather station KJAX - current report says:
Wind 16 kt
Wind Gust 24 kt
Broken Clouds 1400 ft
Scattered Clouds 1900 ft
Few clouds 2400 ft
In this simple example, you may notice that there is no wind gust data supplied for KJAX during this reporting period and no "special weather" (ie rain, haze, fog) specified for KDAB. My app needs to be able to handle "nil" or not provided data without just telling me that there is a valueNotFound or that the index is out of range.
Here are the API Docs: https://avwx.docs.apiary.io/#reference/0/metar/get-metar-report
Here is my code:
import Foundation
struct WeatherManager {
let weatherURL = "https://avwx.rest/api/metar/"
func fetchWeather (stationICAO: String) {
let urlString = "\(weatherURL)\(stationICAO)?token=OVi45FiTDo1LmyodShfOfoizNe5m9wyuO6Mkc95AN-c"
performRequest(urlString: urlString)
}
func performRequest (urlString: String) {
if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
return
}
if let safeData = data {
self.parseJSON(weatherData: safeData)
}
}
task.resume()
print(urlString)
}
}
func parseJSON(weatherData: Data) {
do {
let decoder = JSONDecoder()
let decodedData = try decoder.decode(WeatherData.self, from: weatherData)
let lowCloudsType = decodedData.clouds[0].type
let midCloudsType = decodedData.clouds[1].type
let highCloudsType = decodedData.clouds[2].type
let lowCloudsAlt = decodedData.clouds[0].altitude
let midCloudsAlt = decodedData.clouds[1].altitude
let highCloudsAlt = decodedData.clouds[2].altitude
let reportingStationVar = decodedData.station
let windGustValue = decodedData.wind_gust.value
let windSpeedValue = decodedData.wind_speed.value
let windDirectionValue = decodedData.wind_direction.value
let visibilityValue = decodedData.visibility.value
let flightRulesValue = decodedData.flight_rules
let weather = WeatherModel(lowestCloudsType: lowCloudsType, lowestCloudsAlt: lowCloudsAlt, middleCloudsType: midCloudsType, middleCloudsAlt: midCloudsAlt, highestCloudsType: highCloudsType, highestCloudsAlt: highCloudsAlt, reportingStation: reportingStationVar, windGust: windGustValue, windSpeed: windSpeedValue, windDirection: windDirectionValue, visibility: visibilityValue, flightRules: flightRulesValue)
print(weather.flightConditions)
} catch {
print(error)
}
}
}
import Foundation
struct WeatherModel {
let lowestCloudsType: String
let lowestCloudsAlt: Int
let middleCloudsType: String
let middleCloudsAlt: Int
let highestCloudsType: String
let highestCloudsAlt: Int
let reportingStation: String
let windGust: Int
let windSpeed: Int
let windDirection: Int
let visibility: Int
let flightRules: String
var flightConditions: String {
switch flightRules {
case "VFR":
return "green"
case "MVFR":
return "blue"
case "IFR":
return "red"
case "LIFR":
return "purple"
default:
return "gray"
}
}
}
Last One:
import Foundation
struct WeatherData: Decodable {
let clouds: [Clouds]
let flight_rules: String
let remarks: String
let wind_speed: WindSpeed
let wind_gust: WindGust
let wind_direction: WindDirection
let visibility: Visibility
let station: String
}
struct Clouds: Decodable {
let type: String
let altitude: Int
}
struct WindSpeed: Decodable {
let value: Int
}
struct WindGust: Decodable {
let value: Int
}
struct WindDirection: Decodable {
let value: Int
}
struct Visibility: Decodable {
let value: Int
}
Depending on what I play with, I get the following errors when entering a station that does not have all of that given information that I need to be able to present to the user if reported by the weather service.
2020-09-22 02:47:58.930421-0400 AvWx Pro[66612:4483807] libMobileGestalt MobileGestaltCache.c:38: No persisted cache on this platform.
KDAB
https://avwx.rest/api/metar/KDAB?token=(mySecretToken)
2020-09-22 02:48:02.943231-0400 AvWx Pro[66612:4483809] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed
valueNotFound(Swift.KeyedDecodingContainer<AvWx_Pro.WindGust.(unknown context at $1053fb3b8).CodingKeys>,
Swift.DecodingError.Context(codingPath:
[CodingKeys(stringValue: "wind_gust", intValue: nil)],
debugDescription: "Cannot get keyed decoding container
-- found null value instead.", underlyingError: nil))
A different error when I use an airport that doesn't have all three of the possible cloud layers reported:
2020-09-22 03:06:02.398628-0400 AvWx Pro[66736:4497432] libMobileGestalt MobileGestaltCache.c:38: No persisted cache on this platform.
KJAX
https://avwx.rest/api/metar/KJAX?token=(mySecretKey)
2020-09-22 03:06:07.955064-0400 AvWx Pro[66736:4497429] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed
Fatal error: Index out of range: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1200.2.22.2/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 444
2020-09-22 03:06:08.908826-0400 AvWx Pro[66736:4497429] Fatal error: Index out of range: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1200.2.22.2/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 444
(lldb)
I've spent a few hours now trying various solutions I've found online, including using optionals and force unwrapping, using guard let, using if let, and a few others. I'm pretty lost at the moment.
I am new to this platform (as a poster) and would really appreciate any insight anyone can offer! Thanks for the help in advance.
To avoid crashes while decoding json you should make correct configuration of your structs and check the fields before access values:
Optional fields
[CodingKeys(stringValue: "wind_gust", intValue: nil)],
debugDescription: "Cannot get keyed decoding container -- found null
value instead.", underlyingError: nil))
wind_gust can be empty so you should make it optional:
If a field can be empty or null in responses you should make it optional in your struct e.g.:
struct WeatherData: Decodable {
...
let wind_gust: WindGust?
...
}
Then in your code just use optional binding to extract a value if wind_gust exists:
if let value = decodedData.wind_gust?.value {
print(value)
}
Arrays
Fatal error: Index out of range
You must always check an array's bounds before access to items e.g.:
let clouds = decodedData.clouds
let lowCloudsType = clouds.count > 0 ? clouds[0].type : nil
let midCloudsType = clouds.count > 1 ? clouds[1].type : nil
let highCloudsType = clouds.count > 2 ? clouds[2].type : nil
if let low = lowCloudsType, let mid = midCloudsType, let high = highCloudsType {
print(low)
print(mid)
print(high)
}
The answer is to use Optionals
Consider the below playground example, the age and location properties are optional, the location property is missing from the JSON.
import Foundation
struct TestModel: Decodable {
let name: String
let age: Int?
let location: String?
enum CodingKeys: String, CodingKey {
case name
case age
case location
}
}
let jsonData = """
{
"name": "John Smith",
"age": 28
}
""".data(using: .utf8)!
let result = try JSONDecoder().decode(TestModel.self, from: jsonData)
print(result)
Output
TestModel(name: "John Smith", age: Optional(28), location: nil)

How to parse through JSON with [] brackets?

I'm parsing through JSON on a website like so (under a request.httpMethod = "GET" in Swift
):
let example = json.data.first?.TShirtPrice
The JSON I'm getting is structured like so
{"returned":1,"data":[{"TShirtPrice":"5"}]}
But I have a new JSON set that is structured without [] brackets like so:
{"returned":1,"base":"USD","data":{"TShirtPrice":"3.448500"}}
The same exact code doesn't let me get the price of the shirt anymore -- what is the fix? Thank you!
This is my code
if let data = data {
do {
let json = try JSONDecoder().decode(Root.self,from: data)
let price = json.data.first?.TShirtPrice
struct Root: Codable {
let data: [Datum]
}
struct Datum: Codable {
let TShirtPrice: String
}
Assuming your data model is something as follows You can be using Struct or Class it's not an issue.
struct Root: Decodable {
let returned: Int?
let base: String?
let data: Price?
}
struct Price: Codable {
let TShirtPrice: String?
}
Sample JSON Sting is as follows
let jsonString = """
{
"returned": 1,
"base": "USD",
"data": {
"TShirtPrice": "3.448500"
}
}
"""
You just have to change the way data is parsed by making change in data model as given above and way to access the data as given below
if let data = jsonString.data(using: .utf8) {
let myObject = try JSONDecoder().decode(Root.self, from: data)
print(myObject.data?.TShirtPrice)
}
In your case it will look like this
if let data = data {
do {
let json = try JSONDecoder().decode(Root.self,from: data)
let Price = json.data?.TShirtPrice
}
}
What is changed here?
As your price data was in format of Array the code was written accordingly and as per new data it's not an Array anymore so you have to adapt those changes app side also.

how to add Json value into model Array to display into tableview in swift

I'm using the tableview to display the Two Json value but the problem is I cant add value into model struct to displaying into tableview using two Api's. i want to show percentage value in one of the cell label and
here is my json
[
{
"Percentage": 99.792098999,
}
]
my second json value
{
"Categories": [
"Developer",
"ios "
],
"Tags": [
{
"Value": "kishore",
"Key": "Name"
},
{
"Value": "2",
"Key": "office"
},
]
}
and i need show the Categories value in Categories label in tableview
value and key on tableview
here is my Struct
struct info: Decodable {
let Categories: String?
let Tags: String?
let Value: String?
let Key: String?
var Name: String?
let percentage: Double?
}
here its my code
var List = [info]()
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
print(json as Any)
guard let jsonArray = json as? [[String: Any]] else {
return
}
print(jsonArray)
for dic in jsonArray{
guard let per = dic["percentage"] as? Double else { return }
print(per)
}
and second json
if let array = json["Tags"] as? [[String: String]] {
for dict in array {
let key = dict["Key"]
let value = dict["Value"]
switch key {
case "office":
case "Name":
default:
break;
}
}
here is my cell for row indexpath
cell.Categories.text = list[indexpath.row].percentage
cell.Name.text = list[indexpath.row].name
cell.office.text = list[indexpath.row].office
Please use Swift 4 Codable protocol to decode the value from JSON.
//1.0 Create your structures and make it conform to Codable Protocol
struct Tags: Codable{
var Key: String
var Value: String
}
struct Sample: Codable{
var Categories: [String]
var Tags: [Tags]
}
In your method, perform below steps:
//2.0 Get your json data from your API. In example below, i am reading from a JSON file named "Sample.json"
if let path = Bundle.main.path(forResource: "Sample", ofType: "json") {
do {
let jsonData = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
do {
//3.0 use JSONDecoder's decode method to decode JSON to your model.
let sample = try JSONDecoder().decode(Sample.self, from: jsonData)
//4.0 User the "sample" model to do your stuff. Example, printing some values
print("Sample.Category = \(sample.Categories)")
print("Sample.Name = \(sample.Tags[0].Value)")
print("Sample.Office = \(sample.Tags[1].Value)")
} catch let error {
print("Error = \(error)")
}
} catch {
// handle error
}
}
I prefer to use Codable all the time with JSON even for simpler types so for percentage I would do
struct ItemElement: Decodable {
let percentage: Double
enum CodingKeys: String, CodingKey {
case percentage = "Percentage"
}
}
and we need to keep these values in a separate array, declared as a class property
let percentageList: [Double]()
and json encoding would then be
let decoder = JSONDecoder()
do {
let result = try decoder.decode([ItemElement].self, from: data)
percentageList = result.map { item.percentage }
} catch {
print(error)
}
Similar for the second part
struct Item: Decodable {
let categories: [String]
let tags: [Tag]
enum CodingKeys: String, CodingKey {
case categories = "Categories"
case tags = "Tags"
}
}
struct Tag: Decodable {
let value, key: String
enum CodingKeys: String, CodingKey {
case value = "Value"
case key = "Key"
}
}
use a dictionary for the result, again as a class property
var values = [String: String]()
and the decoding
let decoder = JSONDecoder()
do {
let result = try decoder.decode(Item.self, from: data)
for item in result.tags {
values[item.key] = values.item.value
}
} catch {
print(error)
}
and then in the cell for row code
cell.Categories.text = percentageList[indexpath.row].percentage
cell.Name.text = values["name"]
cell.office.text = values["office"]
Note that this last code looks very strange since you don't have an array of name/office values judging by your json. Maybe you have simplified it some way but the code above is the best I can do with the information given even if it possibly wrong

Nested Json data fetch and append problem using swiftyjson library swift

Getting data append problem in nested json by using swiftjson library swift.
I have created two struct but getting an error while appending the final list. Error in getting when appending data. Have i created struct well.
My struct
struct GistModel {
var comments : Int!
var commentsUrl : String!
var descriptionField : String!
var owner : Owner!
}
struct Owner{
var login : String!
}
JSON DATA result:
{
url: "https://api.github.com/gists/7e624eed62b3a317541791d719dcacf2",
forks_url: "https://api.github.com/gists/7e624eed62b3a317541791d719dcacf2/forks",
commits_url: "https://api.github.com/gists/7e624eed62b3a317541791d719dcacf2/commits",
id: "7e624eed62b3a317541791d719dcacf2",
node_id: "MDQ6R2lzdDdlNjI0ZWVkNjJiM2EzMTc1NDE3OTFkNzE5ZGNhY2Yy",
git_pull_url: "https://gist.github.com/7e624eed62b3a317541791d719dcacf2.git",
git_push_url: "https://gist.github.com/7e624eed62b3a317541791d719dcacf2.git",
html_url: "https://gist.github.com/7e624eed62b3a317541791d719dcacf2",
files: 
 {
GistTest2: 
 {
filename: "GistTest2",
type: "text/plain",
language: null,
raw_url: "https://gist.githubusercontent.com/MasamMahmood/7e624eed62b3a317541791d719dcacf2/raw/7302f0d923e9e08b0e502ad9df762a1b2aa072e1/GistTest2",
size: 29
}
},
public: true,
created_at: "2019-02-01T18:41:39Z",
updated_at: "2019-02-01T19:01:16Z",
description: "Gist Test 2",
comments: 0,
user: null,
comments_url: "https://api.github.com/gists/7e624eed62b3a317541791d719dcacf2/comments",
owner: 
 {
login: "MasamMahmood",
id: 36441313,
node_id: "MDQ6VXNlcjM2NDQxMzEz",
avatar_url: "https://avatars3.githubusercontent.com/u/36441313?v=4",
gravatar_id: "",
url: "https://api.github.com/users/MasamMahmood",
html_url: "https://github.com/MasamMahmood",
followers_url: "https://api.github.com/users/MasamMahmood/followers",
following_url: "https://api.github.com/users/MasamMahmood/following{/other_user}",
gists_url: "https://api.github.com/users/MasamMahmood/gists{/gist_id}",
starred_url: "https://api.github.com/users/MasamMahmood/starred{/owner}{/repo}",
subscriptions_url: "https://api.github.com/users/MasamMahmood/subscriptions",
organizations_url: "https://api.github.com/users/MasamMahmood/orgs",
repos_url: "https://api.github.com/users/MasamMahmood/repos",
events_url: "https://api.github.com/users/MasamMahmood/events{/privacy}",
received_events_url: "https://api.github.com/users/MasamMahmood/received_events",
type: "User",
site_admin: false
},
truncated: false
}
Swift:
switch response.result{
case .success(let value):
let json = JSON(value)
print(json)
for subJson in json.arrayValue {
let comm = subJson["comments"].intValue
let commurl = subJson["comments_url"].stringValue
let desc = subJson["description"].string
//let age = subJson["owner"]["login"].string
for item in subJson{
let login = subJson["owner"]["login"].string
// do something
}
let user = GistModel(comments: comm, commentsUrl: commurl, descriptionField: desc, login: login)//, owner: login)
self.DataList.append(user)
print(user)
}
I am newbie Getting error on append the list. "Use of unresolved identifier 'login'".
If you are willing to move to standard json handling using Codable then this will work. First let structs implement Decodable
struct GistModel: Decodable {
let comments: Int
let commentsUrl: String
let description: String //Changed the name here
let owner: Owner
}
struct Owner: Decodable {
let login: String
}
And encoding is done like this
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode([GistModel].self, from: data)
print(result[0].owner.login)
print(result[0].comments)
print(result[0].commentsUrl)
} catch {
print(error)
}

Resources