Decoding JSON to Swift Model Not Root Level
I have the following model:
struct Article: Decodable {
let title: String
let description: String
let imageURL: String
private enum CodingKeys: String, CodingKey {
case title
case description
case imageURL = "urlToImage"
}
}
The JSON coming from URL is like this:
{
status: "ok",
totalResults: 70,
articles: [
{
source: {
id: null,
name: "Oilprice.com"
},
author: "Tim Daiss",
title: "$70 Oil Could Be Right Around The Corner | OilPrice.com - OilPrice.com",
description: "A recent Bloomberg survey of oil analysts suggests that many believe oil could hit $70 per barrel in 2019, but are they just downplaying the bearish signals?",
url: "https://oilprice.com/Energy/Crude-Oil/70-Oil-Could-Be-Right-Around-The-Corner.html",
urlToImage: "https://d32r1sh890xpii.cloudfront.net/article/718x300/d7b8868e80d766d6a5d401219c65d6a0.jpg",
publishedAt: "2019-01-01T00:00:08Z",
content: "Oil markets have always been cyclical, and now even more so with advanced electronic trading, more speculation (which often results in wider oil price swings) and more producers, including the resurgence of U.S. oil production, now reaching over 11 million ba… [+4696 chars]"
},
{
source: {
id: "cnbc",
name: "CNBC"
},
author: "Jordan Novet",
title: "Activision Blizzard plans to fire its CFO for an unspecified cause - CNBC",
description: "Shares of gaming company Activision Blizzard moved lower Monday after it announced plans to let go of its chief financial officer.",
url: "https://www.cnbc.com/2018/12/31/activision-blizzard-plans-to-fire-its-cfo-for-an-unspecified-cause.html",
urlToImage: "https://fm.cnbc.com/applications/cnbc.com/resources/img/editorial/2012/08/02/48465125-activision-200.1910x1000.jpg",
publishedAt: "2018-12-31T23:18:17Z",
content: "Activision Blizzard shares moved down 1 percent in after-hours trading on Monday after the company said that it has informed its chief financial officer, Spencer Neumann, that it plans to let him go. For now he has been placed on a paid leave of absence. div … [+950 chars]"
},
All I want is the value in articles key. How can I get it using Swift 4 JSONDecoder.
I know how to do it by creating a parent struct and then creating "articles" property inside the parent. But how can I do that without the parent struct.
swift jsondecoder
add a comment |
I have the following model:
struct Article: Decodable {
let title: String
let description: String
let imageURL: String
private enum CodingKeys: String, CodingKey {
case title
case description
case imageURL = "urlToImage"
}
}
The JSON coming from URL is like this:
{
status: "ok",
totalResults: 70,
articles: [
{
source: {
id: null,
name: "Oilprice.com"
},
author: "Tim Daiss",
title: "$70 Oil Could Be Right Around The Corner | OilPrice.com - OilPrice.com",
description: "A recent Bloomberg survey of oil analysts suggests that many believe oil could hit $70 per barrel in 2019, but are they just downplaying the bearish signals?",
url: "https://oilprice.com/Energy/Crude-Oil/70-Oil-Could-Be-Right-Around-The-Corner.html",
urlToImage: "https://d32r1sh890xpii.cloudfront.net/article/718x300/d7b8868e80d766d6a5d401219c65d6a0.jpg",
publishedAt: "2019-01-01T00:00:08Z",
content: "Oil markets have always been cyclical, and now even more so with advanced electronic trading, more speculation (which often results in wider oil price swings) and more producers, including the resurgence of U.S. oil production, now reaching over 11 million ba… [+4696 chars]"
},
{
source: {
id: "cnbc",
name: "CNBC"
},
author: "Jordan Novet",
title: "Activision Blizzard plans to fire its CFO for an unspecified cause - CNBC",
description: "Shares of gaming company Activision Blizzard moved lower Monday after it announced plans to let go of its chief financial officer.",
url: "https://www.cnbc.com/2018/12/31/activision-blizzard-plans-to-fire-its-cfo-for-an-unspecified-cause.html",
urlToImage: "https://fm.cnbc.com/applications/cnbc.com/resources/img/editorial/2012/08/02/48465125-activision-200.1910x1000.jpg",
publishedAt: "2018-12-31T23:18:17Z",
content: "Activision Blizzard shares moved down 1 percent in after-hours trading on Monday after the company said that it has informed its chief financial officer, Spencer Neumann, that it plans to let him go. For now he has been placed on a paid leave of absence. div … [+950 chars]"
},
All I want is the value in articles key. How can I get it using Swift 4 JSONDecoder.
I know how to do it by creating a parent struct and then creating "articles" property inside the parent. But how can I do that without the parent struct.
swift jsondecoder
stackoverflow.com/questions/38864579/…
– impression7vx
Jan 1 at 1:51
@impression7vx That is old way of doing things. I am looking for JSONDecoder way.
– john doe
Jan 1 at 1:53
1
I see. You are trying to parse a portion of it instead of the whole thing. Interesting. Wouldn't you want a parent struct so you can usetotalResults
as well asstatus
?
– impression7vx
Jan 1 at 2:11
"The JSON coming from URL is like this" No, it isn't. What you've shown is not valid JSON.
– matt
Jan 1 at 5:53
1
Using JSONDecoder alone, you cannot decode without some sort of outer struct, because your result is going to be an array of Article, which is an outer entity. Merely defining Article alone thus can never be sufficient.
– matt
Jan 1 at 6:53
add a comment |
I have the following model:
struct Article: Decodable {
let title: String
let description: String
let imageURL: String
private enum CodingKeys: String, CodingKey {
case title
case description
case imageURL = "urlToImage"
}
}
The JSON coming from URL is like this:
{
status: "ok",
totalResults: 70,
articles: [
{
source: {
id: null,
name: "Oilprice.com"
},
author: "Tim Daiss",
title: "$70 Oil Could Be Right Around The Corner | OilPrice.com - OilPrice.com",
description: "A recent Bloomberg survey of oil analysts suggests that many believe oil could hit $70 per barrel in 2019, but are they just downplaying the bearish signals?",
url: "https://oilprice.com/Energy/Crude-Oil/70-Oil-Could-Be-Right-Around-The-Corner.html",
urlToImage: "https://d32r1sh890xpii.cloudfront.net/article/718x300/d7b8868e80d766d6a5d401219c65d6a0.jpg",
publishedAt: "2019-01-01T00:00:08Z",
content: "Oil markets have always been cyclical, and now even more so with advanced electronic trading, more speculation (which often results in wider oil price swings) and more producers, including the resurgence of U.S. oil production, now reaching over 11 million ba… [+4696 chars]"
},
{
source: {
id: "cnbc",
name: "CNBC"
},
author: "Jordan Novet",
title: "Activision Blizzard plans to fire its CFO for an unspecified cause - CNBC",
description: "Shares of gaming company Activision Blizzard moved lower Monday after it announced plans to let go of its chief financial officer.",
url: "https://www.cnbc.com/2018/12/31/activision-blizzard-plans-to-fire-its-cfo-for-an-unspecified-cause.html",
urlToImage: "https://fm.cnbc.com/applications/cnbc.com/resources/img/editorial/2012/08/02/48465125-activision-200.1910x1000.jpg",
publishedAt: "2018-12-31T23:18:17Z",
content: "Activision Blizzard shares moved down 1 percent in after-hours trading on Monday after the company said that it has informed its chief financial officer, Spencer Neumann, that it plans to let him go. For now he has been placed on a paid leave of absence. div … [+950 chars]"
},
All I want is the value in articles key. How can I get it using Swift 4 JSONDecoder.
I know how to do it by creating a parent struct and then creating "articles" property inside the parent. But how can I do that without the parent struct.
swift jsondecoder
I have the following model:
struct Article: Decodable {
let title: String
let description: String
let imageURL: String
private enum CodingKeys: String, CodingKey {
case title
case description
case imageURL = "urlToImage"
}
}
The JSON coming from URL is like this:
{
status: "ok",
totalResults: 70,
articles: [
{
source: {
id: null,
name: "Oilprice.com"
},
author: "Tim Daiss",
title: "$70 Oil Could Be Right Around The Corner | OilPrice.com - OilPrice.com",
description: "A recent Bloomberg survey of oil analysts suggests that many believe oil could hit $70 per barrel in 2019, but are they just downplaying the bearish signals?",
url: "https://oilprice.com/Energy/Crude-Oil/70-Oil-Could-Be-Right-Around-The-Corner.html",
urlToImage: "https://d32r1sh890xpii.cloudfront.net/article/718x300/d7b8868e80d766d6a5d401219c65d6a0.jpg",
publishedAt: "2019-01-01T00:00:08Z",
content: "Oil markets have always been cyclical, and now even more so with advanced electronic trading, more speculation (which often results in wider oil price swings) and more producers, including the resurgence of U.S. oil production, now reaching over 11 million ba… [+4696 chars]"
},
{
source: {
id: "cnbc",
name: "CNBC"
},
author: "Jordan Novet",
title: "Activision Blizzard plans to fire its CFO for an unspecified cause - CNBC",
description: "Shares of gaming company Activision Blizzard moved lower Monday after it announced plans to let go of its chief financial officer.",
url: "https://www.cnbc.com/2018/12/31/activision-blizzard-plans-to-fire-its-cfo-for-an-unspecified-cause.html",
urlToImage: "https://fm.cnbc.com/applications/cnbc.com/resources/img/editorial/2012/08/02/48465125-activision-200.1910x1000.jpg",
publishedAt: "2018-12-31T23:18:17Z",
content: "Activision Blizzard shares moved down 1 percent in after-hours trading on Monday after the company said that it has informed its chief financial officer, Spencer Neumann, that it plans to let him go. For now he has been placed on a paid leave of absence. div … [+950 chars]"
},
All I want is the value in articles key. How can I get it using Swift 4 JSONDecoder.
I know how to do it by creating a parent struct and then creating "articles" property inside the parent. But how can I do that without the parent struct.
swift jsondecoder
swift jsondecoder
asked Jan 1 at 1:32
john doejohn doe
2,963104296
2,963104296
stackoverflow.com/questions/38864579/…
– impression7vx
Jan 1 at 1:51
@impression7vx That is old way of doing things. I am looking for JSONDecoder way.
– john doe
Jan 1 at 1:53
1
I see. You are trying to parse a portion of it instead of the whole thing. Interesting. Wouldn't you want a parent struct so you can usetotalResults
as well asstatus
?
– impression7vx
Jan 1 at 2:11
"The JSON coming from URL is like this" No, it isn't. What you've shown is not valid JSON.
– matt
Jan 1 at 5:53
1
Using JSONDecoder alone, you cannot decode without some sort of outer struct, because your result is going to be an array of Article, which is an outer entity. Merely defining Article alone thus can never be sufficient.
– matt
Jan 1 at 6:53
add a comment |
stackoverflow.com/questions/38864579/…
– impression7vx
Jan 1 at 1:51
@impression7vx That is old way of doing things. I am looking for JSONDecoder way.
– john doe
Jan 1 at 1:53
1
I see. You are trying to parse a portion of it instead of the whole thing. Interesting. Wouldn't you want a parent struct so you can usetotalResults
as well asstatus
?
– impression7vx
Jan 1 at 2:11
"The JSON coming from URL is like this" No, it isn't. What you've shown is not valid JSON.
– matt
Jan 1 at 5:53
1
Using JSONDecoder alone, you cannot decode without some sort of outer struct, because your result is going to be an array of Article, which is an outer entity. Merely defining Article alone thus can never be sufficient.
– matt
Jan 1 at 6:53
stackoverflow.com/questions/38864579/…
– impression7vx
Jan 1 at 1:51
stackoverflow.com/questions/38864579/…
– impression7vx
Jan 1 at 1:51
@impression7vx That is old way of doing things. I am looking for JSONDecoder way.
– john doe
Jan 1 at 1:53
@impression7vx That is old way of doing things. I am looking for JSONDecoder way.
– john doe
Jan 1 at 1:53
1
1
I see. You are trying to parse a portion of it instead of the whole thing. Interesting. Wouldn't you want a parent struct so you can use
totalResults
as well as status
?– impression7vx
Jan 1 at 2:11
I see. You are trying to parse a portion of it instead of the whole thing. Interesting. Wouldn't you want a parent struct so you can use
totalResults
as well as status
?– impression7vx
Jan 1 at 2:11
"The JSON coming from URL is like this" No, it isn't. What you've shown is not valid JSON.
– matt
Jan 1 at 5:53
"The JSON coming from URL is like this" No, it isn't. What you've shown is not valid JSON.
– matt
Jan 1 at 5:53
1
1
Using JSONDecoder alone, you cannot decode without some sort of outer struct, because your result is going to be an array of Article, which is an outer entity. Merely defining Article alone thus can never be sufficient.
– matt
Jan 1 at 6:53
Using JSONDecoder alone, you cannot decode without some sort of outer struct, because your result is going to be an array of Article, which is an outer entity. Merely defining Article alone thus can never be sufficient.
– matt
Jan 1 at 6:53
add a comment |
3 Answers
3
active
oldest
votes
Using JSONDecoder alone, you cannot decode without some sort of outer struct, because your result is going to be an array of Article, which is an outer entity. Merely defining Article alone thus can never be sufficient.
If you dislike declaring an outer struct that you don't need for any other purpose than to drill down to the "articles"
key, that is easily solved by declaring it only temporarily within the limited scope where you do drill down to the "articles"
key. The rest of your program is thus left with the Article struct but the outer struct doesn't exist there.
For example:
struct Article: Decodable {
// ... your code here ...
}
func getArticles(_ d:Data) -> [Article] {
struct Articles: Decodable { // this struct is temporary
let articles:[Article]
}
return try! JSONDecoder().decode(Articles.self, from: d).articles
}
Other code can now see the Article struct and can call getArticles
to parse the JSON and receive the array of Article, but other code never knows (and can never find out) that an extra Articles struct exist; it exists only temporarily within the getArticles
function as a kind of local. It is no more objectionable than any other local variable created temporarily within a function body.
add a comment |
You can try to combine JSONSerialization
with JSONDecoder
do
{
let tr = try JSONSerialization.jsonObject(with:data, options:) as! [String:Any]
guard let content = tr["articles"] else { return }
let articlesData = try JSONSerialization.data(withJSONObject:content, options: )
let res = try JSONDecoder().decode([Article].self, from: articlesData)
print(res)
}
catch
{
print(error)
}
add a comment |
Consider restructuring your Data. You need to structure your data model to match the data structure of the JSON data. You can include only what you want but you must include every parent or level of the property(s) you want to access. Take the following example from the wikipedia API. It prints out the title property that's three levels deep into the JSON data structure. It leaves out several properties as you can tell from the JSON example code but it includes every parent I need to access the property(s) I want.
import UIKit
struct Item: Decodable {
var title: String
}
struct Search: Decodable {
var search: [Item]
}
struct Result: Decodable {
var query: Search
}
func getSearchResults(){
let url = URL(string: "https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=swift%204&utf8=&format=json")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let urlResponse = response as? HTTPURLResponse, urlResponse.statusCode == 200 {
guard let data = data else { return }
do {
let results = try JSONDecoder().decode(Result.self, from: data)
for item in results.query.search {
print(item.title)
}
} catch let error as NSError {
print("error: (error)")
}
}
}.resume()
}
getSearchResults()
JSON Example:
{
"batchcomplete": "",
"continue": {
"sroffset": 10,
"continue": "-||"
},
"query": {
"searchinfo": {
"totalhits": 30349
},
"search": [
{
"ns": 0,
"title": "Swift",
"pageid": 219023,
"size": 13896,
"wordcount": 1496,
"snippet": "The <span class="searchmatch">swifts</span> are a family, Apodidae, of highly aerial birds. They are superficially similar to swallows, but are not closely related to any passerine species",
"timestamp": "2018-12-28T21:29:44Z"
},
{
"ns": 0,
"title": "Swift (programming language)",
"pageid": 42946389,
"size": 49365,
"wordcount": 5244,
"snippet": "2015. <span class="searchmatch">Swift</span> 3.0 was released on September 13, 2016. <span class="searchmatch">Swift</span> <span class="searchmatch">4</span>.0 was released on September 19, 2017. <span class="searchmatch">Swift</span> <span class="searchmatch">4</span>.1 was released on March 29, 2018. <span class="searchmatch">Swift</span> won first",
"timestamp": "2018-12-19T02:52:33Z"
},
{
"ns": 0,
"title": "Taylor Swift",
"pageid": 5422144,
"size": 237225,
"wordcount": 18505,
"snippet": "Taylor Alison <span class="searchmatch">Swift</span> (born December 13, 1989) is an American singer-songwriter. One of the world's leading contemporary recording artists, she is known",
"timestamp": "2018-12-26T21:55:51Z"
},
This is the output of the print:
//Swift
//Swift (programming language)
//Taylor Swift
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53992522%2fdecoding-json-to-swift-model-not-root-level%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Using JSONDecoder alone, you cannot decode without some sort of outer struct, because your result is going to be an array of Article, which is an outer entity. Merely defining Article alone thus can never be sufficient.
If you dislike declaring an outer struct that you don't need for any other purpose than to drill down to the "articles"
key, that is easily solved by declaring it only temporarily within the limited scope where you do drill down to the "articles"
key. The rest of your program is thus left with the Article struct but the outer struct doesn't exist there.
For example:
struct Article: Decodable {
// ... your code here ...
}
func getArticles(_ d:Data) -> [Article] {
struct Articles: Decodable { // this struct is temporary
let articles:[Article]
}
return try! JSONDecoder().decode(Articles.self, from: d).articles
}
Other code can now see the Article struct and can call getArticles
to parse the JSON and receive the array of Article, but other code never knows (and can never find out) that an extra Articles struct exist; it exists only temporarily within the getArticles
function as a kind of local. It is no more objectionable than any other local variable created temporarily within a function body.
add a comment |
Using JSONDecoder alone, you cannot decode without some sort of outer struct, because your result is going to be an array of Article, which is an outer entity. Merely defining Article alone thus can never be sufficient.
If you dislike declaring an outer struct that you don't need for any other purpose than to drill down to the "articles"
key, that is easily solved by declaring it only temporarily within the limited scope where you do drill down to the "articles"
key. The rest of your program is thus left with the Article struct but the outer struct doesn't exist there.
For example:
struct Article: Decodable {
// ... your code here ...
}
func getArticles(_ d:Data) -> [Article] {
struct Articles: Decodable { // this struct is temporary
let articles:[Article]
}
return try! JSONDecoder().decode(Articles.self, from: d).articles
}
Other code can now see the Article struct and can call getArticles
to parse the JSON and receive the array of Article, but other code never knows (and can never find out) that an extra Articles struct exist; it exists only temporarily within the getArticles
function as a kind of local. It is no more objectionable than any other local variable created temporarily within a function body.
add a comment |
Using JSONDecoder alone, you cannot decode without some sort of outer struct, because your result is going to be an array of Article, which is an outer entity. Merely defining Article alone thus can never be sufficient.
If you dislike declaring an outer struct that you don't need for any other purpose than to drill down to the "articles"
key, that is easily solved by declaring it only temporarily within the limited scope where you do drill down to the "articles"
key. The rest of your program is thus left with the Article struct but the outer struct doesn't exist there.
For example:
struct Article: Decodable {
// ... your code here ...
}
func getArticles(_ d:Data) -> [Article] {
struct Articles: Decodable { // this struct is temporary
let articles:[Article]
}
return try! JSONDecoder().decode(Articles.self, from: d).articles
}
Other code can now see the Article struct and can call getArticles
to parse the JSON and receive the array of Article, but other code never knows (and can never find out) that an extra Articles struct exist; it exists only temporarily within the getArticles
function as a kind of local. It is no more objectionable than any other local variable created temporarily within a function body.
Using JSONDecoder alone, you cannot decode without some sort of outer struct, because your result is going to be an array of Article, which is an outer entity. Merely defining Article alone thus can never be sufficient.
If you dislike declaring an outer struct that you don't need for any other purpose than to drill down to the "articles"
key, that is easily solved by declaring it only temporarily within the limited scope where you do drill down to the "articles"
key. The rest of your program is thus left with the Article struct but the outer struct doesn't exist there.
For example:
struct Article: Decodable {
// ... your code here ...
}
func getArticles(_ d:Data) -> [Article] {
struct Articles: Decodable { // this struct is temporary
let articles:[Article]
}
return try! JSONDecoder().decode(Articles.self, from: d).articles
}
Other code can now see the Article struct and can call getArticles
to parse the JSON and receive the array of Article, but other code never knows (and can never find out) that an extra Articles struct exist; it exists only temporarily within the getArticles
function as a kind of local. It is no more objectionable than any other local variable created temporarily within a function body.
edited Jan 1 at 20:33
answered Jan 1 at 2:41
mattmatt
328k46531732
328k46531732
add a comment |
add a comment |
You can try to combine JSONSerialization
with JSONDecoder
do
{
let tr = try JSONSerialization.jsonObject(with:data, options:) as! [String:Any]
guard let content = tr["articles"] else { return }
let articlesData = try JSONSerialization.data(withJSONObject:content, options: )
let res = try JSONDecoder().decode([Article].self, from: articlesData)
print(res)
}
catch
{
print(error)
}
add a comment |
You can try to combine JSONSerialization
with JSONDecoder
do
{
let tr = try JSONSerialization.jsonObject(with:data, options:) as! [String:Any]
guard let content = tr["articles"] else { return }
let articlesData = try JSONSerialization.data(withJSONObject:content, options: )
let res = try JSONDecoder().decode([Article].self, from: articlesData)
print(res)
}
catch
{
print(error)
}
add a comment |
You can try to combine JSONSerialization
with JSONDecoder
do
{
let tr = try JSONSerialization.jsonObject(with:data, options:) as! [String:Any]
guard let content = tr["articles"] else { return }
let articlesData = try JSONSerialization.data(withJSONObject:content, options: )
let res = try JSONDecoder().decode([Article].self, from: articlesData)
print(res)
}
catch
{
print(error)
}
You can try to combine JSONSerialization
with JSONDecoder
do
{
let tr = try JSONSerialization.jsonObject(with:data, options:) as! [String:Any]
guard let content = tr["articles"] else { return }
let articlesData = try JSONSerialization.data(withJSONObject:content, options: )
let res = try JSONDecoder().decode([Article].self, from: articlesData)
print(res)
}
catch
{
print(error)
}
edited Jan 1 at 2:32
answered Jan 1 at 2:16
Sh_KhanSh_Khan
43k51328
43k51328
add a comment |
add a comment |
Consider restructuring your Data. You need to structure your data model to match the data structure of the JSON data. You can include only what you want but you must include every parent or level of the property(s) you want to access. Take the following example from the wikipedia API. It prints out the title property that's three levels deep into the JSON data structure. It leaves out several properties as you can tell from the JSON example code but it includes every parent I need to access the property(s) I want.
import UIKit
struct Item: Decodable {
var title: String
}
struct Search: Decodable {
var search: [Item]
}
struct Result: Decodable {
var query: Search
}
func getSearchResults(){
let url = URL(string: "https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=swift%204&utf8=&format=json")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let urlResponse = response as? HTTPURLResponse, urlResponse.statusCode == 200 {
guard let data = data else { return }
do {
let results = try JSONDecoder().decode(Result.self, from: data)
for item in results.query.search {
print(item.title)
}
} catch let error as NSError {
print("error: (error)")
}
}
}.resume()
}
getSearchResults()
JSON Example:
{
"batchcomplete": "",
"continue": {
"sroffset": 10,
"continue": "-||"
},
"query": {
"searchinfo": {
"totalhits": 30349
},
"search": [
{
"ns": 0,
"title": "Swift",
"pageid": 219023,
"size": 13896,
"wordcount": 1496,
"snippet": "The <span class="searchmatch">swifts</span> are a family, Apodidae, of highly aerial birds. They are superficially similar to swallows, but are not closely related to any passerine species",
"timestamp": "2018-12-28T21:29:44Z"
},
{
"ns": 0,
"title": "Swift (programming language)",
"pageid": 42946389,
"size": 49365,
"wordcount": 5244,
"snippet": "2015. <span class="searchmatch">Swift</span> 3.0 was released on September 13, 2016. <span class="searchmatch">Swift</span> <span class="searchmatch">4</span>.0 was released on September 19, 2017. <span class="searchmatch">Swift</span> <span class="searchmatch">4</span>.1 was released on March 29, 2018. <span class="searchmatch">Swift</span> won first",
"timestamp": "2018-12-19T02:52:33Z"
},
{
"ns": 0,
"title": "Taylor Swift",
"pageid": 5422144,
"size": 237225,
"wordcount": 18505,
"snippet": "Taylor Alison <span class="searchmatch">Swift</span> (born December 13, 1989) is an American singer-songwriter. One of the world's leading contemporary recording artists, she is known",
"timestamp": "2018-12-26T21:55:51Z"
},
This is the output of the print:
//Swift
//Swift (programming language)
//Taylor Swift
add a comment |
Consider restructuring your Data. You need to structure your data model to match the data structure of the JSON data. You can include only what you want but you must include every parent or level of the property(s) you want to access. Take the following example from the wikipedia API. It prints out the title property that's three levels deep into the JSON data structure. It leaves out several properties as you can tell from the JSON example code but it includes every parent I need to access the property(s) I want.
import UIKit
struct Item: Decodable {
var title: String
}
struct Search: Decodable {
var search: [Item]
}
struct Result: Decodable {
var query: Search
}
func getSearchResults(){
let url = URL(string: "https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=swift%204&utf8=&format=json")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let urlResponse = response as? HTTPURLResponse, urlResponse.statusCode == 200 {
guard let data = data else { return }
do {
let results = try JSONDecoder().decode(Result.self, from: data)
for item in results.query.search {
print(item.title)
}
} catch let error as NSError {
print("error: (error)")
}
}
}.resume()
}
getSearchResults()
JSON Example:
{
"batchcomplete": "",
"continue": {
"sroffset": 10,
"continue": "-||"
},
"query": {
"searchinfo": {
"totalhits": 30349
},
"search": [
{
"ns": 0,
"title": "Swift",
"pageid": 219023,
"size": 13896,
"wordcount": 1496,
"snippet": "The <span class="searchmatch">swifts</span> are a family, Apodidae, of highly aerial birds. They are superficially similar to swallows, but are not closely related to any passerine species",
"timestamp": "2018-12-28T21:29:44Z"
},
{
"ns": 0,
"title": "Swift (programming language)",
"pageid": 42946389,
"size": 49365,
"wordcount": 5244,
"snippet": "2015. <span class="searchmatch">Swift</span> 3.0 was released on September 13, 2016. <span class="searchmatch">Swift</span> <span class="searchmatch">4</span>.0 was released on September 19, 2017. <span class="searchmatch">Swift</span> <span class="searchmatch">4</span>.1 was released on March 29, 2018. <span class="searchmatch">Swift</span> won first",
"timestamp": "2018-12-19T02:52:33Z"
},
{
"ns": 0,
"title": "Taylor Swift",
"pageid": 5422144,
"size": 237225,
"wordcount": 18505,
"snippet": "Taylor Alison <span class="searchmatch">Swift</span> (born December 13, 1989) is an American singer-songwriter. One of the world's leading contemporary recording artists, she is known",
"timestamp": "2018-12-26T21:55:51Z"
},
This is the output of the print:
//Swift
//Swift (programming language)
//Taylor Swift
add a comment |
Consider restructuring your Data. You need to structure your data model to match the data structure of the JSON data. You can include only what you want but you must include every parent or level of the property(s) you want to access. Take the following example from the wikipedia API. It prints out the title property that's three levels deep into the JSON data structure. It leaves out several properties as you can tell from the JSON example code but it includes every parent I need to access the property(s) I want.
import UIKit
struct Item: Decodable {
var title: String
}
struct Search: Decodable {
var search: [Item]
}
struct Result: Decodable {
var query: Search
}
func getSearchResults(){
let url = URL(string: "https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=swift%204&utf8=&format=json")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let urlResponse = response as? HTTPURLResponse, urlResponse.statusCode == 200 {
guard let data = data else { return }
do {
let results = try JSONDecoder().decode(Result.self, from: data)
for item in results.query.search {
print(item.title)
}
} catch let error as NSError {
print("error: (error)")
}
}
}.resume()
}
getSearchResults()
JSON Example:
{
"batchcomplete": "",
"continue": {
"sroffset": 10,
"continue": "-||"
},
"query": {
"searchinfo": {
"totalhits": 30349
},
"search": [
{
"ns": 0,
"title": "Swift",
"pageid": 219023,
"size": 13896,
"wordcount": 1496,
"snippet": "The <span class="searchmatch">swifts</span> are a family, Apodidae, of highly aerial birds. They are superficially similar to swallows, but are not closely related to any passerine species",
"timestamp": "2018-12-28T21:29:44Z"
},
{
"ns": 0,
"title": "Swift (programming language)",
"pageid": 42946389,
"size": 49365,
"wordcount": 5244,
"snippet": "2015. <span class="searchmatch">Swift</span> 3.0 was released on September 13, 2016. <span class="searchmatch">Swift</span> <span class="searchmatch">4</span>.0 was released on September 19, 2017. <span class="searchmatch">Swift</span> <span class="searchmatch">4</span>.1 was released on March 29, 2018. <span class="searchmatch">Swift</span> won first",
"timestamp": "2018-12-19T02:52:33Z"
},
{
"ns": 0,
"title": "Taylor Swift",
"pageid": 5422144,
"size": 237225,
"wordcount": 18505,
"snippet": "Taylor Alison <span class="searchmatch">Swift</span> (born December 13, 1989) is an American singer-songwriter. One of the world's leading contemporary recording artists, she is known",
"timestamp": "2018-12-26T21:55:51Z"
},
This is the output of the print:
//Swift
//Swift (programming language)
//Taylor Swift
Consider restructuring your Data. You need to structure your data model to match the data structure of the JSON data. You can include only what you want but you must include every parent or level of the property(s) you want to access. Take the following example from the wikipedia API. It prints out the title property that's three levels deep into the JSON data structure. It leaves out several properties as you can tell from the JSON example code but it includes every parent I need to access the property(s) I want.
import UIKit
struct Item: Decodable {
var title: String
}
struct Search: Decodable {
var search: [Item]
}
struct Result: Decodable {
var query: Search
}
func getSearchResults(){
let url = URL(string: "https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=swift%204&utf8=&format=json")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let urlResponse = response as? HTTPURLResponse, urlResponse.statusCode == 200 {
guard let data = data else { return }
do {
let results = try JSONDecoder().decode(Result.self, from: data)
for item in results.query.search {
print(item.title)
}
} catch let error as NSError {
print("error: (error)")
}
}
}.resume()
}
getSearchResults()
JSON Example:
{
"batchcomplete": "",
"continue": {
"sroffset": 10,
"continue": "-||"
},
"query": {
"searchinfo": {
"totalhits": 30349
},
"search": [
{
"ns": 0,
"title": "Swift",
"pageid": 219023,
"size": 13896,
"wordcount": 1496,
"snippet": "The <span class="searchmatch">swifts</span> are a family, Apodidae, of highly aerial birds. They are superficially similar to swallows, but are not closely related to any passerine species",
"timestamp": "2018-12-28T21:29:44Z"
},
{
"ns": 0,
"title": "Swift (programming language)",
"pageid": 42946389,
"size": 49365,
"wordcount": 5244,
"snippet": "2015. <span class="searchmatch">Swift</span> 3.0 was released on September 13, 2016. <span class="searchmatch">Swift</span> <span class="searchmatch">4</span>.0 was released on September 19, 2017. <span class="searchmatch">Swift</span> <span class="searchmatch">4</span>.1 was released on March 29, 2018. <span class="searchmatch">Swift</span> won first",
"timestamp": "2018-12-19T02:52:33Z"
},
{
"ns": 0,
"title": "Taylor Swift",
"pageid": 5422144,
"size": 237225,
"wordcount": 18505,
"snippet": "Taylor Alison <span class="searchmatch">Swift</span> (born December 13, 1989) is an American singer-songwriter. One of the world's leading contemporary recording artists, she is known",
"timestamp": "2018-12-26T21:55:51Z"
},
This is the output of the print:
//Swift
//Swift (programming language)
//Taylor Swift
edited Jan 1 at 6:50
answered Jan 1 at 6:17
Gustavo PicciutoGustavo Picciuto
86
86
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53992522%2fdecoding-json-to-swift-model-not-root-level%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
stackoverflow.com/questions/38864579/…
– impression7vx
Jan 1 at 1:51
@impression7vx That is old way of doing things. I am looking for JSONDecoder way.
– john doe
Jan 1 at 1:53
1
I see. You are trying to parse a portion of it instead of the whole thing. Interesting. Wouldn't you want a parent struct so you can use
totalResults
as well asstatus
?– impression7vx
Jan 1 at 2:11
"The JSON coming from URL is like this" No, it isn't. What you've shown is not valid JSON.
– matt
Jan 1 at 5:53
1
Using JSONDecoder alone, you cannot decode without some sort of outer struct, because your result is going to be an array of Article, which is an outer entity. Merely defining Article alone thus can never be sufficient.
– matt
Jan 1 at 6:53