This question already has answers here:
How do I use custom keys with Swift 4's Decodable protocol?
(4 answers)
Closed 4 years ago.
I use an API to parse some data - this works. But now the api uses names like "d/a" and "test%" and I can't create a codable struct with this symbols. Is there a way to use them?
Thanks in advance
You can remap your keys. Here is a basic example:
struct MyObject: Codable {
var name: String
var da: String
var test: String
enum CodingKeys: String, CodingKey {
case name
case da = "d/a"
case test = "test%"
}
}
You can read more about it in the documentation here
Keep in mind though that you will have to manually include all the properties that you want to be encoded/decoded and that "The names of the enumeration cases should match the names you've given to the corresponding properties in your type"
Related
This question already has answers here:
How do I use custom keys with Swift 4's Decodable protocol?
(4 answers)
Decode a PascalCase JSON with JSONDecoder
(1 answer)
Closed 3 months ago.
I can easily decode the keys that are Camel Case:
struct TheData: Codable {
let theNumber: Float
}
But I can not decode this version:
struct TheData: Codable {
let TheNumber: Float
}
"TheNumber" is with first letter capitalized and Swift does allow constants starting with capital case. I have tried to lower case the first letter but it didn't work.
Here is the solution:
struct TheData: Codable {
let theNumber: Float
private enum CodingKeys: String, CodingKey {
case theNumber = "TheNumber"
}
}
It is mentioned in: How do I use custom keys with Swift 4's Decodable protocol?
This question already has answers here:
How to deserialize a parking_lot::Mutex with Serde?
(1 answer)
How do I serialize or deserialize an Arc<T> in Serde?
(1 answer)
Closed 7 months ago.
Disclaimer: This is my first SO post, so forgive me if I fail to comply to convention
I've got some musical artist streaming analytics data and I am trying to use it on my first Rust-based personal project. I would like to take the data (already formatted in JSON) and graph it within a web-app. My artist data structure takes the form
#[derive(Clone, Debug)]
struct Artist {
genre: genre::Genre,
socials: Vec<String>,
background: Arc<RwLock<Background>>,
soundcloud_data: Arc<RwLock<serde_json::value::Value>>,
...
spotify_data: Arc<RwLock<serde_json::value::Value>>,
}
#[derive(Clone, Debug)]
struct Background {
origin: Arc<RwLock<Origin>>,
description: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
struct Origin{
city: String,
state: String,
country: String,
}
Later on I collect a number of various "Artist" instances into a Vec ("result"), and try to return a reference to said Vec:
Ok(warp::reply::json(&result))
But the issue is that "the trait bound 'Artist: Serialize' is not satisfied..." I am unable to derive serialize for Arc<RwLock> because of the Orphan Rule (note, I'm using the Parking_lot's async implementation of RwLock).
I've began trying to implement Serialize for Artist and Background, but I wonder what's the best way to go about this?
Do I need to replace
Arc<RwLock<serde_json::value::Value>>
with
Arc<RwLock<descriptive_struct>>
where descriptive_struct has the (nested) structure of the JSON file? Then implement serialize for said struct? Or is there a better way to do this that I'm not seeing?
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
The new Swift "Decoder" class sounds like a great way to parse JSON data, but all of the examples I've found use a well-known, well-defined 'struct' to do so.
In my case I'm querying an arbitrary website that returns a HUGE JSON string and I only care about a few of the (deeply nested) fields, so I don't want to take all that time to define a 'struct' to get at them.
Is it even possible to do this with "Decoder"? And if so, how does one go about it?
The question seems to be based on a misapprehension about how Decodable works. As a convenience, Decodable is willing to do some automatic code generation behind the scenes so that you can define a struct or nest of structs and just decode the entirety of the JSON. But you are not required to take advantage of that in order to decode JSON.
There is no need to define struct properties for "fields" you don't care about. If a JSON dictionary contains 100 keys and your corresponding struct contains just one property, no problem; that key will be fetched, and no others.
With regard to the "deeply nested" part, it should not take you much time to write simple nested structs that perform the dive to reach the dictionary you really care about. But if you don't want to do even that, you could write an implementation of init(from:) that dives down and fetches out the desired values.
In other words, if you think of Decodable as consisting primarily of your implementation of init(from:), and learn to write the code that it needs, you will see that this JSON can be parsed in a few quick simple lines of code.
As an example, here's a JSON sketch of a deeply nested piece of information with a bunch of extra information at every level that we want to ignore:
{
"ignore": true,
"outer1": {
"ignore": true,
"outer2": {
"ignore": true,
"outer3": {
"name": "matt",
"ignore": true
}
}
}
}
What I'd like to do is define a very simple struct Person that consists solely of the deeply nested name:
struct Person : Decodable {
let name : String
}
I can do that! To do so, I implement Decodable myself, supplying a "hoover" CodingKey adopter struct and an implementation of init(from:), like this (this may look like a lot of work, but it isn't, because the AnyCodingKey implementation is boilerplate, copied and pasted from here, and the init(coder:) implementation is just a few lines of code that were easy to write):
struct Person : Decodable {
let name : String
struct AnyCodingKey : CodingKey {
var stringValue: String
var intValue: Int?
init(_ codingKey: CodingKey) {
self.stringValue = codingKey.stringValue
self.intValue = codingKey.intValue
}
init(stringValue: String) {
self.stringValue = stringValue
self.intValue = nil
}
init(intValue: Int) {
self.stringValue = String(intValue)
self.intValue = intValue
}
}
init(from decoder: Decoder) throws {
var con = try! decoder.container(keyedBy: AnyCodingKey.self)
con = try! con.nestedContainer(keyedBy: AnyCodingKey.self, forKey: AnyCodingKey(stringValue:"outer1"))
con = try! con.nestedContainer(keyedBy: AnyCodingKey.self, forKey: AnyCodingKey(stringValue:"outer2"))
con = try! con.nestedContainer(keyedBy: AnyCodingKey.self, forKey: AnyCodingKey(stringValue:"outer3"))
let name = try! con.decode(String.self, forKey: AnyCodingKey(stringValue:"name"))
self.name = name
}
}
When I want to dive into the JSON and grab the name information, it's trivial:
let person = try! JSONDecoder().decode(Person.self, from: json)
The result is a Person object with name value "matt". Note that I didn't have to add any of the ignore keys and I didn't need to make a nest of structs.
Sure you can achieve this but with both JSonSerialization & Decodable , you have to serialize the json until reach the desired content then decode it ,but instead I recommend to create structs for root keys only then decode , think of it as it's a path from top to bottom don't decode a key that isn't in the path of your desired content
This question already has answers here:
How do I use custom keys with Swift 4's Decodable protocol?
(4 answers)
Closed 3 years ago.
I'm currently using JSONDecoder to parse json into objects with Swift 5. I'm just realizing now that part of the JSON is bad JSON. It has a field name with a space: "Post Title". I'm not sure why it is like this, and I'm aware it is bad practice for JSON to be setup like this, but there's not much I can do on the JSON side. Is there a way to use JSON decoder to get that field as is?
I've researched this a ton, but since it is an issue with bad json, I'm not finding much online other than creating a custom decoder/deserializer (which I'm trying to avoid).
JSON:
{
"Post Title":"Hello World"
}
Struct:
struct Post: Decodable {
var PostTitle: String
}
Decoder:
let jsonObject = try jsonDecoder.decode(Post.self, from: responseData)
Thank you in advance!
For custom keys, use CodingKeys to match JSON keys.
struct Post : Codable {
var PostTitle: String
private enum CodingKeys : String, CodingKey {
case PostTitle = "Post Title"
}
}
Note: you should use lowercased starting letter for variables.
This question already has an answer here:
Strange type definition syntax in Golang (name, then type, then string literal)
(1 answer)
Closed 7 years ago.
I'm learning GO and when defining structs for working with JSON like below.
type List struct {
ID string `datastore:"-"`
Name string
}
I see that there is this text in between ` sign. I have not been able to find an explanation what that signifies.
Things seem to work even without those.
They are struct tags used in Marshal'ing Go struct into JSON. In JSON, unlike Go, fields are in lowercase strings. Therefore, most use cases would be
type List struct {
ID string `json:"id"`
Name string `json:"name"`
}
In JSON
{
"id": "some id",
"name": "some name"
}
See post here