Swagger-codegen: [Swift4] Change model object from `class` to `struct`

Created on 13 Nov 2017  路  20Comments  路  Source: swagger-api/swagger-codegen

Description


I wonder why model templates of swift 4 is type of open class, instead of public 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 use struct instead of class, and it's more comfortable for Modal object.

So, try to change as below.

  • Before
open class Example : Swift.Codable {

  public var id: Int32

  public var name: String

}
  • After
public struct Example : Swift.Codable {

  public var id: Int32

  public var name: String

}

(I think they should be let as get is defined in yaml.)

Swift Suggestion help wanted

Most helpful comment

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.

All 20 comments

@d-date thanks for the suggestion.

Here are similar discussions/suggestions before:

https://github.com/swagger-api/swagger-codegen/issues/5761
https://github.com/swagger-api/swagger-codegen/issues/4126

cc @jgavris @ehyche @Edubits @jaz-ah

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:

  • Have structs when we don't have a parent, and have classes when we do? OR
  • Have classes everywhere?

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.

Thoughts, @jgavris @Edubits @jaz-ah ?

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.

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.

public struct Node : Swift.Codable {
  public var id: Int32
  public var name: String
  public var next: Node?
}

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).

@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.

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.

https://github.com/OpenAPITools/openapi-generator

@HugoMario You merged the new additionalProperty "useModelClasses" into master (Dec 2019), but it seems still missing in V3.0.23 (Nov 2020)?

thanks @Pe-te for letting me know. I just added and merged this PR to port changes

Was this page helpful?
0 / 5 - 0 ratings