Comments (12)
There's really no way for Argo to know how to parse an object of the type T
without also knowing that T
is JSONDecodable
. The long compile times resulting in failures make sense to me, given that the compiler has no idea what to do with that type in this context.
tl;dr: if you want Argo to decode contained types, they need to conform to JSONDecodable
. There's really no way around that.
from argo.
I've pushed a repo with my findings: https://github.com/piercifani/ArgoGenericParse. Please look at Model.swift
and Parse.swift
I think that noting that noting that T
is a JSONDecodable
in the decode
and create
methods should be enough for the compiler to know that when calling Page<T>.decode
it should error when T
doesn't comply with JSONDecodable
but still let you do stuff like Page<U>
when you're not calling either decode
or create
.
I don't think this is an Argo bug, but instead a compiler bug. Shall we create a radar with this behaviour?
PS: It still won't compile if I declare <T:JSONDecodable>
in the original struct Page
declaration
from argo.
Because of the way we've implemented Argo, you would need to make T like so: <T: JSONDecodable where T.DecodedType == T>
. You could try that and see if it helps with Page.
from argo.
You also can't have a generic class/struct that conforms to a protocol in only some cases. For example, Page<T>
. Page: JSONDecodable
for only when T: JSONDecodable
wouldn't work. The declairation of Page<T>
would have to say that T is such.
from argo.
You are right, declaring:
public struct Page<T: JSONDecodable where T.DecodedType == T> {
public let count : Int
public let next : String?
public let previous : String?
public let results : [T]
}
Compiles and works as expected. However, it is a shame that this limitation exists, since now my model classes are tightly coupled to Argo
, that means that now my ViewControllers must know what JSONDecodable
is and what classes/structs comply to it.
I still don't understand why the compiler can't figure out when it's correct to call Page<T>.decode
and when not to, since it knows which <T>
s comply to the protocol and which don't.
I have updated the repository including the correct code.
Thanks for your help!
from argo.
However, it is a shame that this limitation exists, since now my model classes are tightly coupled to Argo
This isn't a limitation, there's really no other way for Argo to work. Argo is designed to be tightly coupled to your model objects.
that means that now my ViewControllers must know what
JSONDecodable
is and what classes/structs comply to it.
Your view controllers might know that your object is JSONDecodable
, but they really shouldn't need to care about JSONDecodable
. I'd be interested in why you think they do.
I still don't understand why the compiler can't figure out when it's correct to call
Page<T>.decode
and when not to
The issue isn't calling Page<T>.decode
, the issue is calling T.decode
when it tries to decode your results
property.
since it knows which
<T>
s comply to the protocol and which don't.
That's simply not true. The compiler has no idea what T
is. So how can it know if it's JSONDecodable
? The larger issue that there's literally no way that the compiler can know that Page
is JSONDecodable
if it doesn't know that all of the properties on Page
are also JSONDecodable
.
from argo.
Argo is designed to be tightly coupled to your model objects.
Well, I can conform to JSONDecodable
in an extension
and in a different file, just like I did in the attached repo using Parse.swift
. This is one of the nicest things of Argo, because in case you want to change the JSON->Model Objects serialization, you just edit that one file.
Your view controllers might know that your object is JSONDecodable, but they really shouldn't need to care about JSONDecodable
Well, now they have to import Argo
in order to understand what a struct Page<T: JSONDecodable where T.DecodedType == T>
means, before I only had to import my App's internal framework and that was it.
The issue isn't calling Page.decode, the issue is calling T.decode when it tries to decode your results property.
Exactly: I thought that if I declared
extension Page : JSONDecodable {
static func create<T: JSONDecodable where T.DecodedType == T> () -> Page<T> {
}
public static func decode<T: JSONDecodable where T.DecodedType == T>(j: JSONValue) -> Page<T>? {
}
}
That would be enough, but the compiler SEGFAULTs if I do this. Do you see why I think that that should be enough for the compiler to know when Page<T>.decode
is legal and when it isn't?
Because I feel like I'm not explaining myself good enough, if you think it'll help I can change the code back to how I think it should work and you can see the compiler SEGFAULTing :) always fun when that happens!
from argo.
Well, now they have to import Argo in order to understand what a struct Page<T: JSONDecodable where T.DecodedType == T> means, before I only had to import my App's internal framework and that was it.
That doesn't sound right at all. Doing a quick check, the only reason you would need to import Argo in a file that uses one of your models is accessing the decode
function (or the DecodedType
typealias) defined on JSONDecodable
itself. Where are you seeing this behavior?
I'll need to think more about your decode
type constraints. That's an interesting point.
from argo.
Sorry for the long time between answers, I'm using Argo on a side project, so I don't check this thread out everyday :(
I withdraw what I said: the ViewControllers importing the model objects from a framework don't need to import Argo
, since Swift collapses all the necessary imports at the beginning of the generated module header.
So to recap, it's not ideal to have that coupled there, but I can live with this.
I'm still intellectually curious on why the compiler can't figure it out without making all the Page
's Ts comply to JSONDecodable
, but rather only the ones that I'm calling decode
onto. But hell, maybe it's time to ask someone who works on the language
from argo.
I think the answer is probably as simple as the fact that these two function definitions aren't the same:
static func decode<T: JSONDecodable where T.DecodedType == T>(j: JSONValue) -> Page<T>?
static func decode(j: JSONValue) -> DecodedType?
DecodedType
is typealiased to Self
, so you can't make constraints on it.
from argo.
Mmmmm that makes a lot of sense
from argo.
Hello Guys, how it's going?
Some one could post here the solutions file, because I am having the same trouble and can't figure out how fix.
Thx
from argo.
Related Issues (20)
- error: no such module 'Runes' HOT 7
- Problem with Decodable on xcode 9 HOT 3
- RFC: Renaming the Decodable protocol
- How to decode a "Dictionary" to "[Model]"? HOT 3
- Parse nested array failed HOT 5
- Parse nested model fails when adding a specific key HOT 2
- How to decode dynamic keys HOT 2
- RFC: Renaming (or removing) the `<|` family of operators HOT 5
- Decode type 'Any' HOT 2
- RFC: Make Swift.Decodable conform to Argo.Decodable in Swift 4.1 HOT 4
- Convert all wrong type return JSON to specific type HOT 6
- Decoding the same object with different keys HOT 6
- How to parse an empty dictionary object in Argo HOT 1
- [Question] Array decoding HOT 4
- Using pure can't compile using Swift 3 HOT 2
- Decodable' is ambiguous for type lookup in this context (Swift4) HOT 1
- Parsing a json array with strings and objects intermixed HOT 2
- Xcode 11.0 compatibility issue HOT 3
- Xcode 11.2.1 Binary operator '<^>' cannot be applied to operands of type HOT 7
- Upgrade to version 5.0.0 blocked due to Ogra library HOT 6
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 argo.