Comments (6)
Other than that, querying a JSON value like this is an example use case of the new dynamic member lookup feature in Swift, see SE-0195.
from generic-json-swift.
To be honest I did not give much thought to the use case of working with the resulting JSON object manually, my use case was mostly storage or automated postprocessing. But:
if
let value = subject["value"] as? [String : Any],
let identities = value["identities"] as? [[String : Any]],
let types: [String] = identities.compactMap({ $0["type"] as? String }) { β¦ }
This already assumes some kind of structure on the incoming data. Would it be possible to model this structure using Codable
?
struct Value: Codable {
struct TypeTag: Codable { β¦ } // Maybe only use the generic JSON type here?
struct Identity: Codable {
let types: [TypeTag]
}
let identities: [Identity]
}
from generic-json-swift.
That's a great link. I hadn't even thought of SE-0195 as being able to address this issue. Though, we do have to wait until Swift 4.2 for it...
In the mean time, extrapolating from Example Usage, by adding an extension to JSON
:
extension JSON {
public var stringValue: String? {
if case .string(let value) = self {
return value
}
return nil
}
public var floatValue: Float? {
if case .number(let value) = self {
return value
}
return nil
}
public var boolValue: Bool? {
if case .bool(let value) = self {
return value
}
return nil
}
public var objectValue: [String : JSON]? {
if case .object(let value) = self {
return value
}
return nil
}
public var arrayValue: [JSON]? {
if case .array(let value) = self {
return value
}
return nil
}
public var isNull: Bool {
if case .null = self {
return true
}
return false
}
public subscript(index: Int) -> JSON? {
if case .array(let arr) = self {
return index < arr.count ? arr[index] : nil
}
return nil
}
public subscript(key: String) -> JSON? {
if case .object(let dict) = self {
return dict[key]
}
return nil
}
}
Extracting "resources" and "types" becomes:
if let resource = genericJSON?["subject"]?["resource"]?.stringValue {
print("Resource: \(resource)")
}
if let types = genericJSON?["subject"]?["value"]?["identities"]?.arrayValue?.compactMap( {$0["type"]?.stringValue } ) {
print("Types: \(types)")
}
Is this worthy of a PR?
Regarding defining the type to conform to Decodable
, this is not possible in my use case. I decode a json payload (where only some of the payload structure is known) into a Struct, and then pass the struct to an API consumer. Only the consumer knows the structure of the "unknown" section. I use the JSON
type for this unknown section.
Example
{
"known1": "some-string",
"known2": true,
"known3": 1000,
"unknown": {
// some unknown structure
}
}
from generic-json-swift.
I decode a json payload (where only some of the payload structure is known) into a Struct, and then pass the struct to an API consumer. Only the consumer knows the structure of the "unknown" section. I use the JSON type for this unknown section.
I just wonder if something like this makes sense:
extension JSONDecoder {
func decode<T: Decodable>(_ what: T.Type, from json: JSON) throws -> T {
let data = try JSONEncoder().encode(json)
return try JSONDecoder().decode(what, from: data)
}
}
struct DecodedFirst: Decodable {
let known1: String
let known2: String
let unknown: JSON
}
struct DecodedLater: Decodable {
let foo: String
}
let json = """
{
"known1": "foo",
"known2": "bar",
"unknown": {
"foo": "bar"
}
}
"""
let wrapper = try JSONDecoder().decode(DecodedFirst.self, from: Data(json.utf8))
let decoded = try JSONDecoder().decode(DecodedLater.self, from: wrapper.unknown)
print(decoded)
This way you would get both β you could decode the βenvelopeβ first and the unknown part later, both using plain Decodable
with its convenience and safety. The re-encoding part is slightly stupid though?
from generic-json-swift.
That's an interesting approach and it certainly addresses the use case.
Though, yes, the series of transformations (data > JSON > data > native type) may be bit cumbersome. I will look into this some more.
For now, I am happy to leave the unknown type as JSON
. The addition of query helpers provides an adequate API for the consumer.
Thank you for your assistance.
from generic-json-swift.
Happy to help! Thank you for your contributions π
from generic-json-swift.
Related Issues (16)
- Publish new version of the pod? HOT 2
- Add support for Swift Package Manager
- Automate release process HOT 1
- Add Linux support
- Switch to a cross-platform framework
- Initialisation using `nil` or `NSNull` HOT 5
- Tags Are Not SPM-Compliant HOT 3
- JSON initialisation using variables of primitive type HOT 2
- Mutation support HOT 2
- NSNumber Initialization HOT 3
- How to use JSON in Core Data HOT 7
- Provide `Decoder` to turn `JSON` into `Decodable` HOT 2
- Loop through JSON keys?
- Improve querying using dynamic member lookup? HOT 1
- Merging JSON values HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from generic-json-swift.