-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Swift4] Change model object from class
to struct
#6941
Comments
I'm big +1 on this. |
I like this, and considered doing it for my initial implementation. However, when we have allOf/discriminator in the swagger schema, then we need to inherit properties from other models. The easiest way to do this is to use inheritance, which we can't do with structs. So would you rather:
Alternatively, I guess we could probably not worry about shared code, and just put parent properties directly into the child struct and then duplicate them in the parent struct as well. |
i'm +1 on the concept - @ehyche i'd rather be consistent and either always have structs and duplicate properties or always have classes at the end of the day. |
Is there a compelling reason not to offer both and let the user choose? It might also be nice to offer it as a protocol. |
I have a PR for this - just waiting for a dependent PR to be merged, and then I'll put it up. |
This fixes issue swagger-api#6941. In this change, we make our Swift4 generated model objects struct instead of class. However, in order to do this, we needed to handle the following edge cases: * Inheritance and polymorphism (allOf) * With classes, we use inheritance. So therefore, the parent properties are ONLY on the parent generated class, and the model object which derives from the parent class picks up those properties through inheritance. * However, structs do not support inheritance. So we simply duplicate the parent allOf properties in the child struct. * We have to handle the case where the property name on the struct may be different than the property name in the JSON. By default, the Codable protocol assumes that the JSON property name is the same as the struct property name. If they need to be different, then we generate a CodingKeys string enum, which contains the mapping between struct property name and JSON property name. * additionalProperties. We cannot use the default Codable implementation for the additionalProperties, since it will look for an actual dictionary called "additionalProperties" in the JSON. Therefore, for model objects which have additionalProperties, we must generate our own implementation for the Decodable and Encodable protocols. I have run ./bin/swift4-all.sh and ./bin/swift4-test.sh to re-generate all of the sources, and I have verified that the generated code in samples/clients/test/swift4/default builds and the unit tests pass.
* Split up model template into partials * Change models from class to struct. This fixes issue #6941. In this change, we make our Swift4 generated model objects struct instead of class. However, in order to do this, we needed to handle the following edge cases: * Inheritance and polymorphism (allOf) * With classes, we use inheritance. So therefore, the parent properties are ONLY on the parent generated class, and the model object which derives from the parent class picks up those properties through inheritance. * However, structs do not support inheritance. So we simply duplicate the parent allOf properties in the child struct. * We have to handle the case where the property name on the struct may be different than the property name in the JSON. By default, the Codable protocol assumes that the JSON property name is the same as the struct property name. If they need to be different, then we generate a CodingKeys string enum, which contains the mapping between struct property name and JSON property name. * additionalProperties. We cannot use the default Codable implementation for the additionalProperties, since it will look for an actual dictionary called "additionalProperties" in the JSON. Therefore, for model objects which have additionalProperties, we must generate our own implementation for the Decodable and Encodable protocols. I have run ./bin/swift4-all.sh and ./bin/swift4-test.sh to re-generate all of the sources, and I have verified that the generated code in samples/clients/test/swift4/default builds and the unit tests pass. * Update VERSION in .swagger-codegen * Update generated code for swift4-test schema
Initializers are no longer see from other package. Could you add initializer again? I am usually using the generated code as a CocoaTouch Framework to reuse this via Carthage. |
This needs to do something special for recursion.
|
I've just updated my codegen to generate swift4 code. How do I enable class generation instead of struct? I'll have a great deal of refactoring, not to mention that I need the object references, as my code passes the same object to different views and I don't need multiple copies. |
There is not an option to switch between class and struct. The swift4 module always generates structs now. |
thank you, I thought so after seeing the moustache files, but I wanted to be certain. I switch would've been handy for people who want to port complex projects, or if they just want to take advantage of classes. |
Classes are essential for Objective C interoperability. |
@eoinnorris I agree, but isn't it a bit strange to expose Swift classes to Objective-C? I often do the opposite. Maybe that's just a side effect of having a nearly pure Swift application. The Objective-C bits are usually just there to bridge C++ code into Swift. |
@jgavris the particular use case I have is a swift framework, which may be consumed by an Objective C app. We are designing the SDK to interact with our services, and have written it for swift for future proofing. However we can't really assume that only swift apps will use it. Probably this will become even more common in swift 5. In fact in our demo app is a react app, and the react bridge is in Objective C only. Besides classes, all public instances need an @objc. I need to do this anyway, so I could take a look at whether its worth doing in CodeGen as an option, or write a separate script myself. |
Classes are useful when the model uses inheritance and polymorphism. We can't take advantage of these object-oriented basic features anymore. Like many others, I will need to maintain my own templates (and it's a pain). Classes should still be supported (as a first-class alternative). |
I do agree that structs are much more powerful in swift. but neither of both have capabilities to replace one another. Not sure who decided not to support both. |
We've already supported on our fork. This is main stream about Swift codegen. |
@HugoMario You merged the new additionalProperty "useModelClasses" into master (Dec 2019), but it seems still missing in V3.0.23 (Nov 2020)? |
Description
I wonder why model templates of swift 4 is type of
open class
, instead ofpublic struct
.Swagger-codegen version
2.3.0
Swagger declaration file content or url
Command line used for generation
Steps to reproduce
Related issues/PRs
Suggest a fix/enhancement
In Swift 4, all of generated model class is adopted for
Swift.Codable
, which is protocol so that we can usestruct
instead ofclass
, and it's more comfortable for Modal object.So, try to change as below.
(I think they should be
let
asget
is defined in yaml.)The text was updated successfully, but these errors were encountered: