[iOS] Cannot assign to property: 'x' is a get-only property

Since migrating to the new codegen I can’t seem to change the values in my array.

In the old version I could do
array[index].progress = 5
but in the new version it gives me this error.

Looking into the generated Swift code and I can see the old codegen had getters and setters, but the new one looks like they’re all computed vars. Is there something I’m missing?

Hi @PaulDoesDev :wave:

The gist of what you’re experiencing is that the 0.x generated models were mutable whereas the new 1.x generated models are immutable. This is by design and representative that the generated models are only used in and initialized by GraphQL responses.

If you were mutating the models to do some cache manipulation there is another API to do the same. If not, I’d love to learn more about your use case.

I recommend you read through the 1.0 migration guide, which guides you through moving from 0.x to 1.x.

Hi @calvincestari,

Thanks for the prompt response.

Essentially, I’m building an anime/manga tracking app using AniList’s API.

This particular use case depends on them being mutable, since I:

  1. Fetch ‘MediaEntry’ data from the API
  2. Present this in my app
  3. The user taps + or - on a stepper to add or remove an episode
  4. I update the ‘progress’ value of that MediaEntry. This then updates my view.
  5. I send a request using the id of that MediaEntry and the new count to the server

Is it expected we create our own models and hydrate them using the data from the generated models now?

  1. I update the ‘progress’ value of that MediaEntry. This then updates my view.

Is progress a value that you fetch from the server in your query?

  • If it is then a cache mutation to affect the underlying data in the cache is advised rather than just mutating the query response. Part of the design change to make response types immutable is to remove the perception that updating a response value would somehow have it sent back to the server or into the cache.
  • If it’s a local client-side only property (i.e.: not part of the query response) then yes it sounds like you will need to wrap the response type in your own type to augment it with progress. One day we will support client-side properties that could behave this way automatically.

i would like to add to this as well. I need to be able to change an attribute that comes from a query - namely, provide a custom iOS date format and replace that with the string that I originally had…

i.e. user.birthday = user.birthday?.convertToDate().toString() ← or something like that.

This is something that should be client specific I would think. I am getting the same error with this.

Any suggestions on what the easiest way to fix this might be?

It sounds like for your use case, you should be using a Custom Scalar.

The generated models are intended to be a direct representation of your GraphQL network response data. If you need to do custom business logic or data transformations that cannot be handled with Custom Scalars, I’d recommend wrapping the generated models in your own ViewModels of some sort.

-Great, Apollo has swift codegen and is capable of generating all this boilerplate code based on my .schema and .graphql and I bet it will work just like codegen for the other languages Apollo has codegen for.

  • :frowning: WOW this sucks. The codegen will generate all of the models based off my schema and graphql files but it IS ABSOLUTELY USLESS TRASH AND A WASTE OF TIME BECAUSE THE MODELS IT GENERATED CANNOT BE USED OUTSIDE OF THE CONTEXT OF A GRAPHQL RESPONSE.

Sounds like you’re looking for the configuration option to generate Selection Set Initializers. The API reference documentation for that particular property is broken and we haven’t figured out why yet. There is example JSON on that docs page that demonstrates how to use the configuration option.

I suggest reading the rest of the codegen configuration documentation. There might be something else in there you’ll find useful.

1 Like